diff options
| author | Shulhan <ms@kilabit.info> | 2022-10-28 10:42:16 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2022-10-28 11:10:29 +0700 |
| commit | 542a11bc463dfaea70ba95fd089b4e1c820f2b38 (patch) | |
| tree | 5be7377ee3ef79e8b2856fc62a2e6d69f9adc109 /lib/http | |
| parent | 8080dad8f616f5e82a4967de449a97423245cfc2 (diff) | |
| download | pakakeh.go-542a11bc463dfaea70ba95fd089b4e1c820f2b38.tar.xz | |
lib/http: sanitize ServerUrl and request path
This is to fix double slash in case the ServerUrl end with it and the
request path begin with it.
For example, "http://127.0.0.1/" and "/" should send request to
"http://127.0.0.1/" not "http://127.0.0.1//".
Diffstat (limited to 'lib/http')
| -rw-r--r-- | lib/http/client.go | 53 | ||||
| -rw-r--r-- | lib/http/client_options.go | 2 | ||||
| -rw-r--r-- | lib/http/endpoint_example_test.go | 11 |
3 files changed, 39 insertions, 27 deletions
diff --git a/lib/http/client.go b/lib/http/client.go index 4fc51c68..477d506e 100644 --- a/lib/http/client.go +++ b/lib/http/client.go @@ -21,6 +21,7 @@ import ( "net/http" "net/http/httputil" "net/url" + "path" "strings" "time" @@ -81,14 +82,14 @@ func NewClient(opts *ClientOptions) (client *Client) { // Delete send the DELETE request to server using path and params as query // parameters. // On success, it will return the uncompressed response body. -func (client *Client) Delete(path string, headers http.Header, params url.Values) ( +func (client *Client) Delete(requestPath string, headers http.Header, params url.Values) ( httpRes *http.Response, resBody []byte, err error, ) { if params != nil { - path += "?" + params.Encode() + requestPath += `?` + params.Encode() } - return client.doRequest(http.MethodDelete, headers, path, "", nil) + return client.doRequest(http.MethodDelete, headers, requestPath, ``, nil) } // Do overwrite the standard http Client.Do to allow debugging request and @@ -216,7 +217,7 @@ out: // be encoded as JSON in body. func (client *Client) GenerateHttpRequest( method RequestMethod, - path string, + requestPath string, requestType RequestType, headers http.Header, params interface{}, @@ -242,7 +243,7 @@ func (client *Client) GenerateHttpRequest( RequestMethodTrace: if isParamsUrlValues { - path += "?" + paramsAsUrlValues.Encode() + requestPath += `?` + paramsAsUrlValues.Encode() } case RequestMethodPatch, @@ -251,7 +252,7 @@ func (client *Client) GenerateHttpRequest( switch requestType { case RequestTypeQuery: if isParamsUrlValues { - path += "?" + paramsAsUrlValues.Encode() + requestPath += `?` + paramsAsUrlValues.Encode() } case RequestTypeForm: @@ -282,7 +283,8 @@ func (client *Client) GenerateHttpRequest( } } - fullURL := client.opts.ServerUrl + path + requestPath = path.Join(`/`, requestPath) + fullURL := client.opts.ServerUrl + requestPath httpRequest, err = http.NewRequest(method.String(), fullURL, body) if err != nil { @@ -302,42 +304,42 @@ func (client *Client) GenerateHttpRequest( // Get send the GET request to server using path and params as query // parameters. // On success, it will return the uncompressed response body. -func (client *Client) Get(path string, headers http.Header, params url.Values) ( +func (client *Client) Get(requestPath string, headers http.Header, params url.Values) ( httpRes *http.Response, resBody []byte, err error, ) { if params != nil { - path += "?" + params.Encode() + requestPath += `?` + params.Encode() } - return client.doRequest(http.MethodGet, headers, path, "", nil) + return client.doRequest(http.MethodGet, headers, requestPath, ``, nil) } // Post send the POST request to path without setting "Content-Type". // If the params is not nil, it will send as query parameters in the path. -func (client *Client) Post(path string, headers http.Header, params url.Values) ( +func (client *Client) Post(requestPath string, headers http.Header, params url.Values) ( httpRes *http.Response, resBody []byte, err error, ) { if params != nil { - path += "?" + params.Encode() + requestPath += `?` + params.Encode() } - return client.doRequest(http.MethodPost, headers, path, "", nil) + return client.doRequest(http.MethodPost, headers, requestPath, ``, nil) } // PostForm send the POST request to path using // "application/x-www-form-urlencoded". -func (client *Client) PostForm(path string, headers http.Header, params url.Values) ( +func (client *Client) PostForm(requestPath string, headers http.Header, params url.Values) ( httpRes *http.Response, resBody []byte, err error, ) { body := strings.NewReader(params.Encode()) - return client.doRequest(http.MethodPost, headers, path, ContentTypeForm, body) + return client.doRequest(http.MethodPost, headers, requestPath, ContentTypeForm, body) } // PostFormData send the POST request to path with all parameters is send // using "multipart/form-data". func (client *Client) PostFormData( - path string, + requestPath string, headers http.Header, params map[string][]byte, ) ( @@ -350,12 +352,12 @@ func (client *Client) PostFormData( body := strings.NewReader(strBody) - return client.doRequest(http.MethodPost, headers, path, contentType, body) + return client.doRequest(http.MethodPost, headers, requestPath, contentType, body) } // PostJSON send the POST request with content type set to "application/json" // and params encoded automatically to JSON. -func (client *Client) PostJSON(path string, headers http.Header, params interface{}) ( +func (client *Client) PostJSON(requestPath string, headers http.Header, params interface{}) ( httpRes *http.Response, resBody []byte, err error, ) { paramsJSON, err := json.Marshal(params) @@ -365,21 +367,21 @@ func (client *Client) PostJSON(path string, headers http.Header, params interfac body := bytes.NewReader(paramsJSON) - return client.doRequest(http.MethodPost, headers, path, ContentTypeJSON, body) + return client.doRequest(http.MethodPost, headers, requestPath, ContentTypeJSON, body) } // Put send the HTTP PUT request with specific content type and body to // specific path at the server. -func (client *Client) Put(path string, headers http.Header, body []byte) ( +func (client *Client) Put(requestPath string, headers http.Header, body []byte) ( *http.Response, []byte, error, ) { bodyReader := bytes.NewReader(body) - return client.doRequest(http.MethodPut, headers, path, "", bodyReader) + return client.doRequest(http.MethodPut, headers, requestPath, ``, bodyReader) } // PutJSON send the PUT request with content type set to "application/json" // and params encoded automatically to JSON. -func (client *Client) PutJSON(path string, headers http.Header, params interface{}) ( +func (client *Client) PutJSON(requestPath string, headers http.Header, params interface{}) ( httpRes *http.Response, resBody []byte, err error, ) { paramsJSON, err := json.Marshal(params) @@ -389,18 +391,19 @@ func (client *Client) PutJSON(path string, headers http.Header, params interface body := bytes.NewReader(paramsJSON) - return client.doRequest(http.MethodPut, headers, path, ContentTypeJSON, body) + return client.doRequest(http.MethodPut, headers, requestPath, ContentTypeJSON, body) } func (client *Client) doRequest( httpMethod string, headers http.Header, - path, contentType string, + requestPath, contentType string, body io.Reader, ) ( httpRes *http.Response, resBody []byte, err error, ) { - fullURL := client.opts.ServerUrl + path + requestPath = path.Join(`/`, requestPath) + fullURL := client.opts.ServerUrl + requestPath httpReq, err := http.NewRequest(httpMethod, fullURL, body) if err != nil { diff --git a/lib/http/client_options.go b/lib/http/client_options.go index 2357fd6d..d881ba12 100644 --- a/lib/http/client_options.go +++ b/lib/http/client_options.go @@ -2,6 +2,7 @@ package http import ( "net/http" + "strings" "time" ) @@ -38,4 +39,5 @@ func (opts *ClientOptions) init() { if opts.Timeout <= 0 { opts.Timeout = defClientTimeout } + opts.ServerUrl = strings.TrimSuffix(opts.ServerUrl, `/`) } diff --git a/lib/http/endpoint_example_test.go b/lib/http/endpoint_example_test.go index e5e8238b..231421ce 100644 --- a/lib/http/endpoint_example_test.go +++ b/lib/http/endpoint_example_test.go @@ -6,6 +6,7 @@ package http import ( "fmt" + "log" "net/http" "net/url" "strconv" @@ -58,11 +59,17 @@ func ExampleEndpoint_errorHandler() { params := url.Values{} params.Set("error", "400:error with status code") - httpres, resbody, _ := client.Get("/", nil, params) + httpres, resbody, err := client.Get(`/`, nil, params) + if err != nil { + log.Fatal(err) + } fmt.Printf("%d: %s\n", httpres.StatusCode, resbody) params.Set("error", "error without status code") - httpres, resbody, _ = client.Get("/", nil, params) + httpres, resbody, err = client.Get(`/`, nil, params) + if err != nil { + log.Fatal(err) + } fmt.Printf("%d: %s\n", httpres.StatusCode, resbody) // Output: |
