diff --git a/httpclient/client.go b/httpclient/client.go index 5f03c5b..4df377d 100644 --- a/httpclient/client.go +++ b/httpclient/client.go @@ -57,10 +57,9 @@ func (c *Client) AddPlugin(p heimdall.Plugin) { // Get makes a HTTP GET request to provided URL func (c *Client) Get(url string, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - return response, errors.Wrap(err, "GET - request creation failed") + return nil, errors.Wrap(err, "GET - request creation failed") } request.Header = headers @@ -70,10 +69,9 @@ func (c *Client) Get(url string, headers http.Header) (*http.Response, error) { // Post makes a HTTP POST request to provided URL and requestBody func (c *Client) Post(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPost, url, body) if err != nil { - return response, errors.Wrap(err, "POST - request creation failed") + return nil, errors.Wrap(err, "POST - request creation failed") } request.Header = headers @@ -83,10 +81,9 @@ func (c *Client) Post(url string, body io.Reader, headers http.Header) (*http.Re // Put makes a HTTP PUT request to provided URL and requestBody func (c *Client) Put(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPut, url, body) if err != nil { - return response, errors.Wrap(err, "PUT - request creation failed") + return nil, errors.Wrap(err, "PUT - request creation failed") } request.Header = headers @@ -96,10 +93,9 @@ func (c *Client) Put(url string, body io.Reader, headers http.Header) (*http.Res // Patch makes a HTTP PATCH request to provided URL and requestBody func (c *Client) Patch(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPatch, url, body) if err != nil { - return response, errors.Wrap(err, "PATCH - request creation failed") + return nil, errors.Wrap(err, "PATCH - request creation failed") } request.Header = headers @@ -109,10 +105,21 @@ func (c *Client) Patch(url string, body io.Reader, headers http.Header) (*http.R // Delete makes a HTTP DELETE request with provided URL func (c *Client) Delete(url string, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodDelete, url, nil) if err != nil { - return response, errors.Wrap(err, "DELETE - request creation failed") + return nil, errors.Wrap(err, "DELETE - request creation failed") + } + + request.Header = headers + + return c.Do(request) +} + +// Head makes a HTTP HEAD request with provided URL +func (c *Client) Head(url string, headers http.Header) (*http.Response, error) { + request, err := http.NewRequest(http.MethodHead, url, nil) + if err != nil { + return nil, errors.Wrap(err, "HEAD - request creation failed") } request.Header = headers diff --git a/httpclient/client_test.go b/httpclient/client_test.go index dbca35d..7cbc6e0 100644 --- a/httpclient/client_test.go +++ b/httpclient/client_test.go @@ -131,6 +131,32 @@ func TestHTTPClientDeleteSuccess(t *testing.T) { assert.Equal(t, "{ \"response\": \"ok\" }", respBody(t, response)) } +func TestHTTPClientHeadSuccess(t *testing.T) { + client := NewClient(WithHTTPTimeout(10 * time.Millisecond)) + + dummyHandler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodHead, r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + assert.Equal(t, "en", r.Header.Get("Accept-Language")) + + w.Header().Add("x-foo", "bar") + w.WriteHeader(http.StatusOK) + } + + server := httptest.NewServer(http.HandlerFunc(dummyHandler)) + defer server.Close() + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept-Language", "en") + + response, err := client.Head(server.URL, headers) + require.NoError(t, err, "should not have failed to make a HEAD request") + + assert.Equal(t, http.StatusOK, response.StatusCode) + assert.Equal(t, "bar", response.Header.Get("x-foo")) +} + func TestHTTPClientPutSuccess(t *testing.T) { client := NewClient(WithHTTPTimeout(10 * time.Millisecond)) diff --git a/hystrix/hystrix_client.go b/hystrix/hystrix_client.go index 01c0ca3..42475de 100644 --- a/hystrix/hystrix_client.go +++ b/hystrix/hystrix_client.go @@ -102,10 +102,9 @@ func durationToInt(duration, unit time.Duration) int { // Get makes a HTTP GET request to provided URL func (hhc *Client) Get(url string, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - return response, errors.Wrap(err, "GET - request creation failed") + return nil, errors.Wrap(err, "GET - request creation failed") } request.Header = headers @@ -115,10 +114,9 @@ func (hhc *Client) Get(url string, headers http.Header) (*http.Response, error) // Post makes a HTTP POST request to provided URL and requestBody func (hhc *Client) Post(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPost, url, body) if err != nil { - return response, errors.Wrap(err, "POST - request creation failed") + return nil, errors.Wrap(err, "POST - request creation failed") } request.Header = headers @@ -128,10 +126,9 @@ func (hhc *Client) Post(url string, body io.Reader, headers http.Header) (*http. // Put makes a HTTP PUT request to provided URL and requestBody func (hhc *Client) Put(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPut, url, body) if err != nil { - return response, errors.Wrap(err, "PUT - request creation failed") + return nil, errors.Wrap(err, "PUT - request creation failed") } request.Header = headers @@ -141,10 +138,9 @@ func (hhc *Client) Put(url string, body io.Reader, headers http.Header) (*http.R // Patch makes a HTTP PATCH request to provided URL and requestBody func (hhc *Client) Patch(url string, body io.Reader, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodPatch, url, body) if err != nil { - return response, errors.Wrap(err, "PATCH - request creation failed") + return nil, errors.Wrap(err, "PATCH - request creation failed") } request.Header = headers @@ -154,10 +150,21 @@ func (hhc *Client) Patch(url string, body io.Reader, headers http.Header) (*http // Delete makes a HTTP DELETE request with provided URL func (hhc *Client) Delete(url string, headers http.Header) (*http.Response, error) { - var response *http.Response request, err := http.NewRequest(http.MethodDelete, url, nil) if err != nil { - return response, errors.Wrap(err, "DELETE - request creation failed") + return nil, errors.Wrap(err, "DELETE - request creation failed") + } + + request.Header = headers + + return hhc.Do(request) +} + +// Head makes a HTTP HEAD request with provided URL +func (hhc *Client) Head(url string, headers http.Header) (*http.Response, error) { + request, err := http.NewRequest(http.MethodHead, url, nil) + if err != nil { + return nil, errors.Wrap(err, "HEAD - request creation failed") } request.Header = headers diff --git a/hystrix/hystrix_client_test.go b/hystrix/hystrix_client_test.go index 65a7bbd..e49c92f 100644 --- a/hystrix/hystrix_client_test.go +++ b/hystrix/hystrix_client_test.go @@ -171,6 +171,40 @@ func TestHystrixHTTPClientDeleteSuccess(t *testing.T) { assert.Equal(t, "{ \"response\": \"ok\" }", respBody(t, response)) } +func TestHystrixHTTPClientHeadSuccess(t *testing.T) { + client := NewClient( + WithHTTPTimeout(10*time.Millisecond), + WithCommandName("head_command"), + WithHystrixTimeout(10*time.Millisecond), + WithMaxConcurrentRequests(100), + WithErrorPercentThreshold(10), + WithSleepWindow(100), + WithRequestVolumeThreshold(10), + ) + + dummyHandler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodHead, r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + assert.Equal(t, "en", r.Header.Get("Accept-Language")) + + w.Header().Add("x-foo", "bar") + w.WriteHeader(http.StatusOK) + } + + server := httptest.NewServer(http.HandlerFunc(dummyHandler)) + defer server.Close() + + headers := http.Header{} + headers.Set("Content-Type", "application/json") + headers.Set("Accept-Language", "en") + + response, err := client.Head(server.URL, headers) + require.NoError(t, err, "should not have failed to make a HEAD request") + + assert.Equal(t, http.StatusOK, response.StatusCode) + assert.Equal(t, "bar", response.Header.Get("x-foo")) +} + func TestHystrixHTTPClientPutSuccess(t *testing.T) { client := NewClient( WithHTTPTimeout(10*time.Millisecond),