Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include "src/core/httpcli/parser.h"
35 :
36 : #include <stdarg.h>
37 : #include <string.h>
38 :
39 : #include <grpc/support/alloc.h>
40 : #include <grpc/support/log.h>
41 : #include <grpc/support/useful.h>
42 : #include "test/core/util/slice_splitter.h"
43 : #include "test/core/util/test_config.h"
44 :
45 6 : static void test_succeeds(grpc_slice_split_mode split_mode, char *response,
46 : int expect_status, char *expect_body, ...) {
47 : grpc_httpcli_parser parser;
48 6 : gpr_slice input_slice = gpr_slice_from_copied_string(response);
49 : size_t num_slices;
50 : size_t i;
51 : gpr_slice *slices;
52 : va_list args;
53 :
54 6 : grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
55 6 : gpr_slice_unref(input_slice);
56 :
57 6 : grpc_httpcli_parser_init(&parser);
58 :
59 117 : for (i = 0; i < num_slices; i++) {
60 111 : GPR_ASSERT(grpc_httpcli_parser_parse(&parser, slices[i]));
61 111 : gpr_slice_unref(slices[i]);
62 : }
63 6 : GPR_ASSERT(grpc_httpcli_parser_eof(&parser));
64 :
65 6 : GPR_ASSERT(expect_status == parser.r.status);
66 6 : if (expect_body != NULL) {
67 4 : GPR_ASSERT(strlen(expect_body) == parser.r.body_length);
68 4 : GPR_ASSERT(0 == memcmp(expect_body, parser.r.body, parser.r.body_length));
69 : } else {
70 2 : GPR_ASSERT(parser.r.body_length == 0);
71 : }
72 :
73 6 : va_start(args, expect_body);
74 6 : i = 0;
75 : for (;;) {
76 : char *expect_key;
77 : char *expect_value;
78 10 : expect_key = va_arg(args, char *);
79 10 : if (!expect_key) break;
80 4 : GPR_ASSERT(i < parser.r.hdr_count);
81 4 : expect_value = va_arg(args, char *);
82 4 : GPR_ASSERT(expect_value);
83 4 : GPR_ASSERT(0 == strcmp(expect_key, parser.r.hdrs[i].key));
84 4 : GPR_ASSERT(0 == strcmp(expect_value, parser.r.hdrs[i].value));
85 4 : i++;
86 4 : }
87 6 : va_end(args);
88 6 : GPR_ASSERT(i == parser.r.hdr_count);
89 :
90 6 : grpc_httpcli_parser_destroy(&parser);
91 6 : gpr_free(slices);
92 6 : }
93 :
94 12 : static void test_fails(grpc_slice_split_mode split_mode, char *response) {
95 : grpc_httpcli_parser parser;
96 12 : gpr_slice input_slice = gpr_slice_from_copied_string(response);
97 : size_t num_slices;
98 : size_t i;
99 : gpr_slice *slices;
100 12 : int done = 0;
101 :
102 12 : grpc_split_slices(split_mode, &input_slice, 1, &slices, &num_slices);
103 12 : gpr_slice_unref(input_slice);
104 :
105 12 : grpc_httpcli_parser_init(&parser);
106 :
107 113 : for (i = 0; i < num_slices; i++) {
108 101 : if (!done && !grpc_httpcli_parser_parse(&parser, slices[i])) {
109 8 : done = 1;
110 : }
111 101 : gpr_slice_unref(slices[i]);
112 : }
113 12 : if (!done && !grpc_httpcli_parser_eof(&parser)) {
114 4 : done = 1;
115 : }
116 12 : GPR_ASSERT(done);
117 :
118 12 : grpc_httpcli_parser_destroy(&parser);
119 12 : gpr_free(slices);
120 12 : }
121 :
122 1 : int main(int argc, char **argv) {
123 : size_t i;
124 1 : const grpc_slice_split_mode split_modes[] = {GRPC_SLICE_SPLIT_IDENTITY,
125 : GRPC_SLICE_SPLIT_ONE_BYTE};
126 :
127 1 : grpc_test_init(argc, argv);
128 :
129 3 : for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) {
130 2 : test_succeeds(split_modes[i],
131 : "HTTP/1.0 200 OK\r\n"
132 : "xyz: abc\r\n"
133 : "\r\n"
134 : "hello world!",
135 : 200, "hello world!", "xyz", "abc", NULL);
136 2 : test_succeeds(split_modes[i],
137 : "HTTP/1.0 404 Not Found\r\n"
138 : "\r\n",
139 : 404, NULL, NULL);
140 2 : test_succeeds(split_modes[i],
141 : "HTTP/1.1 200 OK\r\n"
142 : "xyz: abc\r\n"
143 : "\r\n"
144 : "hello world!",
145 : 200, "hello world!", "xyz", "abc", NULL);
146 2 : test_fails(split_modes[i], "HTTP/1.0\r\n");
147 2 : test_fails(split_modes[i], "HTTP/1.2\r\n");
148 2 : test_fails(split_modes[i], "HTTP/1.0 000 XYX\r\n");
149 2 : test_fails(split_modes[i], "HTTP/1.0 200 OK\n");
150 2 : test_fails(split_modes[i], "HTTP/1.0 200 OK\r\n");
151 2 : test_fails(split_modes[i], "HTTP/1.0 200 OK\r\nFoo x\r\n");
152 : }
153 :
154 1 : return 0;
155 : }
|