From f28c7dde466c8e7b9773d71e0cc1a516e1f7968e Mon Sep 17 00:00:00 2001 From: Rowan Seymour Date: Sat, 28 Oct 2023 09:20:05 -0500 Subject: [PATCH] Use error constants for some httpx error cases --- httpx/access_test.go | 41 ++++++++++++++++++----------------------- httpx/http.go | 10 ++++++++-- httpx/http_test.go | 3 ++- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/httpx/access_test.go b/httpx/access_test.go index 850d838..5ef996b 100644 --- a/httpx/access_test.go +++ b/httpx/access_test.go @@ -35,41 +35,36 @@ func TestAccessConfig(t *testing.T) { })) tests := []struct { - url string - err string + url string + allowed bool }{ // allowed - {"https://nyaruka.com", ""}, - {"https://11.0.0.0", ""}, + {"https://nyaruka.com", true}, + {"https://11.0.0.0", true}, // denied by IP match - {"https://localhost/path", "request to localhost denied"}, - {"https://LOCALHOST:80", "request to LOCALHOST denied"}, - {"http://foo.localtest.me", "request to foo.localtest.me denied"}, - {"https://127.0.0.1", "request to 127.0.0.1 denied"}, - {"https://127.0.00.1", "?"}, // Go 1.19: "request to 127.0.00.1 denied", Go 1.20: "lookup 127.0.00.1: no such host" - {"https://[::1]:80", "request to ::1 denied"}, - {"https://[0:0:0:0:0:0:0:1]:80", "request to 0:0:0:0:0:0:0:1 denied"}, - {"https://[0000:0000:0000:0000:0000:0000:0000:0001]:80", "request to 0000:0000:0000:0000:0000:0000:0000:0001 denied"}, + {"https://localhost/path", false}, + {"https://LOCALHOST:80", false}, + {"http://foo.localtest.me", false}, + {"https://127.0.0.1", false}, + {"https://[::1]:80", false}, + {"https://[0:0:0:0:0:0:0:1]:80", false}, + {"https://[0000:0000:0000:0000:0000:0000:0000:0001]:80", false}, // denied by network match - {"https://10.1.0.0", "request to 10.1.0.0 denied"}, - {"https://10.0.1.0", "request to 10.0.1.0 denied"}, - {"https://10.0.0.1", "request to 10.0.0.1 denied"}, - {"https://[0:0:0:0:0:ffff:0a01:0000]:80", "request to 0:0:0:0:0:ffff:0a01:0000 denied"}, // 10.1.0.0 mapped to IPv6 + {"https://10.1.0.0", false}, + {"https://10.0.1.0", false}, + {"https://10.0.0.1", false}, + {"https://[0:0:0:0:0:ffff:0a01:0000]:80", false}, // 10.1.0.0 mapped to IPv6 } for _, tc := range tests { request, _ := http.NewRequest("GET", tc.url, nil) _, err := httpx.DoTrace(http.DefaultClient, request, nil, access, -1) - if tc.err != "" { - if tc.err == "?" { - assert.Error(t, err) - } else { - assert.EqualError(t, err, tc.err, "error message mismatch for url %s", tc.url) - } - } else { + if tc.allowed { assert.NoError(t, err) + } else { + assert.Equal(t, err, httpx.ErrAccessConfig, "error message mismatch for url %s", tc.url) } } } diff --git a/httpx/http.go b/httpx/http.go index 442db8f..d2d9512 100644 --- a/httpx/http.go +++ b/httpx/http.go @@ -16,6 +16,12 @@ import ( "github.com/pkg/errors" ) +// ErrResponseSize is returned when response size exceeds provided limit +var ErrResponseSize = errors.New("response body exceeds size limit") + +// ErrAccessConfig is returned when provided access config prevents request +var ErrAccessConfig = errors.New("request not permitted by access config") + // Do makes the given HTTP request using the current requestor and retry config func Do(client *http.Client, request *http.Request, retries *RetryConfig, access *AccessConfig) (*http.Response, error) { r, _, err := do(client, request, retries, access) @@ -29,7 +35,7 @@ func do(client *http.Client, request *http.Request, retries *RetryConfig, access return nil, 0, err } if !allowed { - return nil, 0, errors.Errorf("request to %s denied", request.URL.Hostname()) + return nil, 0, ErrAccessConfig } } @@ -198,7 +204,7 @@ func readBody(response *http.Response, maxBodyBytes int) ([]byte, error) { // if we have no remaining bytes, error because the body was too big if bodyReader.(*io.LimitedReader).N <= 0 { - return nil, errors.Errorf("webhook response body exceeds %d bytes limit", maxBodyBytes) + return nil, ErrResponseSize } return bodyBytes, nil diff --git a/httpx/http_test.go b/httpx/http_test.go index 8f357b5..3ee1e87 100644 --- a/httpx/http_test.go +++ b/httpx/http_test.go @@ -157,7 +157,8 @@ func TestMaxBodyBytes(t *testing.T) { assert.Equal(t, string(testBody), string(trace.ResponseBody)) trace, err = call(10) // limit smaller than body - assert.EqualError(t, err, `webhook response body exceeds 10 bytes limit`) + assert.Equal(t, err, httpx.ErrResponseSize) + assert.EqualError(t, err, `response body exceeds size limit`) assert.Equal(t, "HTTP/1.0 200 OK\r\nContent-Length: 26\r\n\r\n", string(trace.ResponseTrace)) assert.Equal(t, ``, string(trace.ResponseBody)) }