fix(zarinhub): limit upstream response size
This commit is contained in:
@@ -13,6 +13,8 @@ import (
|
|||||||
"card-to-iban/internal/service"
|
"card-to-iban/internal/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxResponseBodySize = 1 << 20
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
endpointURL string
|
endpointURL string
|
||||||
@@ -95,7 +97,9 @@ func (c *Client) Convert(
|
|||||||
UpstreamHTTPStatus: resp.StatusCode,
|
UpstreamHTTPStatus: resp.StatusCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(
|
||||||
|
io.LimitReader(resp.Body, maxResponseBodySize+1),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result,
|
return result,
|
||||||
fmt.Errorf(
|
fmt.Errorf(
|
||||||
@@ -105,6 +109,14 @@ func (c *Client) Convert(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(body) > maxResponseBodySize {
|
||||||
|
return result,
|
||||||
|
fmt.Errorf(
|
||||||
|
"%w: response body is too large",
|
||||||
|
ErrInvalidResponse,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
result.RawResponse = body
|
result.RawResponse = body
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -381,3 +381,36 @@ func TestClientReturnsTimeout(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientRejectsOversizedResponse(t *testing.T) {
|
||||||
|
server := httptest.NewServer(
|
||||||
|
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
body := make([]byte, maxResponseBodySize+1)
|
||||||
|
for index := range body {
|
||||||
|
body[index] = 'x'
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(body); err != nil {
|
||||||
|
t.Errorf("write response: %v", err)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
client := NewClient(
|
||||||
|
&http.Client{Timeout: time.Second},
|
||||||
|
server.URL,
|
||||||
|
"test-token",
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err := client.Convert(
|
||||||
|
context.Background(),
|
||||||
|
"6037997512345678",
|
||||||
|
)
|
||||||
|
|
||||||
|
if !errors.Is(err, ErrInvalidResponse) {
|
||||||
|
t.Fatalf("error = %v, want ErrInvalidResponse", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user