max_message_length.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. /*
  2. *
  3. * Copyright 2015 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 <stdio.h>
  19. #include <string.h>
  20. #include <grpc/byte_buffer.h>
  21. #include <grpc/support/alloc.h>
  22. #include <grpc/support/log.h>
  23. #include <grpc/support/time.h>
  24. #include "src/core/lib/channel/channel_args.h"
  25. #include "src/core/lib/iomgr/exec_ctx.h"
  26. #include "src/core/lib/slice/slice_internal.h"
  27. #include "src/core/lib/slice/slice_string_helpers.h"
  28. #include "test/core/end2end/cq_verifier.h"
  29. #include "test/core/end2end/end2end_tests.h"
  30. static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
  31. static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
  32. const char* test_name,
  33. grpc_channel_args* client_args,
  34. grpc_channel_args* server_args) {
  35. grpc_end2end_test_fixture f;
  36. gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
  37. // We intentionally do not pass the client and server args to
  38. // create_fixture(), since we don't want the limit enforced on the
  39. // proxy, only on the backend server.
  40. f = config.create_fixture(nullptr, nullptr);
  41. config.init_server(&f, server_args);
  42. config.init_client(&f, client_args);
  43. return f;
  44. }
  45. static gpr_timespec n_seconds_from_now(int n) {
  46. return grpc_timeout_seconds_to_deadline(n);
  47. }
  48. static gpr_timespec five_seconds_from_now(void) {
  49. return n_seconds_from_now(5);
  50. }
  51. static void drain_cq(grpc_completion_queue* cq) {
  52. grpc_event ev;
  53. do {
  54. ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
  55. } while (ev.type != GRPC_QUEUE_SHUTDOWN);
  56. }
  57. static void shutdown_server(grpc_end2end_test_fixture* f) {
  58. if (!f->server) return;
  59. grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
  60. grpc_event ev = grpc_completion_queue_next(
  61. f->cq, grpc_timeout_seconds_to_deadline(5), nullptr);
  62. GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  63. GPR_ASSERT(ev.tag == tag(1000));
  64. grpc_server_destroy(f->server);
  65. f->server = nullptr;
  66. }
  67. static void shutdown_client(grpc_end2end_test_fixture* f) {
  68. if (!f->client) return;
  69. grpc_channel_destroy(f->client);
  70. f->client = nullptr;
  71. }
  72. static void end_test(grpc_end2end_test_fixture* f) {
  73. shutdown_server(f);
  74. shutdown_client(f);
  75. grpc_completion_queue_shutdown(f->cq);
  76. drain_cq(f->cq);
  77. grpc_completion_queue_destroy(f->cq);
  78. grpc_completion_queue_destroy(f->shutdown_cq);
  79. }
  80. // Test with request larger than the limit.
  81. // If send_limit is true, applies send limit on client; otherwise, applies
  82. // recv limit on server.
  83. static void test_max_message_length_on_request(grpc_end2end_test_config config,
  84. bool send_limit,
  85. bool use_service_config,
  86. bool use_string_json_value) {
  87. gpr_log(GPR_INFO,
  88. "testing request with send_limit=%d use_service_config=%d "
  89. "use_string_json_value=%d",
  90. send_limit, use_service_config, use_string_json_value);
  91. grpc_end2end_test_fixture f;
  92. grpc_call* c = nullptr;
  93. grpc_call* s = nullptr;
  94. cq_verifier* cqv;
  95. grpc_op ops[6];
  96. grpc_op* op;
  97. grpc_slice request_payload_slice =
  98. grpc_slice_from_copied_string("hello world");
  99. grpc_byte_buffer* request_payload =
  100. grpc_raw_byte_buffer_create(&request_payload_slice, 1);
  101. grpc_byte_buffer* recv_payload = nullptr;
  102. grpc_metadata_array initial_metadata_recv;
  103. grpc_metadata_array trailing_metadata_recv;
  104. grpc_metadata_array request_metadata_recv;
  105. grpc_call_details call_details;
  106. grpc_status_code status;
  107. grpc_call_error error;
  108. grpc_slice details;
  109. int was_cancelled = 2;
  110. grpc_channel_args* client_args = nullptr;
  111. grpc_channel_args* server_args = nullptr;
  112. if (use_service_config) {
  113. // We don't currently support service configs on the server side.
  114. GPR_ASSERT(send_limit);
  115. grpc_arg arg;
  116. arg.type = GRPC_ARG_STRING;
  117. arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
  118. arg.value.string =
  119. use_string_json_value
  120. ? const_cast<char*>(
  121. "{\n"
  122. " \"methodConfig\": [ {\n"
  123. " \"name\": [\n"
  124. " { \"service\": \"service\", \"method\": \"method\" }\n"
  125. " ],\n"
  126. " \"maxRequestMessageBytes\": \"5\"\n"
  127. " } ]\n"
  128. "}")
  129. : const_cast<char*>(
  130. "{\n"
  131. " \"methodConfig\": [ {\n"
  132. " \"name\": [\n"
  133. " { \"service\": \"service\", \"method\": \"method\" }\n"
  134. " ],\n"
  135. " \"maxRequestMessageBytes\": 5\n"
  136. " } ]\n"
  137. "}");
  138. client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
  139. } else {
  140. // Set limit via channel args.
  141. grpc_arg arg;
  142. arg.key = send_limit
  143. ? const_cast<char*>(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH)
  144. : const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH);
  145. arg.type = GRPC_ARG_INTEGER;
  146. arg.value.integer = 5;
  147. grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
  148. if (send_limit) {
  149. client_args = args;
  150. } else {
  151. server_args = args;
  152. }
  153. }
  154. f = begin_test(config, "test_max_request_message_length", client_args,
  155. server_args);
  156. {
  157. grpc_core::ExecCtx exec_ctx;
  158. if (client_args != nullptr) grpc_channel_args_destroy(client_args);
  159. if (server_args != nullptr) grpc_channel_args_destroy(server_args);
  160. }
  161. cqv = cq_verifier_create(f.cq);
  162. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  163. grpc_slice_from_static_string("/service/method"),
  164. nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
  165. nullptr);
  166. GPR_ASSERT(c);
  167. grpc_metadata_array_init(&initial_metadata_recv);
  168. grpc_metadata_array_init(&trailing_metadata_recv);
  169. grpc_metadata_array_init(&request_metadata_recv);
  170. grpc_call_details_init(&call_details);
  171. memset(ops, 0, sizeof(ops));
  172. op = ops;
  173. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  174. op->data.send_initial_metadata.count = 0;
  175. op->flags = 0;
  176. op->reserved = nullptr;
  177. op++;
  178. op->op = GRPC_OP_SEND_MESSAGE;
  179. op->data.send_message.send_message = request_payload;
  180. op->flags = 0;
  181. op->reserved = nullptr;
  182. op++;
  183. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  184. op->flags = 0;
  185. op->reserved = nullptr;
  186. op++;
  187. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  188. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  189. op->flags = 0;
  190. op->reserved = nullptr;
  191. op++;
  192. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  193. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  194. op->data.recv_status_on_client.status = &status;
  195. op->data.recv_status_on_client.status_details = &details;
  196. op->flags = 0;
  197. op->reserved = nullptr;
  198. op++;
  199. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  200. nullptr);
  201. GPR_ASSERT(GRPC_CALL_OK == error);
  202. if (send_limit) {
  203. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  204. cq_verify(cqv);
  205. goto done;
  206. }
  207. error =
  208. grpc_server_request_call(f.server, &s, &call_details,
  209. &request_metadata_recv, f.cq, f.cq, tag(101));
  210. GPR_ASSERT(GRPC_CALL_OK == error);
  211. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  212. cq_verify(cqv);
  213. memset(ops, 0, sizeof(ops));
  214. op = ops;
  215. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  216. op->data.recv_close_on_server.cancelled = &was_cancelled;
  217. op->flags = 0;
  218. op->reserved = nullptr;
  219. op++;
  220. op->op = GRPC_OP_RECV_MESSAGE;
  221. op->data.recv_message.recv_message = &recv_payload;
  222. op->flags = 0;
  223. op->reserved = nullptr;
  224. op++;
  225. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  226. nullptr);
  227. GPR_ASSERT(GRPC_CALL_OK == error);
  228. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  229. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  230. cq_verify(cqv);
  231. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
  232. GPR_ASSERT(was_cancelled == 1);
  233. done:
  234. GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
  235. GPR_ASSERT(
  236. grpc_slice_str_cmp(
  237. details, send_limit
  238. ? "Sent message larger than max (11 vs. 5)"
  239. : "Received message larger than max (11 vs. 5)") == 0);
  240. grpc_slice_unref(details);
  241. grpc_metadata_array_destroy(&initial_metadata_recv);
  242. grpc_metadata_array_destroy(&trailing_metadata_recv);
  243. grpc_metadata_array_destroy(&request_metadata_recv);
  244. grpc_call_details_destroy(&call_details);
  245. grpc_byte_buffer_destroy(request_payload);
  246. grpc_byte_buffer_destroy(recv_payload);
  247. grpc_call_unref(c);
  248. if (s != nullptr) grpc_call_unref(s);
  249. cq_verifier_destroy(cqv);
  250. end_test(&f);
  251. config.tear_down_data(&f);
  252. }
  253. // Test with response larger than the limit.
  254. // If send_limit is true, applies send limit on server; otherwise, applies
  255. // recv limit on client.
  256. static void test_max_message_length_on_response(grpc_end2end_test_config config,
  257. bool send_limit,
  258. bool use_service_config,
  259. bool use_string_json_value) {
  260. gpr_log(GPR_INFO,
  261. "testing response with send_limit=%d use_service_config=%d "
  262. "use_string_json_value=%d",
  263. send_limit, use_service_config, use_string_json_value);
  264. grpc_end2end_test_fixture f;
  265. grpc_call* c = nullptr;
  266. grpc_call* s = nullptr;
  267. cq_verifier* cqv;
  268. grpc_op ops[6];
  269. grpc_op* op;
  270. grpc_slice response_payload_slice =
  271. grpc_slice_from_copied_string("hello world");
  272. grpc_byte_buffer* response_payload =
  273. grpc_raw_byte_buffer_create(&response_payload_slice, 1);
  274. grpc_byte_buffer* recv_payload = nullptr;
  275. grpc_metadata_array initial_metadata_recv;
  276. grpc_metadata_array trailing_metadata_recv;
  277. grpc_metadata_array request_metadata_recv;
  278. grpc_call_details call_details;
  279. grpc_status_code status;
  280. grpc_call_error error;
  281. grpc_slice details;
  282. int was_cancelled = 2;
  283. grpc_channel_args* client_args = nullptr;
  284. grpc_channel_args* server_args = nullptr;
  285. if (use_service_config) {
  286. // We don't currently support service configs on the server side.
  287. GPR_ASSERT(!send_limit);
  288. grpc_arg arg;
  289. arg.type = GRPC_ARG_STRING;
  290. arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
  291. arg.value.string = const_cast<char*>(
  292. use_string_json_value
  293. ? "{\n"
  294. " \"methodConfig\": [ {\n"
  295. " \"name\": [\n"
  296. " { \"service\": \"service\", \"method\": \"method\" }\n"
  297. " ],\n"
  298. " \"maxResponseMessageBytes\": \"5\"\n"
  299. " } ]\n"
  300. "}"
  301. : "{\n"
  302. " \"methodConfig\": [ {\n"
  303. " \"name\": [\n"
  304. " { \"service\": \"service\", \"method\": \"method\" }\n"
  305. " ],\n"
  306. " \"maxResponseMessageBytes\": 5\n"
  307. " } ]\n"
  308. "}");
  309. client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
  310. } else {
  311. // Set limit via channel args.
  312. grpc_arg arg;
  313. arg.key = send_limit
  314. ? const_cast<char*>(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH)
  315. : const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH);
  316. arg.type = GRPC_ARG_INTEGER;
  317. arg.value.integer = 5;
  318. grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
  319. if (send_limit) {
  320. server_args = args;
  321. } else {
  322. client_args = args;
  323. }
  324. }
  325. f = begin_test(config, "test_max_response_message_length", client_args,
  326. server_args);
  327. {
  328. grpc_core::ExecCtx exec_ctx;
  329. if (client_args != nullptr) grpc_channel_args_destroy(client_args);
  330. if (server_args != nullptr) grpc_channel_args_destroy(server_args);
  331. }
  332. cqv = cq_verifier_create(f.cq);
  333. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  334. grpc_slice_from_static_string("/service/method"),
  335. nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
  336. nullptr);
  337. GPR_ASSERT(c);
  338. grpc_metadata_array_init(&initial_metadata_recv);
  339. grpc_metadata_array_init(&trailing_metadata_recv);
  340. grpc_metadata_array_init(&request_metadata_recv);
  341. grpc_call_details_init(&call_details);
  342. memset(ops, 0, sizeof(ops));
  343. op = ops;
  344. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  345. op->data.send_initial_metadata.count = 0;
  346. op->flags = 0;
  347. op->reserved = nullptr;
  348. op++;
  349. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  350. op->flags = 0;
  351. op->reserved = nullptr;
  352. op++;
  353. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  354. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  355. op->flags = 0;
  356. op->reserved = nullptr;
  357. op++;
  358. op->op = GRPC_OP_RECV_MESSAGE;
  359. op->data.recv_message.recv_message = &recv_payload;
  360. op->flags = 0;
  361. op->reserved = nullptr;
  362. op++;
  363. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  364. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  365. op->data.recv_status_on_client.status = &status;
  366. op->data.recv_status_on_client.status_details = &details;
  367. op->flags = 0;
  368. op->reserved = nullptr;
  369. op++;
  370. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  371. nullptr);
  372. GPR_ASSERT(GRPC_CALL_OK == error);
  373. error =
  374. grpc_server_request_call(f.server, &s, &call_details,
  375. &request_metadata_recv, f.cq, f.cq, tag(101));
  376. GPR_ASSERT(GRPC_CALL_OK == error);
  377. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  378. cq_verify(cqv);
  379. memset(ops, 0, sizeof(ops));
  380. op = ops;
  381. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  382. op->data.send_initial_metadata.count = 0;
  383. op->flags = 0;
  384. op->reserved = nullptr;
  385. op++;
  386. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  387. op->data.recv_close_on_server.cancelled = &was_cancelled;
  388. op->flags = 0;
  389. op->reserved = nullptr;
  390. op++;
  391. op->op = GRPC_OP_SEND_MESSAGE;
  392. op->data.send_message.send_message = response_payload;
  393. op->flags = 0;
  394. op->reserved = nullptr;
  395. op++;
  396. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  397. op->data.send_status_from_server.trailing_metadata_count = 0;
  398. op->data.send_status_from_server.status = GRPC_STATUS_OK;
  399. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  400. op->data.send_status_from_server.status_details = &status_details;
  401. op->flags = 0;
  402. op->reserved = nullptr;
  403. op++;
  404. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  405. nullptr);
  406. GPR_ASSERT(GRPC_CALL_OK == error);
  407. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  408. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  409. cq_verify(cqv);
  410. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
  411. GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
  412. GPR_ASSERT(
  413. grpc_slice_str_cmp(
  414. details, send_limit
  415. ? "Sent message larger than max (11 vs. 5)"
  416. : "Received message larger than max (11 vs. 5)") == 0);
  417. grpc_slice_unref(details);
  418. grpc_metadata_array_destroy(&initial_metadata_recv);
  419. grpc_metadata_array_destroy(&trailing_metadata_recv);
  420. grpc_metadata_array_destroy(&request_metadata_recv);
  421. grpc_call_details_destroy(&call_details);
  422. grpc_byte_buffer_destroy(response_payload);
  423. grpc_byte_buffer_destroy(recv_payload);
  424. grpc_call_unref(c);
  425. if (s != nullptr) grpc_call_unref(s);
  426. cq_verifier_destroy(cqv);
  427. end_test(&f);
  428. config.tear_down_data(&f);
  429. }
  430. static grpc_metadata gzip_compression_override() {
  431. grpc_metadata gzip_compression_override;
  432. gzip_compression_override.key =
  433. grpc_slice_from_static_string("grpc-internal-encoding-request");
  434. gzip_compression_override.value = grpc_slice_from_static_string("gzip");
  435. memset(&gzip_compression_override.internal_data, 0,
  436. sizeof(gzip_compression_override.internal_data));
  437. return gzip_compression_override;
  438. }
  439. // Test receive message limit with compressed request larger than the limit
  440. static void test_max_receive_message_length_on_compressed_request(
  441. grpc_end2end_test_config config, bool minimal_stack) {
  442. gpr_log(GPR_INFO,
  443. "test max receive message length on compressed request with "
  444. "minimal_stack=%d",
  445. minimal_stack);
  446. grpc_end2end_test_fixture f;
  447. grpc_call* c = nullptr;
  448. grpc_call* s = nullptr;
  449. cq_verifier* cqv;
  450. grpc_op ops[6];
  451. grpc_op* op;
  452. grpc_slice request_payload_slice = grpc_slice_malloc(1024);
  453. memset(GRPC_SLICE_START_PTR(request_payload_slice), 'a', 1024);
  454. grpc_byte_buffer* request_payload =
  455. grpc_raw_byte_buffer_create(&request_payload_slice, 1);
  456. grpc_byte_buffer* recv_payload = nullptr;
  457. grpc_metadata_array initial_metadata_recv;
  458. grpc_metadata_array trailing_metadata_recv;
  459. grpc_metadata_array request_metadata_recv;
  460. grpc_call_details call_details;
  461. grpc_status_code status;
  462. grpc_call_error error;
  463. grpc_slice details, status_details;
  464. int was_cancelled = 2;
  465. // Set limit via channel args.
  466. grpc_arg arg[2];
  467. arg[0] = grpc_channel_arg_integer_create(
  468. const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH), 5);
  469. arg[1] = grpc_channel_arg_integer_create(
  470. const_cast<char*>(GRPC_ARG_MINIMAL_STACK), minimal_stack);
  471. grpc_channel_args* server_args =
  472. grpc_channel_args_copy_and_add(nullptr, arg, 2);
  473. f = begin_test(config, "test_max_request_message_length", nullptr,
  474. server_args);
  475. {
  476. grpc_core::ExecCtx exec_ctx;
  477. grpc_channel_args_destroy(server_args);
  478. }
  479. cqv = cq_verifier_create(f.cq);
  480. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  481. grpc_slice_from_static_string("/service/method"),
  482. nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
  483. nullptr);
  484. GPR_ASSERT(c);
  485. grpc_metadata_array_init(&initial_metadata_recv);
  486. grpc_metadata_array_init(&trailing_metadata_recv);
  487. grpc_metadata_array_init(&request_metadata_recv);
  488. grpc_call_details_init(&call_details);
  489. grpc_metadata compression_md = gzip_compression_override();
  490. memset(ops, 0, sizeof(ops));
  491. op = ops;
  492. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  493. op->data.send_initial_metadata.count = 1;
  494. op->data.send_initial_metadata.metadata = &compression_md;
  495. op->flags = 0;
  496. op->reserved = nullptr;
  497. op++;
  498. op->op = GRPC_OP_SEND_MESSAGE;
  499. op->data.send_message.send_message = request_payload;
  500. op->flags = 0;
  501. op->reserved = nullptr;
  502. op++;
  503. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  504. op->flags = 0;
  505. op->reserved = nullptr;
  506. op++;
  507. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  508. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  509. op->flags = 0;
  510. op->reserved = nullptr;
  511. op++;
  512. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  513. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  514. op->data.recv_status_on_client.status = &status;
  515. op->data.recv_status_on_client.status_details = &details;
  516. op->flags = 0;
  517. op->reserved = nullptr;
  518. op++;
  519. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  520. nullptr);
  521. GPR_ASSERT(GRPC_CALL_OK == error);
  522. error =
  523. grpc_server_request_call(f.server, &s, &call_details,
  524. &request_metadata_recv, f.cq, f.cq, tag(101));
  525. GPR_ASSERT(GRPC_CALL_OK == error);
  526. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  527. cq_verify(cqv);
  528. memset(ops, 0, sizeof(ops));
  529. op = ops;
  530. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  531. op->data.recv_close_on_server.cancelled = &was_cancelled;
  532. op->flags = 0;
  533. op->reserved = nullptr;
  534. op++;
  535. op->op = GRPC_OP_RECV_MESSAGE;
  536. op->data.recv_message.recv_message = &recv_payload;
  537. op->flags = 0;
  538. op->reserved = nullptr;
  539. op++;
  540. if (minimal_stack) {
  541. /* Expect the RPC to proceed normally for a minimal stack */
  542. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  543. op->data.send_initial_metadata.count = 0;
  544. op->flags = 0;
  545. op->reserved = nullptr;
  546. op++;
  547. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  548. op->data.send_status_from_server.trailing_metadata_count = 0;
  549. op->data.send_status_from_server.status = GRPC_STATUS_OK;
  550. status_details = grpc_slice_from_static_string("xyz");
  551. op->data.send_status_from_server.status_details = &status_details;
  552. op->flags = 0;
  553. op->reserved = nullptr;
  554. op++;
  555. }
  556. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  557. nullptr);
  558. GPR_ASSERT(GRPC_CALL_OK == error);
  559. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  560. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  561. cq_verify(cqv);
  562. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
  563. if (minimal_stack) {
  564. /* We do not perform message size checks for minimal stack. */
  565. GPR_ASSERT(status == GRPC_STATUS_OK);
  566. } else {
  567. GPR_ASSERT(was_cancelled == 1);
  568. GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
  569. GPR_ASSERT(grpc_slice_str_cmp(
  570. details, "Received message larger than max (29 vs. 5)") ==
  571. 0);
  572. }
  573. grpc_slice_unref(details);
  574. grpc_slice_unref(request_payload_slice);
  575. grpc_metadata_array_destroy(&initial_metadata_recv);
  576. grpc_metadata_array_destroy(&trailing_metadata_recv);
  577. grpc_metadata_array_destroy(&request_metadata_recv);
  578. grpc_call_details_destroy(&call_details);
  579. grpc_byte_buffer_destroy(request_payload);
  580. grpc_byte_buffer_destroy(recv_payload);
  581. grpc_call_unref(c);
  582. if (s != nullptr) grpc_call_unref(s);
  583. cq_verifier_destroy(cqv);
  584. end_test(&f);
  585. config.tear_down_data(&f);
  586. }
  587. // Test receive message limit with compressed response larger than the limit.
  588. static void test_max_receive_message_length_on_compressed_response(
  589. grpc_end2end_test_config config, bool minimal_stack) {
  590. gpr_log(GPR_INFO,
  591. "testing max receive message length on compressed response with "
  592. "minimal_stack=%d",
  593. minimal_stack);
  594. grpc_end2end_test_fixture f;
  595. grpc_call* c = nullptr;
  596. grpc_call* s = nullptr;
  597. cq_verifier* cqv;
  598. grpc_op ops[6];
  599. grpc_op* op;
  600. grpc_slice response_payload_slice = grpc_slice_malloc(1024);
  601. memset(GRPC_SLICE_START_PTR(response_payload_slice), 'a', 1024);
  602. grpc_byte_buffer* response_payload =
  603. grpc_raw_byte_buffer_create(&response_payload_slice, 1);
  604. grpc_byte_buffer* recv_payload = nullptr;
  605. grpc_metadata_array initial_metadata_recv;
  606. grpc_metadata_array trailing_metadata_recv;
  607. grpc_metadata_array request_metadata_recv;
  608. grpc_call_details call_details;
  609. grpc_status_code status;
  610. grpc_call_error error;
  611. grpc_slice details;
  612. int was_cancelled = 2;
  613. // Set limit via channel args.
  614. grpc_arg arg[2];
  615. arg[0] = grpc_channel_arg_integer_create(
  616. const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH), 5);
  617. arg[1] = grpc_channel_arg_integer_create(
  618. const_cast<char*>(GRPC_ARG_MINIMAL_STACK), minimal_stack);
  619. grpc_channel_args* client_args =
  620. grpc_channel_args_copy_and_add(nullptr, arg, 2);
  621. f = begin_test(config, "test_max_response_message_length", client_args,
  622. nullptr);
  623. {
  624. grpc_core::ExecCtx exec_ctx;
  625. grpc_channel_args_destroy(client_args);
  626. }
  627. cqv = cq_verifier_create(f.cq);
  628. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  629. grpc_slice_from_static_string("/service/method"),
  630. nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
  631. nullptr);
  632. GPR_ASSERT(c);
  633. grpc_metadata_array_init(&initial_metadata_recv);
  634. grpc_metadata_array_init(&trailing_metadata_recv);
  635. grpc_metadata_array_init(&request_metadata_recv);
  636. grpc_call_details_init(&call_details);
  637. memset(ops, 0, sizeof(ops));
  638. op = ops;
  639. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  640. op->data.send_initial_metadata.count = 0;
  641. op->flags = 0;
  642. op->reserved = nullptr;
  643. op++;
  644. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  645. op->flags = 0;
  646. op->reserved = nullptr;
  647. op++;
  648. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  649. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  650. op->flags = 0;
  651. op->reserved = nullptr;
  652. op++;
  653. op->op = GRPC_OP_RECV_MESSAGE;
  654. op->data.recv_message.recv_message = &recv_payload;
  655. op->flags = 0;
  656. op->reserved = nullptr;
  657. op++;
  658. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  659. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  660. op->data.recv_status_on_client.status = &status;
  661. op->data.recv_status_on_client.status_details = &details;
  662. op->flags = 0;
  663. op->reserved = nullptr;
  664. op++;
  665. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  666. nullptr);
  667. GPR_ASSERT(GRPC_CALL_OK == error);
  668. error =
  669. grpc_server_request_call(f.server, &s, &call_details,
  670. &request_metadata_recv, f.cq, f.cq, tag(101));
  671. GPR_ASSERT(GRPC_CALL_OK == error);
  672. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  673. cq_verify(cqv);
  674. grpc_metadata compression_md = gzip_compression_override();
  675. memset(ops, 0, sizeof(ops));
  676. op = ops;
  677. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  678. op->data.send_initial_metadata.count = 1;
  679. op->data.send_initial_metadata.metadata = &compression_md;
  680. op->flags = 0;
  681. op->reserved = nullptr;
  682. op++;
  683. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  684. op->data.recv_close_on_server.cancelled = &was_cancelled;
  685. op->flags = 0;
  686. op->reserved = nullptr;
  687. op++;
  688. op->op = GRPC_OP_SEND_MESSAGE;
  689. op->data.send_message.send_message = response_payload;
  690. op->flags = 0;
  691. op->reserved = nullptr;
  692. op++;
  693. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  694. op->data.send_status_from_server.trailing_metadata_count = 0;
  695. op->data.send_status_from_server.status = GRPC_STATUS_OK;
  696. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  697. op->data.send_status_from_server.status_details = &status_details;
  698. op->flags = 0;
  699. op->reserved = nullptr;
  700. op++;
  701. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  702. nullptr);
  703. GPR_ASSERT(GRPC_CALL_OK == error);
  704. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  705. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  706. cq_verify(cqv);
  707. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
  708. if (minimal_stack) {
  709. /* We do not perform message size checks for minimal stack. */
  710. GPR_ASSERT(status == GRPC_STATUS_OK);
  711. } else {
  712. GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
  713. GPR_ASSERT(grpc_slice_str_cmp(
  714. details, "Received message larger than max (29 vs. 5)") ==
  715. 0);
  716. }
  717. grpc_slice_unref(details);
  718. grpc_slice_unref(response_payload_slice);
  719. grpc_metadata_array_destroy(&initial_metadata_recv);
  720. grpc_metadata_array_destroy(&trailing_metadata_recv);
  721. grpc_metadata_array_destroy(&request_metadata_recv);
  722. grpc_call_details_destroy(&call_details);
  723. grpc_byte_buffer_destroy(response_payload);
  724. grpc_byte_buffer_destroy(recv_payload);
  725. grpc_call_unref(c);
  726. if (s != nullptr) grpc_call_unref(s);
  727. cq_verifier_destroy(cqv);
  728. end_test(&f);
  729. config.tear_down_data(&f);
  730. }
  731. void max_message_length(grpc_end2end_test_config config) {
  732. test_max_message_length_on_request(config, false /* send_limit */,
  733. false /* use_service_config */,
  734. false /* use_string_json_value */);
  735. test_max_message_length_on_request(config, true /* send_limit */,
  736. false /* use_service_config */,
  737. false /* use_string_json_value */);
  738. test_max_message_length_on_response(config, false /* send_limit */,
  739. false /* use_service_config */,
  740. false /* use_string_json_value */);
  741. test_max_message_length_on_response(config, true /* send_limit */,
  742. false /* use_service_config */,
  743. false /* use_string_json_value */);
  744. test_max_message_length_on_request(config, true /* send_limit */,
  745. true /* use_service_config */,
  746. false /* use_string_json_value */);
  747. test_max_message_length_on_request(config, true /* send_limit */,
  748. true /* use_service_config */,
  749. true /* use_string_json_value */);
  750. test_max_message_length_on_response(config, false /* send_limit */,
  751. true /* use_service_config */,
  752. false /* use_string_json_value */);
  753. test_max_message_length_on_response(config, false /* send_limit */,
  754. true /* use_service_config */,
  755. true /* use_string_json_value */);
  756. /* The following tests are not useful for inproc transport and do not work
  757. * with our simple proxy. */
  758. if (strcmp(config.name, "inproc") != 0 &&
  759. (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) == 0) {
  760. test_max_receive_message_length_on_compressed_request(config, false);
  761. test_max_receive_message_length_on_compressed_request(config, true);
  762. test_max_receive_message_length_on_compressed_response(config, false);
  763. test_max_receive_message_length_on_compressed_response(config, true);
  764. }
  765. }
  766. void max_message_length_pre_init(void) {}