github.com/go-board/x-go@v0.1.2-0.20220610024734-db1323f6cb15/xnet/xhttp/xrequest/http.go (about) 1 package xrequest 2 3 import ( 4 "context" 5 "net/http" 6 "net/url" 7 ) 8 9 // Client is a client to perform http request and retrieve http response. 10 // Field client is *http.Client that real perform request. 11 // Field interceptors is chain of Interceptor to hook client. 12 type Client struct { 13 client *http.Client 14 interceptors []Interceptor 15 baseHost string 16 } 17 18 var DefaultClient = &Client{ 19 client: http.DefaultClient, 20 } 21 22 // NewHttpClient create new client. 23 func NewHttpClient(client *http.Client, baseHost string, interceptors ...Interceptor) *Client { 24 // try set client.Transport first 25 if client.Transport == nil { 26 client.Transport = http.DefaultTransport 27 } 28 // wrapper client.Transport 29 client.Transport = ComposeInterceptor(client.Transport, interceptors...) 30 return &Client{client: client, interceptors: interceptors, baseHost: baseHost} 31 } 32 33 func (c *Client) newRequest(ctx context.Context, method string, rawurl string, body RequestBody, options ...RequestOption) (*http.Request, error) { 34 if c.baseHost != "" { 35 u, err := url.Parse(rawurl) 36 if err == nil { 37 rawurl = c.baseHost + u.RequestURI() 38 } 39 } 40 r, err := http.NewRequestWithContext(ctx, method, rawurl, body) 41 if err != nil { 42 return nil, err 43 } 44 for _, option := range options { 45 option(r) 46 } 47 if body != nil { 48 r.Header.Set("Content-Type", body.ContentType()) 49 if encoding := body.ContentEncoding(); encoding != nil { 50 r.Header.Set("Content-Encoding", *encoding) 51 } 52 } 53 return r, nil 54 } 55 56 func (c *Client) doRequest(req *http.Request) (*Response, error) { 57 response, err := c.client.Do(req) 58 if err != nil { 59 return nil, err 60 } 61 return newResponse(response), nil 62 } 63 64 func (c *Client) perform(ctx context.Context, method string, rawurl string, body RequestBody, options ...RequestOption) (*Response, error) { 65 r, err := c.newRequest(ctx, method, rawurl, body, options...) 66 if err != nil { 67 return nil, err 68 } 69 return c.doRequest(r) 70 } 71 72 // Head do HEAD request. 73 func (c *Client) Head(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 74 return c.perform(ctx, http.MethodHead, url, nil, options...) 75 } 76 77 // Connect do CONNECT request. 78 func (c *Client) Connect(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 79 return c.perform(ctx, http.MethodConnect, url, nil, options...) 80 } 81 82 // Options do OPTIONS request. 83 func (c *Client) Options(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 84 return c.perform(ctx, http.MethodConnect, url, nil, options...) 85 } 86 87 // Trace do TRACE request. 88 func (c *Client) Trace(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 89 return c.perform(ctx, http.MethodTrace, url, nil, options...) 90 } 91 92 // Get do GET request. 93 func (c *Client) Get(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 94 return c.perform(ctx, http.MethodGet, url, nil, options...) 95 } 96 97 // Post do POST request. 98 func (c *Client) Post(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 99 return c.perform(ctx, http.MethodPost, url, body, options...) 100 } 101 102 // Put do PUT request. 103 func (c *Client) Put(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 104 return c.perform(ctx, http.MethodPut, url, body, options...) 105 } 106 107 // Patch do PATCH request. 108 func (c *Client) Patch(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 109 return c.perform(ctx, http.MethodPatch, url, body, options...) 110 } 111 112 // Delete do DELETE request. 113 func (c *Client) Delete(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 114 return c.perform(ctx, http.MethodDelete, url, body, options...) 115 } 116 117 // Head do HEAD request. 118 func Head(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 119 return DefaultClient.Head(ctx, url, options...) 120 } 121 122 // Connect do CONNECT request. 123 func Connect(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 124 return DefaultClient.Connect(ctx, url, options...) 125 } 126 127 // Options do OPTIONS request. 128 func Options(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 129 return DefaultClient.Options(ctx, url, options...) 130 } 131 132 // Trace do TRACE request. 133 func Trace(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 134 return DefaultClient.Trace(ctx, url, options...) 135 } 136 137 // Get do GET request. 138 func Get(ctx context.Context, url string, options ...RequestOption) (*Response, error) { 139 return DefaultClient.Get(ctx, url, options...) 140 } 141 142 // Post do POST request. 143 func Post(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 144 return DefaultClient.Post(ctx, url, body, options...) 145 } 146 147 // Put do PUT request. 148 func Put(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 149 return DefaultClient.Put(ctx, url, body, options...) 150 } 151 152 // Patch do PATCH request. 153 func Patch(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 154 return DefaultClient.Patch(ctx, url, body, options...) 155 } 156 157 // Delete do DELETE request. 158 func Delete(ctx context.Context, url string, body RequestBody, options ...RequestOption) (*Response, error) { 159 return DefaultClient.Delete(ctx, url, body, options...) 160 }