...

Source file src/github.com/go-resty/resty/v2/response.go

Documentation: github.com/go-resty/resty/v2

     1  // Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
     2  // resty source code and usage is governed by a MIT style
     3  // license that can be found in the LICENSE file.
     4  
     5  package resty
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"io"
    11  	"net/http"
    12  	"strings"
    13  	"time"
    14  )
    15  
    16  //‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
    17  // Response struct and methods
    18  //_______________________________________________________________________
    19  
    20  // Response struct holds response values of executed request.
    21  type Response struct {
    22  	Request     *Request
    23  	RawResponse *http.Response
    24  
    25  	body       []byte
    26  	size       int64
    27  	receivedAt time.Time
    28  }
    29  
    30  // Body method returns HTTP response as []byte array for the executed request.
    31  //
    32  // Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
    33  func (r *Response) Body() []byte {
    34  	if r.RawResponse == nil {
    35  		return []byte{}
    36  	}
    37  	return r.body
    38  }
    39  
    40  // Status method returns the HTTP status string for the executed request.
    41  //	Example: 200 OK
    42  func (r *Response) Status() string {
    43  	if r.RawResponse == nil {
    44  		return ""
    45  	}
    46  	return r.RawResponse.Status
    47  }
    48  
    49  // StatusCode method returns the HTTP status code for the executed request.
    50  //	Example: 200
    51  func (r *Response) StatusCode() int {
    52  	if r.RawResponse == nil {
    53  		return 0
    54  	}
    55  	return r.RawResponse.StatusCode
    56  }
    57  
    58  // Proto method returns the HTTP response protocol used for the request.
    59  func (r *Response) Proto() string {
    60  	if r.RawResponse == nil {
    61  		return ""
    62  	}
    63  	return r.RawResponse.Proto
    64  }
    65  
    66  // Result method returns the response value as an object if it has one
    67  func (r *Response) Result() interface{} {
    68  	return r.Request.Result
    69  }
    70  
    71  // Error method returns the error object if it has one
    72  func (r *Response) Error() interface{} {
    73  	return r.Request.Error
    74  }
    75  
    76  // Header method returns the response headers
    77  func (r *Response) Header() http.Header {
    78  	if r.RawResponse == nil {
    79  		return http.Header{}
    80  	}
    81  	return r.RawResponse.Header
    82  }
    83  
    84  // Cookies method to access all the response cookies
    85  func (r *Response) Cookies() []*http.Cookie {
    86  	if r.RawResponse == nil {
    87  		return make([]*http.Cookie, 0)
    88  	}
    89  	return r.RawResponse.Cookies()
    90  }
    91  
    92  // String method returns the body of the server response as String.
    93  func (r *Response) String() string {
    94  	if r.body == nil {
    95  		return ""
    96  	}
    97  	return strings.TrimSpace(string(r.body))
    98  }
    99  
   100  // Time method returns the time of HTTP response time that from request we sent and received a request.
   101  //
   102  // See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
   103  // when client sent a request.
   104  func (r *Response) Time() time.Duration {
   105  	if r.Request.clientTrace != nil {
   106  		return r.Request.TraceInfo().TotalTime
   107  	}
   108  	return r.receivedAt.Sub(r.Request.Time)
   109  }
   110  
   111  // ReceivedAt method returns when response got received from server for the request.
   112  func (r *Response) ReceivedAt() time.Time {
   113  	return r.receivedAt
   114  }
   115  
   116  // Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header,
   117  // however it won't be good for chucked transfer/compressed response. Since Resty calculates response size
   118  // at the client end. You will get actual size of the http response.
   119  func (r *Response) Size() int64 {
   120  	return r.size
   121  }
   122  
   123  // RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse`
   124  // option otherwise you get an error as `read err: http: read on closed response body`.
   125  //
   126  // Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse.
   127  // Basically you have taken over the control of response parsing from `Resty`.
   128  func (r *Response) RawBody() io.ReadCloser {
   129  	if r.RawResponse == nil {
   130  		return nil
   131  	}
   132  	return r.RawResponse.Body
   133  }
   134  
   135  // IsSuccess method returns true if HTTP status `code >= 200 and <= 299` otherwise false.
   136  func (r *Response) IsSuccess() bool {
   137  	return r.StatusCode() > 199 && r.StatusCode() < 300
   138  }
   139  
   140  // IsError method returns true if HTTP status `code >= 400` otherwise false.
   141  func (r *Response) IsError() bool {
   142  	return r.StatusCode() > 399
   143  }
   144  
   145  //‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
   146  // Response Unexported methods
   147  //_______________________________________________________________________
   148  
   149  func (r *Response) setReceivedAt() {
   150  	r.receivedAt = time.Now()
   151  	if r.Request.clientTrace != nil {
   152  		r.Request.clientTrace.endTime = r.receivedAt
   153  	}
   154  }
   155  
   156  func (r *Response) fmtBodyString(sl int64) string {
   157  	if r.body != nil {
   158  		if int64(len(r.body)) > sl {
   159  			return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
   160  		}
   161  		ct := r.Header().Get(hdrContentTypeKey)
   162  		if IsJSONType(ct) {
   163  			out := acquireBuffer()
   164  			defer releaseBuffer(out)
   165  			err := json.Indent(out, r.body, "", "   ")
   166  			if err != nil {
   167  				return fmt.Sprintf("*** Error: Unable to format response body - \"%s\" ***\n\nLog Body as-is:\n%s", err, r.String())
   168  			}
   169  			return out.String()
   170  		}
   171  		return r.String()
   172  	}
   173  
   174  	return "***** NO CONTENT *****"
   175  }
   176  

View as plain text