|
1 | 1 | ''' |
2 | | -Verify HTTP body buffering. |
| 2 | +Verify HTTP body buffering with request_buffer.so plugin. |
3 | 3 | ''' |
4 | 4 | # Licensed to the Apache Software Foundation (ASF) under one |
5 | 5 | # or more contributor license agreements. See the NOTICE file |
|
17 | 17 | # See the License for the specific language governing permissions and |
18 | 18 | # limitations under the License. |
19 | 19 |
|
20 | | -Test.SkipUnless(Condition.PluginExists('request_buffer.so')) |
21 | | - |
22 | | - |
23 | | -def int_to_hex_string(int_value): |
24 | | - ''' |
25 | | - Convert the given int value to a hex string with no '0x' prefix. |
26 | | -
|
27 | | - >>> int_to_hex_string(0) |
28 | | - '0' |
29 | | - >>> int_to_hex_string(1) |
30 | | - '1' |
31 | | - >>> int_to_hex_string(10) |
32 | | - 'a' |
33 | | - >>> int_to_hex_string(16) |
34 | | - '10' |
35 | | - >>> int_to_hex_string(17) |
36 | | - 'f1' |
37 | | - ''' |
38 | | - if not isinstance(int_value, int): |
39 | | - raise ValueError("Input should be an int type.") |
40 | | - return hex(int_value).split('x')[1] |
41 | | - |
42 | | - |
43 | | -class BodyBufferTest: |
| 20 | +Test.Summary = 'Verify HTTP body buffering with request_buffer.so plugin.' |
44 | 21 |
|
45 | | - def __init__(cls, description): |
46 | | - Test.Summary = description |
47 | | - cls._origin_max_connections = 3 |
48 | | - cls.setupOriginServer() |
49 | | - cls.setupTS() |
50 | | - |
51 | | - def setupOriginServer(self): |
52 | | - self._server = Test.MakeOriginServer("server") |
53 | | - self.content_length_request_body = "content-length request" |
54 | | - self.content_length_size = len(self.content_length_request_body) |
55 | | - request_header = { |
56 | | - "headers": |
57 | | - "POST /contentlength HTTP/1.1\r\n" |
58 | | - "Host: www.example.com\r\n" |
59 | | - f"Content-Length: {self.content_length_size}\r\n\r\n", |
60 | | - "timestamp": "1469733493.993", |
61 | | - "body": self.content_length_request_body |
62 | | - } |
63 | | - content_length_response_body = "content-length response" |
64 | | - content_length_response_size = len(content_length_response_body) |
65 | | - response_header = { |
66 | | - "headers": |
67 | | - "HTTP/1.1 200 OK\r\n" |
68 | | - "Server: microserver\r\n" |
69 | | - f"Content-Length: {content_length_response_size}\r\n\r\n" |
70 | | - "Connection: close\r\n\r\n", |
71 | | - "timestamp": "1469733493.993", |
72 | | - "body": content_length_response_body |
73 | | - } |
74 | | - self._server.addResponse("sessionlog.json", request_header, response_header) |
75 | | - |
76 | | - self.chunked_request_body = "chunked request" |
77 | | - hex_size = int_to_hex_string(len(self.chunked_request_body)) |
78 | | - self.encoded_chunked_request = f"{hex_size}\r\n{self.chunked_request_body}\r\n0\r\n\r\n" |
79 | | - self.encoded_chunked_size = len(self.content_length_request_body) |
80 | | - request_header2 = { |
81 | | - "headers": |
82 | | - "POST /chunked HTTP/1.1\r\n" |
83 | | - "Transfer-Encoding: chunked\r\n" |
84 | | - "Host: www.example.com\r\n" |
85 | | - "Connection: keep-alive\r\n\r\n", |
86 | | - "timestamp": "1469733493.993", |
87 | | - "body": self.encoded_chunked_request |
88 | | - } |
89 | | - self.chunked_response_body = "chunked response" |
90 | | - hex_size = int_to_hex_string(len(self.chunked_response_body)) |
91 | | - self.encoded_chunked_response = f"{hex_size}\r\n{self.chunked_response_body}\r\n0\r\n\r\n" |
92 | | - response_header2 = { |
93 | | - "headers": "HTTP/1.1 200 OK\r\n" |
94 | | - "Transfer-Encoding: chunked\r\n" |
95 | | - "Server: microserver\r\n" |
96 | | - "Connection: close\r\n\r\n", |
97 | | - "timestamp": "1469733493.993", |
98 | | - "body": self.encoded_chunked_response |
99 | | - } |
100 | | - self._server.addResponse("sessionlog.json", request_header2, response_header2) |
101 | | - |
102 | | - def setupTS(self): |
103 | | - self._ts = Test.MakeATSProcess("ts", select_ports=False) |
104 | | - self._ts.Disk.remap_config.AddLine(f'map / http://127.0.0.1:{self._server.Variables.Port}') |
105 | | - Test.PrepareInstalledPlugin('request_buffer.so', self._ts) |
106 | | - self._ts.Disk.records_config.update( |
107 | | - { |
108 | | - 'proxy.config.diags.debug.enabled': 1, |
109 | | - 'proxy.config.diags.debug.tags': 'request_buffer', |
110 | | - 'proxy.config.http.server_ports': str(self._ts.Variables.port) + f" {self._ts.Variables.uds_path}", |
111 | | - }) |
112 | | - |
113 | | - self._ts.Disk.traffic_out.Content = Testers.ContainsExpression( |
114 | | - rf"request_buffer_plugin gets the request body with length\[{self.content_length_size}\]", |
115 | | - "Verify that the plugin parsed the content-length request body data.") |
116 | | - self._ts.Disk.traffic_out.Content += Testers.ContainsExpression( |
117 | | - rf"request_buffer_plugin gets the request body with length\[{self.encoded_chunked_size}\]", |
118 | | - "Verify that the plugin parsed the chunked request body.") |
119 | | - |
120 | | - def run(self): |
121 | | - tr = Test.AddTestRun() |
122 | | - # Send both a Content-Length request and a chunked-encoded request. |
123 | | - tr.MakeCurlCommand( |
124 | | - f'-v http://127.0.0.1:{self._ts.Variables.port}/contentlength -d "{self.content_length_request_body}" --next ' |
125 | | - f'-v http://127.0.0.1:{self._ts.Variables.port}/chunked -H "Transfer-Encoding: chunked" -d "{self.chunked_request_body}"', |
126 | | - ts=self._ts) |
127 | | - tr.Processes.Default.ReturnCode = 0 |
128 | | - tr.Processes.Default.StartBefore(self._server) |
129 | | - tr.Processes.Default.StartBefore(Test.Processes.ts) |
130 | | - tr.Processes.Default.Streams.stderr = "200.gold" |
| 22 | +Test.SkipUnless(Condition.PluginExists('request_buffer.so')) |
131 | 23 |
|
| 24 | +Test.ATSReplayTest(replay_file="replay/body_buffer.replay.yaml") |
132 | 25 |
|
133 | | -bodyBufferTest = BodyBufferTest("Test request body buffering.") |
134 | | -bodyBufferTest.run() |
| 26 | +# Test for issue #6900: post_copy_size=0 with request_buffer_enabled should not cause 403. |
| 27 | +Test.ATSReplayTest(replay_file="replay/zero_post_copy_size.replay.yaml") |
0 commit comments