xref: /aosp_15_r20/external/grpc-grpc/test/core/http/parser_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "src/core/lib/http/parser.h"
20 
21 #include <stdarg.h>
22 #include <string.h>
23 
24 #include <string>
25 
26 #include "absl/status/status.h"
27 #include "absl/strings/str_format.h"
28 #include "gtest/gtest.h"
29 
30 #include <grpc/support/alloc.h>
31 
32 #include "src/core/lib/gpr/useful.h"
33 #include "test/core/util/slice_splitter.h"
34 #include "test/core/util/test_config.h"
35 
test_request_succeeds(grpc_slice_split_mode split_mode,const char * request_text,const char * expect_method,grpc_http_version expect_version,const char * expect_path,const char * expect_body,...)36 static void test_request_succeeds(grpc_slice_split_mode split_mode,
37                                   const char* request_text,
38                                   const char* expect_method,
39                                   grpc_http_version expect_version,
40                                   const char* expect_path,
41                                   const char* expect_body, ...) {
42   grpc_http_parser parser;
43   grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
44   size_t num_slices;
45   size_t i;
46   grpc_slice* slices;
47   va_list args;
48   grpc_http_request request;
49   memset(&request, 0, sizeof(request));
50 
51   grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
52   grpc_slice_unref(input_slice);
53 
54   grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
55 
56   for (i = 0; i < num_slices; i++) {
57     ASSERT_EQ(grpc_http_parser_parse(&parser, slices[i], nullptr),
58               absl::OkStatus());
59     grpc_slice_unref(slices[i]);
60   }
61   ASSERT_EQ(grpc_http_parser_eof(&parser), absl::OkStatus());
62 
63   ASSERT_EQ(GRPC_HTTP_REQUEST, parser.type);
64   ASSERT_STREQ(expect_method, request.method);
65   ASSERT_STREQ(expect_path, request.path);
66   ASSERT_EQ(expect_version, request.version);
67 
68   if (expect_body != nullptr) {
69     ASSERT_EQ(strlen(expect_body), request.body_length);
70     ASSERT_EQ(0, memcmp(expect_body, request.body, request.body_length));
71   } else {
72     ASSERT_EQ(request.body_length, 0);
73   }
74 
75   va_start(args, expect_body);
76   i = 0;
77   for (;;) {
78     char* expect_key;
79     char* expect_value;
80     expect_key = va_arg(args, char*);
81     if (!expect_key) break;
82     ASSERT_LT(i, request.hdr_count);
83     expect_value = va_arg(args, char*);
84     ASSERT_TRUE(expect_value);
85     ASSERT_STREQ(expect_key, request.hdrs[i].key);
86     ASSERT_STREQ(expect_value, request.hdrs[i].value);
87     i++;
88   }
89   va_end(args);
90   ASSERT_EQ(i, request.hdr_count);
91 
92   grpc_http_request_destroy(&request);
93   grpc_http_parser_destroy(&parser);
94   gpr_free(slices);
95 }
96 
test_succeeds(grpc_slice_split_mode split_mode,const char * response_text,int expect_status,const char * expect_body,...)97 static void test_succeeds(grpc_slice_split_mode split_mode,
98                           const char* response_text, int expect_status,
99                           const char* expect_body, ...) {
100   grpc_http_parser parser;
101   grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
102   size_t num_slices;
103   size_t i;
104   grpc_slice* slices;
105   va_list args;
106   grpc_http_response response;
107   response = {};
108 
109   grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
110   grpc_slice_unref(input_slice);
111 
112   grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
113 
114   for (i = 0; i < num_slices; i++) {
115     ASSERT_EQ(grpc_http_parser_parse(&parser, slices[i], nullptr),
116               absl::OkStatus());
117     grpc_slice_unref(slices[i]);
118   }
119   ASSERT_EQ(grpc_http_parser_eof(&parser), absl::OkStatus());
120 
121   ASSERT_EQ(GRPC_HTTP_RESPONSE, parser.type);
122   ASSERT_EQ(expect_status, response.status);
123   if (expect_body != nullptr) {
124     ASSERT_EQ(strlen(expect_body), response.body_length);
125     ASSERT_EQ(0, memcmp(expect_body, response.body, response.body_length));
126   } else {
127     ASSERT_EQ(response.body_length, 0);
128   }
129 
130   va_start(args, expect_body);
131   i = 0;
132   for (;;) {
133     char* expect_key;
134     char* expect_value;
135     expect_key = va_arg(args, char*);
136     if (!expect_key) break;
137     ASSERT_LT(i, response.hdr_count);
138     expect_value = va_arg(args, char*);
139     ASSERT_TRUE(expect_value);
140     ASSERT_STREQ(expect_key, response.hdrs[i].key);
141     ASSERT_STREQ(expect_value, response.hdrs[i].value);
142     i++;
143   }
144   va_end(args);
145   ASSERT_EQ(i, response.hdr_count);
146 
147   grpc_http_response_destroy(&response);
148   grpc_http_parser_destroy(&parser);
149   gpr_free(slices);
150 }
151 
test_fails(grpc_slice_split_mode split_mode,const char * response_text)152 static void test_fails(grpc_slice_split_mode split_mode,
153                        const char* response_text) {
154   grpc_http_parser parser;
155   grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
156   size_t num_slices;
157   size_t i;
158   grpc_slice* slices;
159   grpc_error_handle error;
160   grpc_http_response response;
161   response = {};
162 
163   grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
164   grpc_slice_unref(input_slice);
165 
166   grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
167 
168   for (i = 0; i < num_slices; i++) {
169     if (absl::OkStatus() == error) {
170       error = grpc_http_parser_parse(&parser, slices[i], nullptr);
171     }
172     grpc_slice_unref(slices[i]);
173   }
174   if (absl::OkStatus() == error) {
175     error = grpc_http_parser_eof(&parser);
176   }
177   ASSERT_FALSE(error.ok());
178 
179   grpc_http_response_destroy(&response);
180   grpc_http_parser_destroy(&parser);
181   gpr_free(slices);
182 }
183 
test_request_fails(grpc_slice_split_mode split_mode,const char * request_text)184 static void test_request_fails(grpc_slice_split_mode split_mode,
185                                const char* request_text) {
186   grpc_http_parser parser;
187   grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
188   size_t num_slices;
189   size_t i;
190   grpc_slice* slices;
191   grpc_error_handle error;
192   grpc_http_request request;
193   memset(&request, 0, sizeof(request));
194 
195   grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
196   grpc_slice_unref(input_slice);
197 
198   grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
199 
200   for (i = 0; i < num_slices; i++) {
201     if (error.ok()) {
202       error = grpc_http_parser_parse(&parser, slices[i], nullptr);
203     }
204     grpc_slice_unref(slices[i]);
205   }
206   if (error.ok()) {
207     error = grpc_http_parser_eof(&parser);
208   }
209   ASSERT_FALSE(error.ok());
210 
211   grpc_http_request_destroy(&request);
212   grpc_http_parser_destroy(&parser);
213   gpr_free(slices);
214 }
215 
TEST(ParserTest,MainTest)216 TEST(ParserTest, MainTest) {
217   size_t i;
218   const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY,
219                                                GRPC_SLICE_SPLIT_ONE_BYTE};
220   for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) {
221     test_succeeds(split_modes[i],
222                   "HTTP/1.0 200 OK\r\n"
223                   "xyz: abc\r\n"
224                   "\r\n"
225                   "hello world!",
226                   200, "hello world!", "xyz", "abc", NULL);
227     test_succeeds(split_modes[i],
228                   "HTTP/1.0 404 Not Found\r\n"
229                   "\r\n",
230                   404, nullptr, NULL);
231     test_succeeds(split_modes[i],
232                   "HTTP/1.1 200 OK\r\n"
233                   "xyz: abc\r\n"
234                   "\r\n"
235                   "hello world!",
236                   200, "hello world!", "xyz", "abc", NULL);
237     test_succeeds(split_modes[i],
238                   "HTTP/1.1 200 OK\n"
239                   "\n"
240                   "abc",
241                   200, "abc", NULL);
242     test_succeeds(split_modes[i],
243                   "HTTP/1.1 200 OK\r\n"
244                   "Transfer-Encoding: chunked\r\n"
245                   "\r\n"
246                   "4\r\n"
247                   "This\r\n"
248                   "16;param1;param2\r\n"
249                   " is a chunked encoding\r\n"
250                   "1D\r\n"
251                   " example.\r\nNo params handled.\r\n"
252                   "0\r\n"
253                   "\r\n",
254                   200,
255                   "This is a chunked encoding example.\r\nNo params handled.",
256                   "Transfer-Encoding", "chunked", NULL);
257     test_succeeds(split_modes[i],
258                   "HTTP/1.1 200 OK\r\n"
259                   "Transfer-Encoding: chunked\r\n"
260                   "\r\n"
261                   "e\r\n"
262                   "HTTP Trailers \r\n"
263                   "13\r\n"
264                   "are also supported.\r\n"
265                   "0\r\n"
266                   "abc: xyz\r\n"
267                   "\r\n",
268                   200, "HTTP Trailers are also supported.", "Transfer-Encoding",
269                   "chunked", "abc", "xyz", NULL);
270     test_request_succeeds(split_modes[i],
271                           "GET / HTTP/1.0\r\n"
272                           "\r\n",
273                           "GET", GRPC_HTTP_HTTP10, "/", nullptr, NULL);
274     test_request_succeeds(split_modes[i],
275                           "GET / HTTP/1.0\r\n"
276                           "\r\n"
277                           "xyz",
278                           "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
279     test_request_succeeds(split_modes[i],
280                           "GET / HTTP/1.1\r\n"
281                           "\r\n"
282                           "xyz",
283                           "GET", GRPC_HTTP_HTTP11, "/", "xyz", NULL);
284     test_request_succeeds(split_modes[i],
285                           "GET / HTTP/2.0\r\n"
286                           "\r\n"
287                           "xyz",
288                           "GET", GRPC_HTTP_HTTP20, "/", "xyz", NULL);
289     test_request_succeeds(split_modes[i],
290                           "GET / HTTP/1.0\r\n"
291                           "xyz: abc\r\n"
292                           "\r\n"
293                           "xyz",
294                           "GET", GRPC_HTTP_HTTP10, "/", "xyz", "xyz", "abc",
295                           NULL);
296     test_request_succeeds(split_modes[i],
297                           "GET / HTTP/1.0\n"
298                           "\n"
299                           "xyz",
300                           "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
301     test_fails(split_modes[i], "HTTP/1.0\r\n");
302     test_fails(split_modes[i], "HTTP/1.2\r\n");
303     test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n");
304     test_fails(split_modes[i], "HTTP/1.0 200 OK\n");
305     test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n");
306     test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n");
307     test_fails(split_modes[i],
308                "HTTP/1.0 200 OK\r\n"
309                "xyz: abc\r\n"
310                "  def\r\n"
311                "\r\n"
312                "hello world!");
313     test_request_fails(split_modes[i], "GET\r\n");
314     test_request_fails(split_modes[i], "GET /\r\n");
315     test_request_fails(split_modes[i], "GET / HTTP/0.0\r\n");
316     test_request_fails(split_modes[i], "GET / ____/1.0\r\n");
317     test_request_fails(split_modes[i], "GET / HTTP/1.2\r\n");
318     test_request_fails(split_modes[i], "GET / HTTP/1.0\n");
319 
320     char* tmp1 =
321         static_cast<char*>(gpr_malloc(2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH));
322     memset(tmp1, 'a', 2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1);
323     tmp1[2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1] = 0;
324     std::string tmp2 =
325         absl::StrFormat("HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1);
326     gpr_free(tmp1);
327     test_fails(split_modes[i], tmp2.c_str());
328   }
329 }
330 
main(int argc,char ** argv)331 int main(int argc, char** argv) {
332   grpc::testing::TestEnvironment env(&argc, argv);
333   ::testing::InitGoogleTest(&argc, argv);
334   grpc::testing::TestGrpcScope grpc_scope;
335   return RUN_ALL_TESTS();
336 }
337