xref: /aosp_15_r20/external/grpc-grpc/test/core/bad_client/tests/simple_request.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <grpc/grpc.h>
16 #include <grpc/slice.h>
17 #include <grpc/support/log.h>
18 
19 #include "src/core/lib/surface/server.h"
20 #include "test/core/bad_client/bad_client.h"
21 #include "test/core/end2end/cq_verifier.h"
22 #include "test/core/util/test_config.h"
23 
24 #define PFX_STR                                                            \
25   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"                                       \
26   "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */              \
27   "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from        \
28                                             simple_request.headers in this \
29                                             directory */                   \
30   "\x10\x05:path\x08/foo/bar"                                              \
31   "\x10\x07:scheme\x04http"                                                \
32   "\x10\x07:method\x04POST"                                                \
33   "\x10\x0a:authority\x09localhost"                                        \
34   "\x10\x0c"                                                               \
35   "content-type\x10"                                                       \
36   "application/grpc"                                                       \
37   "\x10\x14grpc-accept-encoding\x15"                                       \
38   "deflate,identity,gzip"                                                  \
39   "\x10\x02te\x08trailers"                                                 \
40   "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
41 
42 #define PFX_STR_UNUSUAL                                                    \
43   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"                                       \
44   "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */              \
45   "\x00\x00\xf4\x01\x04\x00\x00\x00\x01" /* headers: generated from        \
46                                             simple_request_unusual.headers \
47                                             in this directory */           \
48   "\x10\x05:path\x08/foo/bar"                                              \
49   "\x10\x07:scheme\x04http"                                                \
50   "\x10\x07:method\x04POST"                                                \
51   "\x10\x04host\x09localhost"                                              \
52   "\x10\x0c"                                                               \
53   "content-type\x1e"                                                       \
54   "application/grpc+this-is-valid"                                         \
55   "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"                  \
56   "\x10\x02te\x08trailers"                                                 \
57   "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"                 \
58   "\x10\x0cgrpc-timeout\x03"                                               \
59   "10S"                                                                    \
60   "\x10\x0cgrpc-timeout\x02"                                               \
61   "5S"
62 
63 #define PFX_STR_UNUSUAL2                                                    \
64   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"                                        \
65   "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */               \
66   "\x00\x00\xf4\x01\x04\x00\x00\x00\x01" /* headers: generated from         \
67                                             simple_request_unusual2.headers \
68                                             in this directory */            \
69   "\x10\x05:path\x08/foo/bar"                                               \
70   "\x10\x07:scheme\x04http"                                                 \
71   "\x10\x07:method\x04POST"                                                 \
72   "\x10\x04host\x09localhost"                                               \
73   "\x10\x0c"                                                                \
74   "content-type\x1e"                                                        \
75   "application/grpc;this-is-valid"                                          \
76   "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"                   \
77   "\x10\x02te\x08trailers"                                                  \
78   "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"                  \
79   "\x10\x0cgrpc-timeout\x03"                                                \
80   "10S"                                                                     \
81   "\x10\x0cgrpc-timeout\x02"                                                \
82   "5S"
83 
84 #define PFX_STR_TEXT_HTML_CONTENT_TYPE_HEADER                                             \
85   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"                                                      \
86   "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */                             \
87   "\x00\x00\xdf\x01\x04\x00\x00\x00\x01" /* headers: generated from                       \
88                                             simple_request_text_html_content_type.headers \
89                                             in this directory */                          \
90   "\x10\x05:path\x08/foo/bar"                                                             \
91   "\x10\x07:scheme\x04http"                                                               \
92   "\x10\x07:method\x04POST"                                                               \
93   "\x10\x04host\x09localhost"                                                             \
94   "\x10\x0c"                                                                              \
95   "content-type\x09text/html"                                                             \
96   "\x10\x14grpc-accept-encoding\x15"                                                      \
97   "deflate,identity,gzip"                                                                 \
98   "\x10\x02te\x08trailers"                                                                \
99   "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"                                \
100   "\x10\x0cgrpc-timeout\x03"                                                              \
101   "10S"                                                                                   \
102   "\x10\x0cgrpc-timeout\x02"                                                              \
103   "5S"
104 
verifier(grpc_server * server,grpc_completion_queue * cq,void *)105 static void verifier(grpc_server* server, grpc_completion_queue* cq,
106                      void* /*registered_method*/) {
107   grpc_call_error error;
108   grpc_call* s;
109   grpc_call_details call_details;
110   grpc_core::CqVerifier cqv(cq);
111   grpc_metadata_array request_metadata_recv;
112 
113   grpc_call_details_init(&call_details);
114   grpc_metadata_array_init(&request_metadata_recv);
115 
116   error = grpc_server_request_call(server, &s, &call_details,
117                                    &request_metadata_recv, cq, cq,
118                                    grpc_core::CqVerifier::tag(101));
119   GPR_ASSERT(GRPC_CALL_OK == error);
120   cqv.Expect(grpc_core::CqVerifier::tag(101), true);
121   cqv.Verify();
122 
123   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
124   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
125 
126   grpc_metadata_array_destroy(&request_metadata_recv);
127   grpc_call_details_destroy(&call_details);
128   grpc_call_unref(s);
129 }
130 
VerifyRpcDoesNotGetCanceled(grpc_server * server,grpc_completion_queue * cq,void *)131 static void VerifyRpcDoesNotGetCanceled(grpc_server* server,
132                                         grpc_completion_queue* cq,
133                                         void* /*registered_method*/) {
134   grpc_call_error error;
135   grpc_call* s;
136   grpc_call_details call_details;
137   grpc_core::CqVerifier cqv(cq);
138   grpc_metadata_array request_metadata_recv;
139   int was_cancelled = 2;
140 
141   grpc_call_details_init(&call_details);
142   grpc_metadata_array_init(&request_metadata_recv);
143 
144   error = grpc_server_request_call(server, &s, &call_details,
145                                    &request_metadata_recv, cq, cq,
146                                    grpc_core::CqVerifier::tag(101));
147   GPR_ASSERT(GRPC_CALL_OK == error);
148   cqv.Expect(grpc_core::CqVerifier::tag(101), true);
149   cqv.Verify();
150 
151   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost"));
152   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar"));
153 
154   grpc_op* op;
155   grpc_op ops[6];
156   // Send the initial metadata and the status from the server.
157   memset(ops, 0, sizeof(ops));
158   op = ops;
159   op->op = GRPC_OP_SEND_INITIAL_METADATA;
160   op->data.send_initial_metadata.count = 0;
161   op->flags = 0;
162   op->reserved = nullptr;
163   op++;
164   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
165   op->data.recv_close_on_server.cancelled = &was_cancelled;
166   op->flags = 0;
167   op->reserved = nullptr;
168   op++;
169   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
170   op->data.send_status_from_server.trailing_metadata_count = 0;
171   op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
172   grpc_slice status_details = grpc_slice_from_static_string("xyz");
173   op->data.send_status_from_server.status_details = &status_details;
174   op->flags = 0;
175   op->reserved = nullptr;
176   op++;
177   error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
178                                 grpc_core::CqVerifier::tag(103), nullptr);
179   GPR_ASSERT(GRPC_CALL_OK == error);
180 
181   cqv.Expect(grpc_core::CqVerifier::tag(103), true);
182   cqv.Verify();
183 
184   // If the call had an error, `was_cancelled` would be 1.
185   // GPR_ASSERT(was_cancelled == 1);
186 
187   grpc_metadata_array_destroy(&request_metadata_recv);
188   grpc_call_details_destroy(&call_details);
189   grpc_call_unref(s);
190 }
191 
failure_verifier(grpc_server * server,grpc_completion_queue * cq,void *)192 static void failure_verifier(grpc_server* server, grpc_completion_queue* cq,
193                              void* /*registered_method*/) {
194   while (grpc_core::Server::FromC(server)->HasOpenConnections()) {
195     GPR_ASSERT(grpc_completion_queue_next(
196                    cq, grpc_timeout_milliseconds_to_deadline(20), nullptr)
197                    .type == GRPC_QUEUE_TIMEOUT);
198   }
199 }
200 
main(int argc,char ** argv)201 int main(int argc, char** argv) {
202   grpc::testing::TestEnvironment env(&argc, argv);
203   grpc_init();
204 
205   // basic request: check that things are working
206   GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, PFX_STR, 0);
207   GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, PFX_STR_UNUSUAL, 0);
208   GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, PFX_STR_UNUSUAL2, 0);
209 
210   // A basic request with a "content-type: text/html" header. The spec is
211   // not clear on what the behavior should be here, so to avoid breaking anyone,
212   // we should continue to accept this header.
213   GRPC_RUN_BAD_CLIENT_TEST(VerifyRpcDoesNotGetCanceled, nullptr,
214                            PFX_STR_TEXT_HTML_CONTENT_TYPE_HEADER, 0);
215 
216   // push an illegal data frame
217   GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
218                            PFX_STR
219                            "\x00\x00\x05\x00\x00\x00\x00\x00\x01"
220                            "\x34\x00\x00\x00\x00",
221                            0);
222 
223   // push a data frame with bad flags
224   GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
225                            PFX_STR "\x00\x00\x00\x00\x02\x00\x00\x00\x01", 0);
226   // push a window update with a bad length
227   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
228                            PFX_STR "\x00\x00\x01\x08\x00\x00\x00\x00\x01", 0);
229   // push a window update with bad flags
230   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
231                            PFX_STR "\x00\x00\x00\x08\x10\x00\x00\x00\x01", 0);
232   // push a window update with bad data (0 is not legal window size increment)
233   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
234                            PFX_STR
235                            "\x00\x00\x04\x08\x00\x00\x00\x00\x01"
236                            "\x00\x00\x00\x00",
237                            0);
238   // push a short goaway
239   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
240                            PFX_STR "\x00\x00\x04\x07\x00\x00\x00\x00\x00", 0);
241   // disconnect before sending goaway
242   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
243                            PFX_STR "\x00\x01\x12\x07\x00\x00\x00\x00\x00",
244                            GRPC_BAD_CLIENT_DISCONNECT);
245   // push a rst_stream with a bad length
246   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
247                            PFX_STR "\x00\x00\x01\x03\x00\x00\x00\x00\x01", 0);
248   // push a rst_stream with bad flags
249   GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr,
250                            PFX_STR "\x00\x00\x00\x03\x10\x00\x00\x00\x01", 0);
251 
252   grpc_shutdown();
253   return 0;
254 }
255