3 * Copyright 2016 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <grpc/grpc.h>
22 #include <grpc/slice.h>
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
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"
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"
45 #define HTTP2_SETTINGS_FRAME "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
47 #define HTTP2_RESP(STATUS_CODE) \
48 "\x00\x00>\x01\x04\x00\x00\x00\x01" \
50 "content-length\x01" \
55 "\x10\x07:status\x03" #STATUS_CODE
57 #define UNPARSEABLE_RESP "Bad Request\n"
59 #define HTTP2_DETAIL_MSG(STATUS_CODE) \
60 "Received http2 header with status: " #STATUS_CODE
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
69 grpc_completion_queue* cq;
70 grpc_channel* channel;
72 size_t incoming_data_length;
73 grpc_slice_buffer temp_incoming_buffer;
74 grpc_slice_buffer outgoing_buffer;
79 const char* response_payload;
80 size_t response_payload_length;
81 bool connection_attempt_made;
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;
90 static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
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);
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,
104 static void handle_write() {
105 grpc_slice slice = grpc_slice_from_copied_buffer(
106 state.response_payload, state.response_payload_length);
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);
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());
119 state.incoming_data_length += state.temp_incoming_buffer.length;
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);
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) {
139 grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read,
144 static void on_connect(void* arg, grpc_endpoint* tcp,
145 grpc_pollset* /*accepting_pollset*/,
146 grpc_tcp_server_acceptor* 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;
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);
167 grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read,
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));
177 static void start_rpc(int target_port, grpc_status_code expected_status,
178 const char* expected_detail) {
181 grpc_metadata_array initial_metadata_recv;
182 grpc_metadata_array trailing_metadata_recv;
183 grpc_status_code status;
184 grpc_call_error error;
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);
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);
206 grpc_metadata_array_init(&initial_metadata_recv);
207 grpc_metadata_array_init(&trailing_metadata_recv);
209 memset(ops, 0, sizeof(ops));
211 op->op = GRPC_OP_SEND_INITIAL_METADATA;
212 op->data.send_initial_metadata.count = 0;
214 op->reserved = nullptr;
216 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
218 op->reserved = nullptr;
220 op->op = GRPC_OP_RECV_INITIAL_METADATA;
221 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
223 op->reserved = nullptr;
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;
230 op->reserved = nullptr;
232 error = grpc_call_start_batch(state.call, ops, static_cast<size_t>(op - ops),
235 GPR_ASSERT(GRPC_CALL_OK == error);
237 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
240 GPR_ASSERT(status == expected_status);
241 if (expected_detail != nullptr) {
242 GPR_ASSERT(-1 != grpc_slice_slice(details, grpc_slice_from_static_string(
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);
252 static void cleanup_rpc() {
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);
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();
267 test_tcp_server* server;
268 gpr_event* signal_when_done;
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);
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) {
283 test_tcp_server_poll(pa->server, 1000);
285 gpr_event_set(pa->signal_when_done, reinterpret_cast<void*>(1));
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)));
295 pa->signal_when_done = signal_when_done;
297 new grpc_core::Thread("grpc_poll_server", actually_poll_server, pa);
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;
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;
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));
327 /* Proof that the server accepted the TCP connection. */
328 GPR_ASSERT(state.connection_attempt_made == true);
330 grpc_endpoint_shutdown(state.tcp,
331 GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown"));
332 grpc_endpoint_destroy(state.tcp);
334 grpc_core::ExecCtx::Get()->Flush();
335 test_tcp_server_destroy(&test_server);
340 int main(int argc, char** argv) {
341 grpc::testing::TestEnvironment env(argc, argv);
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));
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.
375 run_test(false, false, UNPARSEABLE_RESP, sizeof(UNPARSEABLE_RESP) - 1,
376 GRPC_STATUS_UNAVAILABLE, nullptr);
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);
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);