test/core/http/parser_test.cc
Go to the documentation of this file.
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 
20 
21 #include <stdarg.h>
22 #include <string.h>
23 
24 #include <string>
25 
26 #include "absl/strings/str_format.h"
27 
28 #include <grpc/grpc.h>
29 #include <grpc/support/alloc.h>
30 #include <grpc/support/log.h>
31 
35 
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, ...) {
43  grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
44  size_t num_slices;
45  size_t i;
47  va_list args;
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 
55 
56  for (i = 0; i < num_slices; i++) {
60  }
62 
64  GPR_ASSERT(0 == strcmp(expect_method, request.method));
65  GPR_ASSERT(0 == strcmp(expect_path, request.path));
66  GPR_ASSERT(expect_version == request.version);
67 
68  if (expect_body != nullptr) {
69  GPR_ASSERT(strlen(expect_body) == request.body_length);
70  GPR_ASSERT(0 == memcmp(expect_body, request.body, request.body_length));
71  } else {
72  GPR_ASSERT(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  GPR_ASSERT(i < request.hdr_count);
83  expect_value = va_arg(args, char*);
84  GPR_ASSERT(expect_value);
85  GPR_ASSERT(0 == strcmp(expect_key, request.hdrs[i].key));
86  GPR_ASSERT(0 == strcmp(expect_value, request.hdrs[i].value));
87  i++;
88  }
89  va_end(args);
90  GPR_ASSERT(i == request.hdr_count);
91 
95 }
96 
97 static void test_succeeds(grpc_slice_split_mode split_mode,
98  const char* response_text, int expect_status,
99  const char* expect_body, ...) {
101  grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
102  size_t num_slices;
103  size_t i;
105  va_list args;
107  response = {};
108 
109  grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
110  grpc_slice_unref(input_slice);
111 
113 
114  for (i = 0; i < num_slices; i++) {
118  }
120 
122  GPR_ASSERT(expect_status == response.status);
123  if (expect_body != nullptr) {
124  GPR_ASSERT(strlen(expect_body) == response.body_length);
125  GPR_ASSERT(0 == memcmp(expect_body, response.body, response.body_length));
126  } else {
127  GPR_ASSERT(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  GPR_ASSERT(i < response.hdr_count);
138  expect_value = va_arg(args, char*);
139  GPR_ASSERT(expect_value);
140  GPR_ASSERT(0 == strcmp(expect_key, response.hdrs[i].key));
141  GPR_ASSERT(0 == strcmp(expect_value, response.hdrs[i].value));
142  i++;
143  }
144  va_end(args);
145  GPR_ASSERT(i == response.hdr_count);
146 
149  gpr_free(slices);
150 }
151 
152 static void test_fails(grpc_slice_split_mode split_mode,
153  const char* response_text) {
155  grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
156  size_t num_slices;
157  size_t i;
161  response = {};
162 
163  grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
164  grpc_slice_unref(input_slice);
165 
167 
168  for (i = 0; i < num_slices; i++) {
169  if (GRPC_ERROR_NONE == error) {
170  error = grpc_http_parser_parse(&parser, slices[i], nullptr);
171  }
173  }
174  if (GRPC_ERROR_NONE == error) {
176  }
179 
182  gpr_free(slices);
183 }
184 
186  const char* request_text) {
188  grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
189  size_t num_slices;
190  size_t i;
194  memset(&request, 0, sizeof(request));
195 
196  grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
197  grpc_slice_unref(input_slice);
198 
200 
201  for (i = 0; i < num_slices; i++) {
202  if (GRPC_ERROR_IS_NONE(error)) {
203  error = grpc_http_parser_parse(&parser, slices[i], nullptr);
204  }
206  }
207  if (GRPC_ERROR_IS_NONE(error)) {
209  }
212 
215  gpr_free(slices);
216 }
217 
218 int main(int argc, char** argv) {
219  size_t i;
220  const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY,
222 
223  grpc::testing::TestEnvironment env(&argc, argv);
224  grpc_init();
225 
226  for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) {
227  test_succeeds(split_modes[i],
228  "HTTP/1.0 200 OK\r\n"
229  "xyz: abc\r\n"
230  "\r\n"
231  "hello world!",
232  200, "hello world!", "xyz", "abc", NULL);
233  test_succeeds(split_modes[i],
234  "HTTP/1.0 404 Not Found\r\n"
235  "\r\n",
236  404, nullptr, NULL);
237  test_succeeds(split_modes[i],
238  "HTTP/1.1 200 OK\r\n"
239  "xyz: abc\r\n"
240  "\r\n"
241  "hello world!",
242  200, "hello world!", "xyz", "abc", NULL);
243  test_succeeds(split_modes[i],
244  "HTTP/1.1 200 OK\n"
245  "\n"
246  "abc",
247  200, "abc", NULL);
248  test_succeeds(split_modes[i],
249  "HTTP/1.1 200 OK\r\n"
250  "Transfer-Encoding: chunked\r\n"
251  "\r\n"
252  "4\r\n"
253  "This\r\n"
254  "16;param1;param2\r\n"
255  " is a chunked encoding\r\n"
256  "1D\r\n"
257  " example.\r\nNo params handled.\r\n"
258  "0\r\n"
259  "\r\n",
260  200,
261  "This is a chunked encoding example.\r\nNo params handled.",
262  "Transfer-Encoding", "chunked", NULL);
263  test_succeeds(split_modes[i],
264  "HTTP/1.1 200 OK\r\n"
265  "Transfer-Encoding: chunked\r\n"
266  "\r\n"
267  "e\r\n"
268  "HTTP Trailers \r\n"
269  "13\r\n"
270  "are also supported.\r\n"
271  "0\r\n"
272  "abc: xyz\r\n"
273  "\r\n",
274  200, "HTTP Trailers are also supported.", "Transfer-Encoding",
275  "chunked", "abc", "xyz", NULL);
276  test_request_succeeds(split_modes[i],
277  "GET / HTTP/1.0\r\n"
278  "\r\n",
279  "GET", GRPC_HTTP_HTTP10, "/", nullptr, NULL);
280  test_request_succeeds(split_modes[i],
281  "GET / HTTP/1.0\r\n"
282  "\r\n"
283  "xyz",
284  "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
285  test_request_succeeds(split_modes[i],
286  "GET / HTTP/1.1\r\n"
287  "\r\n"
288  "xyz",
289  "GET", GRPC_HTTP_HTTP11, "/", "xyz", NULL);
290  test_request_succeeds(split_modes[i],
291  "GET / HTTP/2.0\r\n"
292  "\r\n"
293  "xyz",
294  "GET", GRPC_HTTP_HTTP20, "/", "xyz", NULL);
295  test_request_succeeds(split_modes[i],
296  "GET / HTTP/1.0\r\n"
297  "xyz: abc\r\n"
298  "\r\n"
299  "xyz",
300  "GET", GRPC_HTTP_HTTP10, "/", "xyz", "xyz", "abc",
301  NULL);
302  test_request_succeeds(split_modes[i],
303  "GET / HTTP/1.0\n"
304  "\n"
305  "xyz",
306  "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
307  test_fails(split_modes[i], "HTTP/1.0\r\n");
308  test_fails(split_modes[i], "HTTP/1.2\r\n");
309  test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n");
310  test_fails(split_modes[i], "HTTP/1.0 200 OK\n");
311  test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n");
312  test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n");
313  test_fails(split_modes[i],
314  "HTTP/1.0 200 OK\r\n"
315  "xyz: abc\r\n"
316  " def\r\n"
317  "\r\n"
318  "hello world!");
319  test_request_fails(split_modes[i], "GET\r\n");
320  test_request_fails(split_modes[i], "GET /\r\n");
321  test_request_fails(split_modes[i], "GET / HTTP/0.0\r\n");
322  test_request_fails(split_modes[i], "GET / ____/1.0\r\n");
323  test_request_fails(split_modes[i], "GET / HTTP/1.2\r\n");
324  test_request_fails(split_modes[i], "GET / HTTP/1.0\n");
325 
326  char* tmp1 =
327  static_cast<char*>(gpr_malloc(2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH));
328  memset(tmp1, 'a', 2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1);
329  tmp1[2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1] = 0;
330  std::string tmp2 =
331  absl::StrFormat("HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1);
332  gpr_free(tmp1);
333  test_fails(split_modes[i], tmp2.c_str());
334  }
335 
336  grpc_shutdown();
337  return 0;
338 }
grpc_slice_unref
GPRAPI void grpc_slice_unref(grpc_slice s)
Definition: slice_api.cc:32
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
GRPC_SLICE_SPLIT_IDENTITY
@ GRPC_SLICE_SPLIT_IDENTITY
Definition: slice_splitter.h:32
generate.env
env
Definition: generate.py:37
memset
return memset(p, 0, total)
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_http_parser_eof
grpc_error_handle grpc_http_parser_eof(grpc_http_parser *parser)
Definition: src/core/lib/http/parser.cc:457
grpc_slice_from_copied_string
GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source)
Definition: slice/slice.cc:177
grpc_http_version
grpc_http_version
Definition: src/core/lib/http/parser.h:57
string.h
benchmark.request
request
Definition: benchmark.py:77
grpc_slice_split_mode
grpc_slice_split_mode
Definition: slice_splitter.h:28
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
useful.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
GRPC_HTTP_HTTP20
@ GRPC_HTTP_HTTP20
Definition: src/core/lib/http/parser.h:60
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
test_request_succeeds
static void 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,...)
Definition: test/core/http/parser_test.cc:36
grpc_http_response
Definition: src/core/lib/http/parser.h:85
slice_splitter.h
grpc_http_request_destroy
void grpc_http_request_destroy(grpc_http_request *request)
Definition: src/core/lib/http/parser.cc:422
asyncio_get_stats.parser
parser
Definition: asyncio_get_stats.py:34
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
GRPC_HTTP_HTTP10
@ GRPC_HTTP_HTTP10
Definition: src/core/lib/http/parser.h:58
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc.h
GRPC_HTTP_REQUEST
@ GRPC_HTTP_REQUEST
Definition: src/core/lib/http/parser.h:65
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
grpc_http_response_destroy
void grpc_http_response_destroy(grpc_http_response *response)
Definition: src/core/lib/http/parser.cc:434
grpc_http_parser_destroy
void grpc_http_parser_destroy(grpc_http_parser *)
Definition: src/core/lib/http/parser.cc:420
test_succeeds
static void test_succeeds(grpc_slice_split_mode split_mode, const char *response_text, int expect_status, const char *expect_body,...)
Definition: test/core/http/parser_test.cc:97
test_config.h
check_naked_includes.expect_path
expect_path
Definition: check_naked_includes.py:57
GPR_ARRAY_SIZE
#define GPR_ARRAY_SIZE(array)
Definition: useful.h:129
parser.h
grpc_split_slices
void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice *src_slices, size_t src_slice_count, grpc_slice **dst_slices, size_t *dst_slice_count)
Definition: slice_splitter.cc:41
alloc.h
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc_http_parser_parse
grpc_error_handle grpc_http_parser_parse(grpc_http_parser *parser, const grpc_slice &slice, size_t *start_of_body)
Definition: src/core/lib/http/parser.cc:444
slices
SliceBuffer * slices
Definition: retry_filter.cc:631
grpc_http_parser_init
void grpc_http_parser_init(grpc_http_parser *parser, grpc_http_type type, void *request_or_response)
Definition: src/core/lib/http/parser.cc:411
GRPC_HTTP_PARSER_MAX_HEADER_LENGTH
#define GRPC_HTTP_PARSER_MAX_HEADER_LENGTH
Definition: src/core/lib/http/parser.h:33
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
main
int main(int argc, char **argv)
Definition: test/core/http/parser_test.cc:218
test_request_fails
static void test_request_fails(grpc_slice_split_mode split_mode, const char *request_text)
Definition: test/core/http/parser_test.cc:185
GRPC_HTTP_RESPONSE
@ GRPC_HTTP_RESPONSE
Definition: src/core/lib/http/parser.h:64
GRPC_HTTP_HTTP11
@ GRPC_HTTP_HTTP11
Definition: src/core/lib/http/parser.h:59
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc_error
Definition: error_internal.h:42
test_fails
static void test_fails(grpc_slice_split_mode split_mode, const char *response_text)
Definition: test/core/http/parser_test.cc:152
grpc_http_parser
Definition: src/core/lib/http/parser.h:99
GRPC_SLICE_SPLIT_ONE_BYTE
@ GRPC_SLICE_SPLIT_ONE_BYTE
Definition: slice_splitter.h:34
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
grpc_http_request
Definition: src/core/lib/http/parser.h:69


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:40