|
|
@ -244,8 +244,140 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { |
|
|
|
config.tear_down_data(&f); |
|
|
|
config.tear_down_data(&f); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Server responds with metadata larger than what the client accepts.
|
|
|
|
|
|
|
|
static void test_request_with_bad_large_metadata_response( |
|
|
|
|
|
|
|
grpc_end2end_test_config config) { |
|
|
|
|
|
|
|
grpc_call* c; |
|
|
|
|
|
|
|
grpc_call* s; |
|
|
|
|
|
|
|
grpc_metadata meta; |
|
|
|
|
|
|
|
const size_t large_size = 64 * 1024; |
|
|
|
|
|
|
|
grpc_arg arg; |
|
|
|
|
|
|
|
arg.type = GRPC_ARG_INTEGER; |
|
|
|
|
|
|
|
arg.key = const_cast<char*>(GRPC_ARG_MAX_METADATA_SIZE); |
|
|
|
|
|
|
|
arg.value.integer = 1024; |
|
|
|
|
|
|
|
grpc_channel_args args = {1, &arg}; |
|
|
|
|
|
|
|
grpc_end2end_test_fixture f = begin_test( |
|
|
|
|
|
|
|
config, "test_request_with_bad_large_metadata_response", &args, &args); |
|
|
|
|
|
|
|
cq_verifier* cqv = cq_verifier_create(f.cq); |
|
|
|
|
|
|
|
grpc_op ops[6]; |
|
|
|
|
|
|
|
grpc_op* op; |
|
|
|
|
|
|
|
grpc_metadata_array initial_metadata_recv; |
|
|
|
|
|
|
|
grpc_metadata_array trailing_metadata_recv; |
|
|
|
|
|
|
|
grpc_metadata_array request_metadata_recv; |
|
|
|
|
|
|
|
grpc_call_details call_details; |
|
|
|
|
|
|
|
grpc_status_code status; |
|
|
|
|
|
|
|
grpc_call_error error; |
|
|
|
|
|
|
|
grpc_slice details; |
|
|
|
|
|
|
|
int was_cancelled = 2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gpr_timespec deadline = five_seconds_from_now(); |
|
|
|
|
|
|
|
c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, |
|
|
|
|
|
|
|
grpc_slice_from_static_string("/foo"), nullptr, |
|
|
|
|
|
|
|
deadline, nullptr); |
|
|
|
|
|
|
|
GPR_ASSERT(c); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
meta.key = grpc_slice_from_static_string("key"); |
|
|
|
|
|
|
|
meta.value = grpc_slice_malloc(large_size); |
|
|
|
|
|
|
|
memset(GRPC_SLICE_START_PTR(meta.value), 'a', large_size); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_metadata_array_init(&initial_metadata_recv); |
|
|
|
|
|
|
|
grpc_metadata_array_init(&trailing_metadata_recv); |
|
|
|
|
|
|
|
grpc_metadata_array_init(&request_metadata_recv); |
|
|
|
|
|
|
|
grpc_call_details_init(&call_details); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(ops, 0, sizeof(ops)); |
|
|
|
|
|
|
|
// Client: send request.
|
|
|
|
|
|
|
|
op = ops; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
|
|
|
|
|
|
|
op->data.send_initial_metadata.count = 0; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_INITIAL_METADATA; |
|
|
|
|
|
|
|
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.status = &status; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.status_details = &details; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), |
|
|
|
|
|
|
|
nullptr); |
|
|
|
|
|
|
|
GPR_ASSERT(GRPC_CALL_OK == error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
error = |
|
|
|
|
|
|
|
grpc_server_request_call(f.server, &s, &call_details, |
|
|
|
|
|
|
|
&request_metadata_recv, f.cq, f.cq, tag(101)); |
|
|
|
|
|
|
|
GPR_ASSERT(GRPC_CALL_OK == error); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CQ_EXPECT_COMPLETION(cqv, tag(101), 1); |
|
|
|
|
|
|
|
cq_verify(cqv); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(ops, 0, sizeof(ops)); |
|
|
|
|
|
|
|
// Server: send large initial metadata
|
|
|
|
|
|
|
|
op = ops; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
|
|
|
|
|
|
|
op->data.send_initial_metadata.count = 1; |
|
|
|
|
|
|
|
op->data.send_initial_metadata.metadata = &meta; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; |
|
|
|
|
|
|
|
op->data.recv_close_on_server.cancelled = &was_cancelled; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; |
|
|
|
|
|
|
|
op->data.send_status_from_server.trailing_metadata_count = 0; |
|
|
|
|
|
|
|
op->data.send_status_from_server.status = GRPC_STATUS_OK; |
|
|
|
|
|
|
|
grpc_slice status_details = grpc_slice_from_static_string("xyz"); |
|
|
|
|
|
|
|
op->data.send_status_from_server.status_details = &status_details; |
|
|
|
|
|
|
|
op->flags = 0; |
|
|
|
|
|
|
|
op->reserved = nullptr; |
|
|
|
|
|
|
|
op++; |
|
|
|
|
|
|
|
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), |
|
|
|
|
|
|
|
nullptr); |
|
|
|
|
|
|
|
GPR_ASSERT(GRPC_CALL_OK == error); |
|
|
|
|
|
|
|
CQ_EXPECT_COMPLETION(cqv, tag(102), 1); |
|
|
|
|
|
|
|
CQ_EXPECT_COMPLETION(cqv, tag(1), 1); |
|
|
|
|
|
|
|
cq_verify(cqv); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED); |
|
|
|
|
|
|
|
GPR_ASSERT(0 == grpc_slice_str_cmp( |
|
|
|
|
|
|
|
details, "received initial metadata size exceeds limit")); |
|
|
|
|
|
|
|
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_slice_unref(details); |
|
|
|
|
|
|
|
grpc_metadata_array_destroy(&initial_metadata_recv); |
|
|
|
|
|
|
|
grpc_metadata_array_destroy(&trailing_metadata_recv); |
|
|
|
|
|
|
|
grpc_metadata_array_destroy(&request_metadata_recv); |
|
|
|
|
|
|
|
grpc_call_details_destroy(&call_details); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_call_unref(c); |
|
|
|
|
|
|
|
grpc_call_unref(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cq_verifier_destroy(cqv); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grpc_slice_unref(meta.value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end_test(&f); |
|
|
|
|
|
|
|
config.tear_down_data(&f); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void large_metadata(grpc_end2end_test_config config) { |
|
|
|
void large_metadata(grpc_end2end_test_config config) { |
|
|
|
test_request_with_large_metadata(config); |
|
|
|
test_request_with_large_metadata(config); |
|
|
|
|
|
|
|
// TODO(yashykt): Maybe add checks for metadata size in inproc transport too.
|
|
|
|
|
|
|
|
if (strcmp(config.name, "inproc") != 0) { |
|
|
|
|
|
|
|
test_request_with_bad_large_metadata_response(config); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void large_metadata_pre_init(void) {} |
|
|
|
void large_metadata_pre_init(void) {} |
|
|
|