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 <grpc/grpc.h>
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpc/support/string_util.h>
28
29 #include "src/core/lib/gpr/useful.h"
30 #include "test/core/util/slice_splitter.h"
31 #include "test/core/util/test_config.h"
32
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,...)33 static void test_request_succeeds(grpc_slice_split_mode split_mode,
34 const char* request_text,
35 const char* expect_method,
36 grpc_http_version expect_version,
37 const char* expect_path,
38 const char* expect_body, ...) {
39 grpc_http_parser parser;
40 grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
41 size_t num_slices;
42 size_t i;
43 grpc_slice* slices;
44 va_list args;
45 grpc_http_request request;
46 memset(&request, 0, sizeof(request));
47
48 grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
49 grpc_slice_unref(input_slice);
50
51 grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
52
53 for (i = 0; i < num_slices; i++) {
54 GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], nullptr) ==
55 GRPC_ERROR_NONE);
56 grpc_slice_unref(slices[i]);
57 }
58 GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE);
59
60 GPR_ASSERT(GRPC_HTTP_REQUEST == parser.type);
61 GPR_ASSERT(0 == strcmp(expect_method, request.method));
62 GPR_ASSERT(0 == strcmp(expect_path, request.path));
63 GPR_ASSERT(expect_version == request.version);
64
65 if (expect_body != nullptr) {
66 GPR_ASSERT(strlen(expect_body) == request.body_length);
67 GPR_ASSERT(0 == memcmp(expect_body, request.body, request.body_length));
68 } else {
69 GPR_ASSERT(request.body_length == 0);
70 }
71
72 va_start(args, expect_body);
73 i = 0;
74 for (;;) {
75 char* expect_key;
76 char* expect_value;
77 expect_key = va_arg(args, char*);
78 if (!expect_key) break;
79 GPR_ASSERT(i < request.hdr_count);
80 expect_value = va_arg(args, char*);
81 GPR_ASSERT(expect_value);
82 GPR_ASSERT(0 == strcmp(expect_key, request.hdrs[i].key));
83 GPR_ASSERT(0 == strcmp(expect_value, request.hdrs[i].value));
84 i++;
85 }
86 va_end(args);
87 GPR_ASSERT(i == request.hdr_count);
88
89 grpc_http_request_destroy(&request);
90 grpc_http_parser_destroy(&parser);
91 gpr_free(slices);
92 }
93
test_succeeds(grpc_slice_split_mode split_mode,const char * response_text,int expect_status,const char * expect_body,...)94 static void test_succeeds(grpc_slice_split_mode split_mode,
95 const char* response_text, int expect_status,
96 const char* expect_body, ...) {
97 grpc_http_parser parser;
98 grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
99 size_t num_slices;
100 size_t i;
101 grpc_slice* slices;
102 va_list args;
103 grpc_http_response response;
104 memset(&response, 0, sizeof(response));
105
106 grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
107 grpc_slice_unref(input_slice);
108
109 grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
110
111 for (i = 0; i < num_slices; i++) {
112 GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], nullptr) ==
113 GRPC_ERROR_NONE);
114 grpc_slice_unref(slices[i]);
115 }
116 GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE);
117
118 GPR_ASSERT(GRPC_HTTP_RESPONSE == parser.type);
119 GPR_ASSERT(expect_status == response.status);
120 if (expect_body != nullptr) {
121 GPR_ASSERT(strlen(expect_body) == response.body_length);
122 GPR_ASSERT(0 == memcmp(expect_body, response.body, response.body_length));
123 } else {
124 GPR_ASSERT(response.body_length == 0);
125 }
126
127 va_start(args, expect_body);
128 i = 0;
129 for (;;) {
130 char* expect_key;
131 char* expect_value;
132 expect_key = va_arg(args, char*);
133 if (!expect_key) break;
134 GPR_ASSERT(i < response.hdr_count);
135 expect_value = va_arg(args, char*);
136 GPR_ASSERT(expect_value);
137 GPR_ASSERT(0 == strcmp(expect_key, response.hdrs[i].key));
138 GPR_ASSERT(0 == strcmp(expect_value, response.hdrs[i].value));
139 i++;
140 }
141 va_end(args);
142 GPR_ASSERT(i == response.hdr_count);
143
144 grpc_http_response_destroy(&response);
145 grpc_http_parser_destroy(&parser);
146 gpr_free(slices);
147 }
148
test_fails(grpc_slice_split_mode split_mode,const char * response_text)149 static void test_fails(grpc_slice_split_mode split_mode,
150 const char* response_text) {
151 grpc_http_parser parser;
152 grpc_slice input_slice = grpc_slice_from_copied_string(response_text);
153 size_t num_slices;
154 size_t i;
155 grpc_slice* slices;
156 grpc_error* error = GRPC_ERROR_NONE;
157 grpc_http_response response;
158 memset(&response, 0, sizeof(response));
159
160 grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
161 grpc_slice_unref(input_slice);
162
163 grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
164
165 for (i = 0; i < num_slices; i++) {
166 if (GRPC_ERROR_NONE == error) {
167 error = grpc_http_parser_parse(&parser, slices[i], nullptr);
168 }
169 grpc_slice_unref(slices[i]);
170 }
171 if (GRPC_ERROR_NONE == error) {
172 error = grpc_http_parser_eof(&parser);
173 }
174 GPR_ASSERT(error != GRPC_ERROR_NONE);
175 GRPC_ERROR_UNREF(error);
176
177 grpc_http_response_destroy(&response);
178 grpc_http_parser_destroy(&parser);
179 gpr_free(slices);
180 }
181
test_request_fails(grpc_slice_split_mode split_mode,const char * request_text)182 static void test_request_fails(grpc_slice_split_mode split_mode,
183 const char* request_text) {
184 grpc_http_parser parser;
185 grpc_slice input_slice = grpc_slice_from_copied_string(request_text);
186 size_t num_slices;
187 size_t i;
188 grpc_slice* slices;
189 grpc_error* error = GRPC_ERROR_NONE;
190 grpc_http_request request;
191 memset(&request, 0, sizeof(request));
192
193 grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
194 grpc_slice_unref(input_slice);
195
196 grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
197
198 for (i = 0; i < num_slices; i++) {
199 if (error == GRPC_ERROR_NONE) {
200 error = grpc_http_parser_parse(&parser, slices[i], nullptr);
201 }
202 grpc_slice_unref(slices[i]);
203 }
204 if (error == GRPC_ERROR_NONE) {
205 error = grpc_http_parser_eof(&parser);
206 }
207 GPR_ASSERT(error != GRPC_ERROR_NONE);
208 GRPC_ERROR_UNREF(error);
209
210 grpc_http_request_destroy(&request);
211 grpc_http_parser_destroy(&parser);
212 gpr_free(slices);
213 }
214
main(int argc,char ** argv)215 int main(int argc, char** argv) {
216 size_t i;
217 const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY,
218 GRPC_SLICE_SPLIT_ONE_BYTE};
219 char *tmp1, *tmp2;
220
221 grpc_test_init(argc, argv);
222 grpc_init();
223
224 for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) {
225 test_succeeds(split_modes[i],
226 "HTTP/1.0 200 OK\r\n"
227 "xyz: abc\r\n"
228 "\r\n"
229 "hello world!",
230 200, "hello world!", "xyz", "abc", NULL);
231 test_succeeds(split_modes[i],
232 "HTTP/1.0 404 Not Found\r\n"
233 "\r\n",
234 404, nullptr, NULL);
235 test_succeeds(split_modes[i],
236 "HTTP/1.1 200 OK\r\n"
237 "xyz: abc\r\n"
238 "\r\n"
239 "hello world!",
240 200, "hello world!", "xyz", "abc", NULL);
241 test_succeeds(split_modes[i],
242 "HTTP/1.1 200 OK\n"
243 "\n"
244 "abc",
245 200, "abc", NULL);
246 test_request_succeeds(split_modes[i],
247 "GET / HTTP/1.0\r\n"
248 "\r\n",
249 "GET", GRPC_HTTP_HTTP10, "/", nullptr, NULL);
250 test_request_succeeds(split_modes[i],
251 "GET / HTTP/1.0\r\n"
252 "\r\n"
253 "xyz",
254 "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
255 test_request_succeeds(split_modes[i],
256 "GET / HTTP/1.1\r\n"
257 "\r\n"
258 "xyz",
259 "GET", GRPC_HTTP_HTTP11, "/", "xyz", NULL);
260 test_request_succeeds(split_modes[i],
261 "GET / HTTP/2.0\r\n"
262 "\r\n"
263 "xyz",
264 "GET", GRPC_HTTP_HTTP20, "/", "xyz", NULL);
265 test_request_succeeds(split_modes[i],
266 "GET / HTTP/1.0\r\n"
267 "xyz: abc\r\n"
268 "\r\n"
269 "xyz",
270 "GET", GRPC_HTTP_HTTP10, "/", "xyz", "xyz", "abc",
271 NULL);
272 test_request_succeeds(split_modes[i],
273 "GET / HTTP/1.0\n"
274 "\n"
275 "xyz",
276 "GET", GRPC_HTTP_HTTP10, "/", "xyz", NULL);
277 test_fails(split_modes[i], "HTTP/1.0\r\n");
278 test_fails(split_modes[i], "HTTP/1.2\r\n");
279 test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n");
280 test_fails(split_modes[i], "HTTP/1.0 200 OK\n");
281 test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n");
282 test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n");
283 test_fails(split_modes[i],
284 "HTTP/1.0 200 OK\r\n"
285 "xyz: abc\r\n"
286 " def\r\n"
287 "\r\n"
288 "hello world!");
289 test_request_fails(split_modes[i], "GET\r\n");
290 test_request_fails(split_modes[i], "GET /\r\n");
291 test_request_fails(split_modes[i], "GET / HTTP/0.0\r\n");
292 test_request_fails(split_modes[i], "GET / ____/1.0\r\n");
293 test_request_fails(split_modes[i], "GET / HTTP/1.2\r\n");
294 test_request_fails(split_modes[i], "GET / HTTP/1.0\n");
295
296 tmp1 =
297 static_cast<char*>(gpr_malloc(2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH));
298 memset(tmp1, 'a', 2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1);
299 tmp1[2 * GRPC_HTTP_PARSER_MAX_HEADER_LENGTH - 1] = 0;
300 gpr_asprintf(&tmp2, "HTTP/1.0 200 OK\r\nxyz: %s\r\n\r\n", tmp1);
301 test_fails(split_modes[i], tmp2);
302 gpr_free(tmp1);
303 gpr_free(tmp2);
304 }
305
306 grpc_shutdown();
307 return 0;
308 }
309