Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/proxy/http/HttpTransact.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,7 @@ HttpTransact::HandleRequest(State *s)
}
}
}
if (s->txn_conf->request_buffer_enabled &&
if (s->txn_conf->request_buffer_enabled && s->http_config_param->post_copy_size > 0 &&
s->state_machine->get_ua_txn()->has_request_body(s->hdr_info.request_content_length,
s->client_info.transfer_encoding == TransferEncoding_t::CHUNKED)) {
TRANSACT_RETURN(StateMachineAction_t::WAIT_FOR_FULL_BODY, nullptr);
Expand Down
89 changes: 89 additions & 0 deletions tests/gold_tests/pluginTest/test_hooks/body_buffer.test.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,94 @@ def run(self):
tr.Processes.Default.Streams.stderr = "200.gold"


class ZeroPostCopySizeTest:
'''
Test for issue #6900: Verify that post_copy_size=0 with request_buffer_enabled=1
does not cause 403 errors. When post_copy_size is 0, request buffering should be
disabled and POST requests should proceed normally.
'''

def __init__(self):
self.setupOriginServer()
self.setupTS()

def setupOriginServer(self):
self._server = Test.MakeOriginServer("server_zero_copy")
# Empty body POST
request_header_empty = {
"headers": "POST /empty HTTP/1.1\r\n"
"Host: www.example.com\r\n"
"Content-Length: 0\r\n\r\n",
"timestamp": "1469733493.993",
"body": ""
}
response_header_empty = {
"headers": "HTTP/1.1 200 OK\r\n"
"Server: microserver\r\n"
"Content-Length: 2\r\n"
"Connection: close\r\n\r\n",
"timestamp": "1469733493.993",
"body": "OK"
}
self._server.addResponse("sessionlog.json", request_header_empty, response_header_empty)

# Small body POST
self.small_body = "small"
request_header_small = {
"headers": "POST /small HTTP/1.1\r\n"
"Host: www.example.com\r\n"
f"Content-Length: {len(self.small_body)}\r\n\r\n",
"timestamp": "1469733493.993",
"body": self.small_body
}
response_header_small = {
"headers": "HTTP/1.1 200 OK\r\n"
"Server: microserver\r\n"
"Content-Length: 2\r\n"
"Connection: close\r\n\r\n",
"timestamp": "1469733493.993",
"body": "OK"
}
self._server.addResponse("sessionlog.json", request_header_small, response_header_small)

def setupTS(self):
# Use default port selection (not select_ports=False) to avoid port conflicts
self._ts = Test.MakeATSProcess("ts_zero_copy")
self._ts.Disk.remap_config.AddLine(f'map / http://127.0.0.1:{self._server.Variables.Port}')
# Install the request_buffer plugin to enable per-request buffering
Test.PrepareInstalledPlugin('request_buffer.so', self._ts)
self._ts.Disk.records_config.update(
{
'proxy.config.diags.debug.enabled': 1,
'proxy.config.diags.debug.tags': 'http|request_buffer',
# The key configuration: post_copy_size=0 with request_buffer_enabled=1
# This should NOT cause 403 errors (issue #6900 fix)
# The plugin will enable buffering per-request, but with post_copy_size=0
# buffering should be disabled and the request should proceed normally
'proxy.config.http.post_copy_size': 0,
'proxy.config.http.request_buffer_enabled': 1,
})

def run(self):
tr = Test.AddTestRun()
# Send POST with empty body and small body.
# These should return 200, not 403, verifying the fix for issue #6900.
tr.MakeCurlCommand(
f'-v -X POST -H "Content-Length: 0" http://127.0.0.1:{self._ts.Variables.port}/empty --next '
f'-v http://127.0.0.1:{self._ts.Variables.port}/small -d {self.small_body}',
ts=self._ts)
tr.Processes.Default.ReturnCode = 0
tr.Processes.Default.StartBefore(self._server)
tr.Processes.Default.StartBefore(self._ts)
# Verify we get 200 OK, not 403 Forbidden
tr.Processes.Default.Streams.stderr += Testers.ContainsExpression(
"< HTTP/1.1 200 OK", "Verify POST with empty body returns 200")
tr.Processes.Default.Streams.stderr += Testers.ExcludesExpression("< HTTP/1.1 403", "Verify no 403 Forbidden errors")


bodyBufferTest = BodyBufferTest("Test request body buffering.")
bodyBufferTest.run()

# Test for issue #6900: post_copy_size=0 should not cause 403 errors
zeroCopySizeTest = ZeroPostCopySizeTest()
zeroCopySizeTest.run()