1 /*
2 *
3 * Copyright 2016 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 <string.h>
20
21 #include <grpc/grpc.h>
22 #include <grpc/slice.h>
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
25
26 #include "src/core/lib/channel/channel_args.h"
27 #include "src/core/lib/gpr/string.h"
28 #include "src/core/lib/gprpp/host_port.h"
29 #include "src/core/lib/gprpp/memory.h"
30 #include "src/core/lib/gprpp/thd.h"
31 #include "src/core/lib/iomgr/sockaddr.h"
32 #include "src/core/lib/slice/slice_internal.h"
33 #include "src/core/lib/slice/slice_string_helpers.h"
34 #include "test/core/end2end/cq_verifier.h"
35 #include "test/core/util/port.h"
36 #include "test/core/util/test_config.h"
37 #include "test/core/util/test_tcp_server.h"
38
39 #define HTTP1_RESP_400 \
40 "HTTP/1.0 400 Bad Request\n" \
41 "Content-Type: text/html; charset=UTF-8\n" \
42 "Content-Length: 0\n" \
43 "Date: Tue, 07 Jun 2016 17:43:20 GMT\n\n"
44
45 #define HTTP2_SETTINGS_FRAME "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
46
47 #define HTTP2_RESP(STATUS_CODE) \
48 "\x00\x00>\x01\x04\x00\x00\x00\x01" \
49 "\x10\x0e" \
50 "content-length\x01" \
51 "0" \
52 "\x10\x0c" \
53 "content-type\x10" \
54 "application/grpc" \
55 "\x10\x07:status\x03" #STATUS_CODE
56
57 #define UNPARSEABLE_RESP "Bad Request\n"
58
59 #define HTTP2_DETAIL_MSG(STATUS_CODE) \
60 "Received http2 header with status: " #STATUS_CODE
61
62 /* TODO(zyc) Check the content of incoming data instead of using this length */
63 /* The 'bad' server will start sending responses after reading this amount of
64 * data from the client. */
65 #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200
66
67 struct rpc_state {
68 std::string target;
69 grpc_completion_queue* cq;
70 grpc_channel* channel;
71 grpc_call* call;
72 size_t incoming_data_length;
73 grpc_slice_buffer temp_incoming_buffer;
74 grpc_slice_buffer outgoing_buffer;
75 grpc_endpoint* tcp;
76 gpr_atm done_atm;
77 bool http2_response;
78 bool send_settings;
79 const char* response_payload;
80 size_t response_payload_length;
81 bool connection_attempt_made;
82 };
83
84 static int server_port;
85 static struct rpc_state state;
86 static grpc_closure on_read;
87 static grpc_closure on_writing_settings_frame;
88 static grpc_closure on_write;
89
tag(intptr_t t)90 static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
91
done_write(void *,grpc_error_handle error)92 static void done_write(void* /*arg*/, grpc_error_handle error) {
93 GPR_ASSERT(error == GRPC_ERROR_NONE);
94 gpr_atm_rel_store(&state.done_atm, 1);
95 }
96
done_writing_settings_frame(void *,grpc_error_handle error)97 static void done_writing_settings_frame(void* /* arg */,
98 grpc_error_handle error) {
99 GPR_ASSERT(error == GRPC_ERROR_NONE);
100 grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read,
101 /*urgent=*/false);
102 }
103
handle_write()104 static void handle_write() {
105 grpc_slice slice = grpc_slice_from_copied_buffer(
106 state.response_payload, state.response_payload_length);
107
108 grpc_slice_buffer_reset_and_unref(&state.outgoing_buffer);
109 grpc_slice_buffer_add(&state.outgoing_buffer, slice);
110 grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write, nullptr);
111 }
112
handle_read(void *,grpc_error_handle error)113 static void handle_read(void* /*arg*/, grpc_error_handle error) {
114 if (error != GRPC_ERROR_NONE) {
115 gpr_log(GPR_ERROR, "handle_read error: %s",
116 grpc_error_std_string(error).c_str());
117 return;
118 }
119 state.incoming_data_length += state.temp_incoming_buffer.length;
120
121 size_t i;
122 for (i = 0; i < state.temp_incoming_buffer.count; i++) {
123 char* dump = grpc_dump_slice(state.temp_incoming_buffer.slices[i],
124 GPR_DUMP_HEX | GPR_DUMP_ASCII);
125 gpr_log(GPR_DEBUG, "Server received: %s", dump);
126 gpr_free(dump);
127 }
128
129 gpr_log(GPR_DEBUG,
130 "got %" PRIuPTR " bytes, expected %" PRIuPTR
131 " bytes or a non-HTTP2 response to be sent",
132 state.incoming_data_length,
133 SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD);
134 if (state.incoming_data_length >=
135 SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD ||
136 !state.http2_response) {
137 handle_write();
138 } else {
139 grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read,
140 /*urgent=*/false);
141 }
142 }
143
on_connect(void * arg,grpc_endpoint * tcp,grpc_pollset *,grpc_tcp_server_acceptor * acceptor)144 static void on_connect(void* arg, grpc_endpoint* tcp,
145 grpc_pollset* /*accepting_pollset*/,
146 grpc_tcp_server_acceptor* acceptor) {
147 gpr_free(acceptor);
148 test_tcp_server* server = static_cast<test_tcp_server*>(arg);
149 GRPC_CLOSURE_INIT(&on_read, handle_read, nullptr, grpc_schedule_on_exec_ctx);
150 GRPC_CLOSURE_INIT(&on_writing_settings_frame, done_writing_settings_frame,
151 nullptr, grpc_schedule_on_exec_ctx);
152 GRPC_CLOSURE_INIT(&on_write, done_write, nullptr, grpc_schedule_on_exec_ctx);
153 grpc_slice_buffer_init(&state.temp_incoming_buffer);
154 grpc_slice_buffer_init(&state.outgoing_buffer);
155 state.connection_attempt_made = true;
156 state.tcp = tcp;
157 state.incoming_data_length = 0;
158 grpc_endpoint_add_to_pollset(tcp, server->pollset[0]);
159 if (state.send_settings) {
160 // Send settings frame from server
161 grpc_slice slice = grpc_slice_from_static_buffer(
162 HTTP2_SETTINGS_FRAME, sizeof(HTTP2_SETTINGS_FRAME) - 1);
163 grpc_slice_buffer_add(&state.outgoing_buffer, slice);
164 grpc_endpoint_write(state.tcp, &state.outgoing_buffer,
165 &on_writing_settings_frame, nullptr);
166 } else {
167 grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read,
168 /*urgent=*/false);
169 }
170 }
171
n_sec_deadline(int seconds)172 static gpr_timespec n_sec_deadline(int seconds) {
173 return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
174 gpr_time_from_seconds(seconds, GPR_TIMESPAN));
175 }
176
start_rpc(int target_port,grpc_status_code expected_status,const char * expected_detail)177 static void start_rpc(int target_port, grpc_status_code expected_status,
178 const char* expected_detail) {
179 grpc_op ops[6];
180 grpc_op* op;
181 grpc_metadata_array initial_metadata_recv;
182 grpc_metadata_array trailing_metadata_recv;
183 grpc_status_code status;
184 grpc_call_error error;
185 cq_verifier* cqv;
186 grpc_slice details;
187
188 state.cq = grpc_completion_queue_create_for_next(nullptr);
189 cqv = cq_verifier_create(state.cq);
190 state.target = grpc_core::JoinHostPort("127.0.0.1", target_port);
191
192 state.channel =
193 grpc_insecure_channel_create(state.target.c_str(), nullptr, nullptr);
194 grpc_slice host = grpc_slice_from_static_string("localhost");
195 // The default connect deadline is 20 seconds, so reduce the RPC deadline to 1
196 // second. This helps us verify - a) If the server responded with a non-HTTP2
197 // response, the connect fails immediately resulting in
198 // GRPC_STATUS_UNAVAILABLE instead of GRPC_STATUS_DEADLINE_EXCEEDED. b) If the
199 // server does not send a HTTP2 SETTINGs frame, the RPC fails with a
200 // DEADLINE_EXCEEDED.
201 state.call = grpc_channel_create_call(
202 state.channel, nullptr, GRPC_PROPAGATE_DEFAULTS, state.cq,
203 grpc_slice_from_static_string("/Service/Method"), &host,
204 n_sec_deadline(5), nullptr);
205
206 grpc_metadata_array_init(&initial_metadata_recv);
207 grpc_metadata_array_init(&trailing_metadata_recv);
208
209 memset(ops, 0, sizeof(ops));
210 op = ops;
211 op->op = GRPC_OP_SEND_INITIAL_METADATA;
212 op->data.send_initial_metadata.count = 0;
213 op->flags = 0;
214 op->reserved = nullptr;
215 op++;
216 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
217 op->flags = 0;
218 op->reserved = nullptr;
219 op++;
220 op->op = GRPC_OP_RECV_INITIAL_METADATA;
221 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
222 op->flags = 0;
223 op->reserved = nullptr;
224 op++;
225 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
226 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
227 op->data.recv_status_on_client.status = &status;
228 op->data.recv_status_on_client.status_details = &details;
229 op->flags = 0;
230 op->reserved = nullptr;
231 op++;
232 error = grpc_call_start_batch(state.call, ops, static_cast<size_t>(op - ops),
233 tag(1), nullptr);
234
235 GPR_ASSERT(GRPC_CALL_OK == error);
236
237 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
238 cq_verify(cqv);
239
240 GPR_ASSERT(status == expected_status);
241 if (expected_detail != nullptr) {
242 GPR_ASSERT(-1 != grpc_slice_slice(details, grpc_slice_from_static_string(
243 expected_detail)));
244 }
245
246 grpc_metadata_array_destroy(&initial_metadata_recv);
247 grpc_metadata_array_destroy(&trailing_metadata_recv);
248 grpc_slice_unref(details);
249 cq_verifier_destroy(cqv);
250 }
251
cleanup_rpc()252 static void cleanup_rpc() {
253 grpc_event ev;
254 grpc_slice_buffer_destroy_internal(&state.temp_incoming_buffer);
255 grpc_slice_buffer_destroy_internal(&state.outgoing_buffer);
256 grpc_call_unref(state.call);
257 grpc_completion_queue_shutdown(state.cq);
258 do {
259 ev = grpc_completion_queue_next(state.cq, n_sec_deadline(1), nullptr);
260 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
261 grpc_completion_queue_destroy(state.cq);
262 grpc_channel_destroy(state.channel);
263 state.target.clear();
264 }
265
266 typedef struct {
267 test_tcp_server* server;
268 gpr_event* signal_when_done;
269 } poll_args;
270
actually_poll_server(void * arg)271 static void actually_poll_server(void* arg) {
272 poll_args* pa = static_cast<poll_args*>(arg);
273 gpr_timespec deadline = n_sec_deadline(5);
274 while (true) {
275 bool done = gpr_atm_acq_load(&state.done_atm) != 0;
276 gpr_timespec time_left =
277 gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
278 gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done,
279 time_left.tv_sec, time_left.tv_nsec);
280 if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) {
281 break;
282 }
283 test_tcp_server_poll(pa->server, 1000);
284 }
285 gpr_event_set(pa->signal_when_done, reinterpret_cast<void*>(1));
286 gpr_free(pa);
287 }
288
poll_server_until_read_done(test_tcp_server * server,gpr_event * signal_when_done)289 static grpc_core::Thread* poll_server_until_read_done(
290 test_tcp_server* server, gpr_event* signal_when_done) {
291 gpr_atm_rel_store(&state.done_atm, 0);
292 state.connection_attempt_made = false;
293 poll_args* pa = static_cast<poll_args*>(gpr_malloc(sizeof(*pa)));
294 pa->server = server;
295 pa->signal_when_done = signal_when_done;
296 auto* th =
297 new grpc_core::Thread("grpc_poll_server", actually_poll_server, pa);
298 th->Start();
299 return th;
300 }
301
run_test(bool http2_response,bool send_settings,const char * response_payload,size_t response_payload_length,grpc_status_code expected_status,const char * expected_detail)302 static void run_test(bool http2_response, bool send_settings,
303 const char* response_payload,
304 size_t response_payload_length,
305 grpc_status_code expected_status,
306 const char* expected_detail) {
307 test_tcp_server test_server;
308 grpc_core::ExecCtx exec_ctx;
309 gpr_event ev;
310
311 grpc_init();
312 gpr_event_init(&ev);
313 server_port = grpc_pick_unused_port_or_die();
314 test_tcp_server_init(&test_server, on_connect, &test_server);
315 test_tcp_server_start(&test_server, server_port);
316 state.http2_response = http2_response;
317 state.send_settings = send_settings;
318 state.response_payload = response_payload;
319 state.response_payload_length = response_payload_length;
320
321 /* poll server until sending out the response */
322 std::unique_ptr<grpc_core::Thread> thdptr(
323 poll_server_until_read_done(&test_server, &ev));
324 start_rpc(server_port, expected_status, expected_detail);
325 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
326 thdptr->Join();
327 /* Proof that the server accepted the TCP connection. */
328 GPR_ASSERT(state.connection_attempt_made == true);
329 /* clean up */
330 grpc_endpoint_shutdown(state.tcp,
331 GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
332 grpc_endpoint_destroy(state.tcp);
333 cleanup_rpc();
334 grpc_core::ExecCtx::Get()->Flush();
335 test_tcp_server_destroy(&test_server);
336
337 grpc_shutdown();
338 }
339
main(int argc,char ** argv)340 int main(int argc, char** argv) {
341 grpc::testing::TestEnvironment env(argc, argv);
342 grpc_init();
343
344 /* status defined in hpack static table */
345 run_test(true, true, HTTP2_RESP(204), sizeof(HTTP2_RESP(204)) - 1,
346 GRPC_STATUS_UNKNOWN, HTTP2_DETAIL_MSG(204));
347 run_test(true, true, HTTP2_RESP(206), sizeof(HTTP2_RESP(206)) - 1,
348 GRPC_STATUS_UNKNOWN, HTTP2_DETAIL_MSG(206));
349 run_test(true, true, HTTP2_RESP(304), sizeof(HTTP2_RESP(304)) - 1,
350 GRPC_STATUS_UNKNOWN, HTTP2_DETAIL_MSG(304));
351 run_test(true, true, HTTP2_RESP(400), sizeof(HTTP2_RESP(400)) - 1,
352 GRPC_STATUS_INTERNAL, HTTP2_DETAIL_MSG(400));
353 run_test(true, true, HTTP2_RESP(404), sizeof(HTTP2_RESP(404)) - 1,
354 GRPC_STATUS_UNIMPLEMENTED, HTTP2_DETAIL_MSG(404));
355 run_test(true, true, HTTP2_RESP(500), sizeof(HTTP2_RESP(500)) - 1,
356 GRPC_STATUS_UNKNOWN, HTTP2_DETAIL_MSG(500));
357
358 /* status not defined in hpack static table */
359 run_test(true, true, HTTP2_RESP(401), sizeof(HTTP2_RESP(401)) - 1,
360 GRPC_STATUS_UNAUTHENTICATED, HTTP2_DETAIL_MSG(401));
361 run_test(true, true, HTTP2_RESP(403), sizeof(HTTP2_RESP(403)) - 1,
362 GRPC_STATUS_PERMISSION_DENIED, HTTP2_DETAIL_MSG(403));
363 run_test(true, true, HTTP2_RESP(429), sizeof(HTTP2_RESP(429)) - 1,
364 GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(429));
365 run_test(true, true, HTTP2_RESP(499), sizeof(HTTP2_RESP(499)) - 1,
366 GRPC_STATUS_UNKNOWN, HTTP2_DETAIL_MSG(499));
367 run_test(true, true, HTTP2_RESP(502), sizeof(HTTP2_RESP(502)) - 1,
368 GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(502));
369 run_test(true, true, HTTP2_RESP(503), sizeof(HTTP2_RESP(503)) - 1,
370 GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(503));
371 run_test(true, true, HTTP2_RESP(504), sizeof(HTTP2_RESP(504)) - 1,
372 GRPC_STATUS_UNAVAILABLE, HTTP2_DETAIL_MSG(504));
373 /* unparseable response. RPC should fail immediately due to a connect failure.
374 */
375 run_test(false, false, UNPARSEABLE_RESP, sizeof(UNPARSEABLE_RESP) - 1,
376 GRPC_STATUS_UNAVAILABLE, nullptr);
377
378 /* http1 response. RPC should fail immediately due to a connect failure. */
379 run_test(false, false, HTTP1_RESP_400, sizeof(HTTP1_RESP_400) - 1,
380 GRPC_STATUS_UNAVAILABLE, nullptr);
381
382 /* http2 response without sending a SETTINGs frame. RPC should fail with
383 * DEADLINE_EXCEEDED since the RPC deadline is lower than the connection
384 * attempt deadline. */
385 run_test(true, false, HTTP2_RESP(404), sizeof(HTTP2_RESP(404)) - 1,
386 GRPC_STATUS_DEADLINE_EXCEEDED, nullptr);
387 grpc_shutdown();
388 return 0;
389 }
390