From 81b332d2f48622008469d2c5a9b130465a65f2a3 Mon Sep 17 00:00:00 2001 From: Kang Ming Date: Fri, 2 Aug 2024 10:20:48 -0700 Subject: [PATCH] fix: remove check for content-length (#1700) ## What kind of change does this PR introduce? * Not all responses are gonna contain the `Content-Length` header. According to the HTTP/2 spec, it is not required to return the content-length header in the response. If the "Transfer Encoding" is chunked, the content-length header will also not be present as the response is sent in chunks and the content-length is unknown initially. ## What is the current behavior? Please link any relevant issues here. ## What is the new behavior? Feel free to include screenshots if it includes visual changes. ## Additional context Add any other context or screenshots. --- internal/api/errorcodes.go | 1 - internal/api/hooks.go | 15 +++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/internal/api/errorcodes.go b/internal/api/errorcodes.go index 9038dc25d..ce36bb65c 100644 --- a/internal/api/errorcodes.go +++ b/internal/api/errorcodes.go @@ -76,7 +76,6 @@ const ( ErrorCodeHookTimeout ErrorCode = "hook_timeout" ErrorCodeHookTimeoutAfterRetry ErrorCode = "hook_timeout_after_retry" ErrorCodeHookPayloadOverSizeLimit ErrorCode = "hook_payload_over_size_limit" - ErrorCodeHookPayloadUnknownSize ErrorCode = "hook_payload_unknown_size" ErrorCodeRequestTimeout ErrorCode = "request_timeout" ErrorCodeMFAPhoneEnrollDisabled ErrorCode = "mfa_phone_enroll_not_enabled" ErrorCodeMFAPhoneVerifyDisabled ErrorCode = "mfa_phone_verify_not_enabled" diff --git a/internal/api/hooks.go b/internal/api/hooks.go index 197a62f15..7b89dc561 100644 --- a/internal/api/hooks.go +++ b/internal/api/hooks.go @@ -152,18 +152,17 @@ func (a *API) runHTTPHook(r *http.Request, hookConfig conf.ExtensibilityPointCon if rsp.Body == nil { return nil, nil } - contentLength := rsp.ContentLength - if contentLength == -1 { - return nil, unprocessableEntityError(ErrorCodeHookPayloadUnknownSize, "Payload size not known") - } - if contentLength >= PayloadLimit { - return nil, unprocessableEntityError(ErrorCodeHookPayloadOverSizeLimit, fmt.Sprintf("Payload size is: %d bytes exceeded size limit of %d bytes", contentLength, PayloadLimit)) - } - limitedReader := io.LimitedReader{R: rsp.Body, N: contentLength} + limitedReader := io.LimitedReader{R: rsp.Body, N: PayloadLimit} body, err := io.ReadAll(&limitedReader) if err != nil { return nil, err } + if limitedReader.N <= 0 { + // check if the response body still has excess bytes to be read + if n, _ := rsp.Body.Read(make([]byte, 1)); n > 0 { + return nil, unprocessableEntityError(ErrorCodeHookPayloadOverSizeLimit, fmt.Sprintf("Payload size exceeded size limit of %d bytes", PayloadLimit)) + } + } return body, nil case http.StatusTooManyRequests, http.StatusServiceUnavailable: retryAfterHeader := rsp.Header.Get("retry-after")