github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xnet/xhttp/xrequest/response.go (about)

     1  package xrequest
     2  
     3  import (
     4  	"encoding/json"
     5  	"encoding/xml"
     6  	"io"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"os"
    10  
    11  	"github.com/go-board/x-go/xnet/xhttp"
    12  )
    13  
    14  // Response is wrapper of http.Response with extra convenient methods.
    15  type Response struct {
    16  	Response *http.Response
    17  	status   *xhttp.Status
    18  }
    19  
    20  func newResponse(r *http.Response) *Response {
    21  	return &Response{Response: r, status: xhttp.NewStatus(r.StatusCode, r.Status)}
    22  }
    23  
    24  // Header return immutable response header which clone the original header.
    25  func (r *Response) Header() http.Header { return r.Response.Header.Clone() }
    26  
    27  // HeaderMut return mutable Response header.
    28  func (r *Response) HeaderMut() http.Header { return r.Response.Header }
    29  
    30  // ContentType return response content-type in header.
    31  func (r *Response) ContentType() string { return r.Response.Header.Get("Content-Type") }
    32  
    33  // ContentLength return response content-length in header.
    34  func (r *Response) ContentLength() int64 { return r.Response.ContentLength }
    35  
    36  // Status return response status.
    37  func (r *Response) Status() *xhttp.Status { return r.status }
    38  
    39  // RequestBody return response body interface.
    40  func (r *Response) Body() io.Reader { return r.Response.Body }
    41  
    42  // Close close response body.
    43  func (r *Response) Close() error { return r.Response.Body.Close() }
    44  
    45  // JSON unmarshal response body data into v.
    46  func (r *Response) JSON(v interface{}) error {
    47  	if err := errorContentType(xhttp.MIMEApplicationJSON, r.Response.Header); err != nil {
    48  		return err
    49  	}
    50  	d := json.NewDecoder(r.Response.Body)
    51  	d.UseNumber()
    52  	return d.Decode(v)
    53  }
    54  
    55  // XML unmarshal response body data into v.
    56  func (r *Response) XML(v interface{}) error {
    57  	if err := errorContentType(xhttp.MIMETextXML, r.Response.Header); err != nil {
    58  		return err
    59  	}
    60  	return xml.NewDecoder(r.Response.Body).Decode(v)
    61  }
    62  
    63  // Bytes return response body in []byte format.
    64  func (r *Response) Bytes() ([]byte, error) {
    65  	defer r.Close()
    66  	return ioutil.ReadAll(r.Response.Body)
    67  }
    68  
    69  // String return response body in string format.
    70  func (r *Response) String() (string, error) {
    71  	bytes, err := r.Bytes()
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  	return string(bytes), nil
    76  }
    77  
    78  // Cookies retrieve response all cookies.
    79  func (r *Response) Cookies() []*http.Cookie {
    80  	return r.Response.Cookies()
    81  }
    82  
    83  // Cookie retrieve response cookie with name.
    84  func (r *Response) Cookie(name string) (*http.Cookie, bool) {
    85  	cookies := r.Response.Cookies()
    86  	for _, cookie := range cookies {
    87  		if cookie.Name == name {
    88  			return cookie, true
    89  		}
    90  	}
    91  	return nil, false
    92  }
    93  
    94  // DownloadFile write response body to file.
    95  func (r *Response) DownloadFile(name string) error {
    96  	f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, 0666)
    97  	if err != nil {
    98  		return err
    99  	}
   100  	defer f.Close()
   101  	defer r.Close()
   102  	_, err = io.Copy(f, r.Response.Body)
   103  	return err
   104  }