bad_server_response_test.cc 14 KB

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