Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ceeeb18

Browse filesBrowse files
authored
chore: cherry-pick transfer-encoding fix to v2 (#3304)
* fix(http): make Transfer-Encoding detection case-insensitive The HTTP response decoder was checking for "Transfer-Encoding: chunked" using a case-sensitive substring match on the raw header block. Some upstream services (e.g. the Java-based config service) emit "Transfer-encoding: chunked", which caused our code to skip the chunked-body handling path entirely and treat the response as if it had no proper body. As a result, Keploy would: - only capture the headers in the reconstructed response buffer - log "failed to read the http response body: unexpected EOF" in Capture - save testcases with empty or truncated response bodies for those endpoints The fix normalizes header names before checking for transfer-encoding, so both "Transfer-Encoding" and "Transfer-encoding" (and any other case variants) correctly trigger chunked-response handling. Signed-off-by: Anju Pathak <anjupathak9810@gmail.com> * Improve chunked response handling in chunk.go Refactor logic for handling chunked responses in HTTP. Signed-off-by: Anju <168076172+anjupathak03@users.noreply.github.com> --------- Signed-off-by: Anju Pathak <anjupathak9810@gmail.com> Signed-off-by: Anju <168076172+anjupathak03@users.noreply.github.com>
1 parent 0fac6f2 commit ceeeb18
Copy full SHA for ceeeb18

File tree

Expand file treeCollapse file tree

1 file changed

+48
-28
lines changed
Open diff view settings
Filter options
  • pkg/core/proxy/integrations/http
Expand file treeCollapse file tree

1 file changed

+48
-28
lines changed
Open diff view settings
Collapse file

‎pkg/core/proxy/integrations/http/chunk.go‎

Copy file name to clipboardExpand all lines: pkg/core/proxy/integrations/http/chunk.go
+48-28Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,26 @@ func (h *HTTP) HandleChunkedRequests(ctx context.Context, finalReq *[]byte, clie
4646
}
4747

4848
lines := strings.Split(string(*finalReq), "\n")
49-
var contentLengthHeader string
50-
var transferEncodingHeader string
49+
var contentLengthHeader, transferEncodingHeader string
5150
for _, line := range lines {
52-
if strings.HasPrefix(line, "Content-Length:") {
53-
contentLengthHeader = strings.TrimSpace(strings.TrimPrefix(line, "Content-Length:"))
54-
break
55-
} else if strings.HasPrefix(line, "Transfer-Encoding:") {
56-
transferEncodingHeader = strings.TrimSpace(strings.TrimPrefix(line, "Transfer-Encoding:"))
57-
break
51+
line = strings.TrimRight(line, "\r")
52+
if line == "" {
53+
continue
54+
}
55+
56+
parts := strings.SplitN(line, ":", 2)
57+
if len(parts) != 2 {
58+
continue
59+
}
60+
61+
key := strings.ToLower(strings.TrimSpace(parts[0]))
62+
val := strings.TrimSpace(parts[1])
63+
64+
switch key {
65+
case "content-length":
66+
contentLengthHeader = val
67+
case "transfer-encoding":
68+
transferEncodingHeader = val
5869
}
5970
}
6071

@@ -75,13 +86,11 @@ func (h *HTTP) HandleChunkedRequests(ctx context.Context, finalReq *[]byte, clie
7586
}
7687
}
7788
} else if transferEncodingHeader != "" {
78-
// check if the initial request is the complete request.
79-
if strings.HasSuffix(string(*finalReq), "0\r\n\r\n") {
80-
return nil
81-
}
82-
if transferEncodingHeader == "chunked" {
83-
err := h.chunkedRequest(ctx, finalReq, clientConn, destConn, transferEncodingHeader)
84-
if err != nil {
89+
if strings.Contains(strings.ToLower(transferEncodingHeader), "chunked") {
90+
if strings.HasSuffix(string(*finalReq), "0\r\n\r\n") {
91+
return nil
92+
}
93+
if err := h.chunkedRequest(ctx, finalReq, clientConn, destConn, transferEncodingHeader); err != nil {
8594
return err
8695
}
8796
}
@@ -221,12 +230,25 @@ func (h *HTTP) handleChunkedResponses(ctx context.Context, finalResp *[]byte, cl
221230
var contentLengthHeader, transferEncodingHeader string
222231
lines := strings.Split(string(resp), "\n")
223232
for _, line := range lines {
224-
if strings.HasPrefix(line, "Content-Length:") {
225-
contentLengthHeader = strings.TrimSpace(strings.TrimPrefix(line, "Content-Length:"))
226-
break
227-
} else if strings.HasPrefix(line, "Transfer-Encoding:") {
228-
transferEncodingHeader = strings.TrimSpace(strings.TrimPrefix(line, "Transfer-Encoding:"))
229-
break
233+
line = strings.TrimRight(line, "\r") // remove trailing \r if present
234+
if line == "" {
235+
continue
236+
}
237+
238+
// Split key: value
239+
parts := strings.SplitN(line, ":", 2)
240+
if len(parts) != 2 {
241+
continue
242+
}
243+
244+
key := strings.ToLower(strings.TrimSpace(parts[0]))
245+
val := strings.TrimSpace(parts[1])
246+
247+
switch key {
248+
case "content-length":
249+
contentLengthHeader = val
250+
case "transfer-encoding":
251+
transferEncodingHeader = val
230252
}
231253
}
232254
//Handle chunked responses
@@ -245,13 +267,11 @@ func (h *HTTP) handleChunkedResponses(ctx context.Context, finalResp *[]byte, cl
245267
}
246268
}
247269
} else if transferEncodingHeader != "" {
248-
//check if the initial response is the complete response.
249-
if strings.HasSuffix(string(*finalResp), "0\r\n\r\n") {
250-
return nil
251-
}
252-
if transferEncodingHeader == "chunked" {
253-
err := h.chunkedResponse(ctx, finalResp, clientConn, destConn)
254-
if err != nil {
270+
if strings.Contains(strings.ToLower(transferEncodingHeader), "chunked") {
271+
if strings.HasSuffix(string(*finalResp), "0\r\n\r\n") {
272+
return nil
273+
}
274+
if err := h.chunkedResponse(ctx, finalResp, clientConn, destConn); err != nil {
255275
return err
256276
}
257277
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.