static BIGNUM *bignum_from_base64(const char *b64) { BIGNUM *result = NULL; gpr_slice bin; if (b64 == NULL) return NULL; bin = grpc_base64_decode(b64, 1); if (GPR_SLICE_IS_EMPTY(bin)) { gpr_log(GPR_ERROR, "Invalid base64 for big num."); return NULL; } result = BN_bin2bn(GPR_SLICE_START_PTR(bin), TSI_SIZE_AS_SIZE(GPR_SLICE_LENGTH(bin)), NULL); gpr_slice_unref(bin); return result; }
static int zlib_body(z_stream* zs, gpr_slice_buffer* input, gpr_slice_buffer* output, int (*flate)(z_stream* zs, int flush)) { int r; int flush; size_t i; gpr_slice outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); const uInt uint_max = ~(uInt)0; GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); zs->next_out = GPR_SLICE_START_PTR(outbuf); flush = Z_NO_FLUSH; for (i = 0; i < input->count; i++) { if (i == input->count - 1) flush = Z_FINISH; GPR_ASSERT(GPR_SLICE_LENGTH(input->slices[i]) <= uint_max); zs->avail_in = (uInt)GPR_SLICE_LENGTH(input->slices[i]); zs->next_in = GPR_SLICE_START_PTR(input->slices[i]); do { if (zs->avail_out == 0) { gpr_slice_buffer_add_indexed(output, outbuf); outbuf = gpr_slice_malloc(OUTPUT_BLOCK_SIZE); GPR_ASSERT(GPR_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GPR_SLICE_LENGTH(outbuf); zs->next_out = GPR_SLICE_START_PTR(outbuf); } r = flate(zs, flush); if (r == Z_STREAM_ERROR) { gpr_log(GPR_INFO, "zlib: stream error"); goto error; } } while (zs->avail_out == 0); if (zs->avail_in) { gpr_log(GPR_INFO, "zlib: not all input consumed"); goto error; } } GPR_ASSERT(outbuf.refcount); outbuf.data.refcounted.length -= zs->avail_out; gpr_slice_buffer_add_indexed(output, outbuf); return 1; error: gpr_slice_unref(outbuf); return 0; }
gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) { gpr_slice in_slice; size_t bytes_read = 0; const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); gpr_slice out_slice = gpr_slice_malloc(input_size); uint8_t *const outbuf = GPR_SLICE_START_PTR(out_slice); /* just an alias */ while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { const size_t slice_length = GPR_SLICE_LENGTH(in_slice); memcpy(&(outbuf[bytes_read]), GPR_SLICE_START_PTR(in_slice), slice_length); bytes_read += slice_length; gpr_slice_unref(in_slice); GPR_ASSERT(bytes_read <= input_size); } return out_slice; }
void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops) { size_t i; for (i = 0; i < nops; i++) { switch (ops[i].type) { case GRPC_OP_SLICE: gpr_slice_unref(ops[i].data.slice); break; case GRPC_OP_METADATA: grpc_metadata_batch_destroy(&ops[i].data.metadata); break; case GRPC_NO_OP: case GRPC_OP_BEGIN_MESSAGE: break; } } }
static void corrupt_jwt_sig(char *jwt) { gpr_slice sig; char *bad_b64_sig; uint8_t *sig_bytes; char *last_dot = strrchr(jwt, '.'); GPR_ASSERT(last_dot != NULL); sig = grpc_base64_decode(last_dot + 1, 1); GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig)); sig_bytes = GPR_SLICE_START_PTR(sig); (*sig_bytes)++; /* Corrupt first byte. */ bad_b64_sig = grpc_base64_encode(GPR_SLICE_START_PTR(sig), GPR_SLICE_LENGTH(sig), 1, 0); memcpy(last_dot + 1, bad_b64_sig, strlen(bad_b64_sig)); gpr_free(bad_b64_sig); gpr_slice_unref(sig); }
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len, gpr_slice *buffer) { grpc_json *json; *buffer = grpc_base64_decode_with_len(str, len, 1); if (GPR_SLICE_IS_EMPTY(*buffer)) { gpr_log(GPR_ERROR, "Invalid base64."); return NULL; } json = grpc_json_parse_string_with_len((char *)GPR_SLICE_START_PTR(*buffer), GPR_SLICE_LENGTH(*buffer)); if (json == NULL) { gpr_slice_unref(*buffer); gpr_log(GPR_ERROR, "JSON parsing error."); } return json; }
static void test_base64_and_huffman_works(void) { grpc_mdstr *str; gpr_slice slice1; gpr_slice slice2; LOG_TEST("test_base64_and_huffman_works"); grpc_init(); str = grpc_mdstr_from_string("abcdefg"); slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str); slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice); GPR_ASSERT(0 == gpr_slice_cmp(slice1, slice2)); gpr_slice_unref(slice2); GRPC_MDSTR_UNREF(str); grpc_shutdown(); }
/* * Copies data from recv_message to a buffer. Fatal error occurs if * buffer is too small. */ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer( const grpcsharp_batch_context *ctx, char *buffer, size_t buffer_len) { grpc_byte_buffer_reader reader; gpr_slice slice; size_t offset = 0; grpc_byte_buffer_reader_init(&reader, ctx->recv_message); while (grpc_byte_buffer_reader_next(&reader, &slice)) { size_t len = GPR_SLICE_LENGTH(slice); GPR_ASSERT(offset + len <= buffer_len); memcpy(buffer + offset, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)); offset += len; gpr_slice_unref(slice); } }
static void channel_op(grpc_channel_element *elem, grpc_channel_element *from_elem, grpc_channel_op *op) { switch (op->type) { case GRPC_ACCEPT_CALL: gpr_log(GPR_ERROR, "Client cannot accept new calls"); break; case GRPC_TRANSPORT_CLOSED: grpc_client_channel_closed(elem); break; case GRPC_TRANSPORT_GOAWAY: gpr_slice_unref(op->data.goaway.message); break; default: GPR_ASSERT(op->dir == GRPC_CALL_DOWN); grpc_channel_next_op(elem, op); } }
size_t count_and_unref_slices(gpr_slice *slices, size_t nslices, int *current_data) { size_t num_bytes = 0; size_t i; size_t j; unsigned char *buf; for (i = 0; i < nslices; ++i) { buf = GPR_SLICE_START_PTR(slices[i]); for (j = 0; j < GPR_SLICE_LENGTH(slices[i]); ++j) { GPR_ASSERT(buf[j] == *current_data); *current_data = (*current_data + 1) % 256; } num_bytes += GPR_SLICE_LENGTH(slices[i]); gpr_slice_unref(slices[i]); } return num_bytes; }
void pygrpc_byte_buffer_to_bytes( grpc_byte_buffer *buffer, char **result, size_t *result_size) { grpc_byte_buffer_reader reader; gpr_slice slice; char *read_result = NULL; size_t size = 0; grpc_byte_buffer_reader_init(&reader, buffer); while (grpc_byte_buffer_reader_next(&reader, &slice)) { read_result = gpr_realloc(read_result, size + GPR_SLICE_LENGTH(slice)); memcpy(read_result + size, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)); size = size + GPR_SLICE_LENGTH(slice); gpr_slice_unref(slice); } *result_size = size; *result = read_result; }
static grpc_resolver *sockaddr_create(grpc_resolver_args *args, int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) { if (0 != strcmp(args->uri->authority, "")) { gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme", args->uri->scheme); return NULL; } /* Construct addresses. */ gpr_slice path_slice = gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); gpr_slice_buffer path_parts; gpr_slice_buffer_init(&path_parts); gpr_slice_split(path_slice, ",", &path_parts); grpc_lb_addresses *addresses = grpc_lb_addresses_create(path_parts.count); bool errors_found = false; for (size_t i = 0; i < addresses->num_addresses; i++) { grpc_uri ith_uri = *args->uri; char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII); ith_uri.path = part_str; if (!parse( &ith_uri, (struct sockaddr_storage *)(&addresses->addresses[i].address.addr), &addresses->addresses[i].address.len)) { errors_found = true; } gpr_free(part_str); if (errors_found) break; } gpr_slice_buffer_destroy(&path_parts); gpr_slice_unref(path_slice); if (errors_found) { grpc_lb_addresses_destroy(addresses, NULL /* user_data_destroy */); return NULL; } /* Instantiate resolver. */ sockaddr_resolver *r = gpr_malloc(sizeof(sockaddr_resolver)); memset(r, 0, sizeof(*r)); r->target_name = gpr_strdup(args->uri->path); r->addresses = addresses; gpr_mu_init(&r->mu); grpc_resolver_init(&r->base, &sockaddr_resolver_vtable); return &r->base; }
static void test_full_range_encode_decode_b64(int url_safe, int multiline) { unsigned char orig[256]; size_t i; char *b64; gpr_slice orig_decoded; for (i = 0; i < sizeof(orig); i++) orig[i] = (char)i; /* Try all the different paddings. */ for (i = 0; i < 3; i++) { b64 = grpc_base64_encode(orig, sizeof(orig) - i, url_safe, multiline); orig_decoded = grpc_base64_decode(b64, url_safe); GPR_ASSERT(GPR_SLICE_LENGTH(orig_decoded) == (sizeof(orig) - i)); GPR_ASSERT(buffers_are_equal(orig, GPR_SLICE_START_PTR(orig_decoded), sizeof(orig) - i)); gpr_slice_unref(orig_decoded); gpr_free(b64); } }
static void shutdown_during_write_test_read_handler( void *user_data, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status error) { size_t i; shutdown_during_write_test_state *st = user_data; for (i = 0; i < nslices; i++) { gpr_slice_unref(slices[i]); } if (error != GRPC_ENDPOINT_CB_OK) { grpc_endpoint_destroy(st->ep); gpr_event_set(&st->ev, (void *)(gpr_intptr) error); } else { grpc_endpoint_notify_on_read( st->ep, shutdown_during_write_test_read_handler, user_data); } }
static void finish(grpc_exec_ctx *exec_ctx, internal_request *req, int success) { grpc_pollset_set_del_pollset(exec_ctx, &req->context->pollset_set, req->pollset); req->on_response(exec_ctx, req->user_data, success ? &req->parser.r : NULL); grpc_httpcli_parser_destroy(&req->parser); if (req->addresses != NULL) { grpc_resolved_addresses_destroy(req->addresses); } if (req->ep != NULL) { grpc_endpoint_destroy(exec_ctx, req->ep); } gpr_slice_unref(req->request_text); gpr_free(req->host); gpr_free(req->ssl_host_override); grpc_iomgr_unregister_object(&req->iomgr_obj); gpr_slice_buffer_destroy(&req->incoming); gpr_slice_buffer_destroy(&req->outgoing); gpr_free(req); }
static void test_load_failure(void) { FILE *tmp = NULL; gpr_slice slice; int success; char *tmp_name; LOG_TEST_NAME(); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(tmp != NULL); fclose(tmp); remove(tmp_name); slice = gpr_load_file(tmp_name, &success); GPR_ASSERT(success == 0); GPR_ASSERT(GPR_SLICE_LENGTH(slice) == 0); gpr_free(tmp_name); gpr_slice_unref(slice); }
static void shutdown_during_write_test_read_handler( void *user_data, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status error) { size_t i; shutdown_during_write_test_state *st = user_data; for (i = 0; i < nslices; i++) { gpr_slice_unref(slices[i]); } if (error != GRPC_ENDPOINT_CB_OK) { grpc_endpoint_destroy(st->ep); gpr_mu_lock(GRPC_POLLSET_MU(g_pollset)); st->done = error; grpc_pollset_kick(g_pollset); gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset)); } else { grpc_endpoint_notify_on_read( st->ep, shutdown_during_write_test_read_handler, user_data); } }
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len, char **scratchpad) { char *b64; char *decoded; grpc_json *json; gpr_slice slice; b64 = gpr_malloc(len + 1); strncpy(b64, str, len); b64[len] = '\0'; slice = grpc_base64_decode(b64, 1); GPR_ASSERT(!GPR_SLICE_IS_EMPTY(slice)); decoded = gpr_malloc(GPR_SLICE_LENGTH(slice) + 1); strncpy(decoded, (const char *)GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)); decoded[GPR_SLICE_LENGTH(slice)] = '\0'; json = grpc_json_parse_string(decoded); gpr_free(b64); *scratchpad = decoded; gpr_slice_unref(slice); return json; }
void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops) { size_t i; for (i = 0; i < nops; i++) { switch (ops[i].type) { case GRPC_OP_SLICE: gpr_slice_unref(ops[i].data.slice); break; case GRPC_OP_METADATA: grpc_mdelem_unref(ops[i].data.metadata); break; case GRPC_OP_FLOW_CTL_CB: ops[i].data.flow_ctl_cb.cb(ops[i].data.flow_ctl_cb.arg, GRPC_OP_ERROR); break; case GRPC_NO_OP: case GRPC_OP_DEADLINE: case GRPC_OP_METADATA_BOUNDARY: case GRPC_OP_BEGIN_MESSAGE: break; } } }
static void test_decode_random_headers_inner(int max_len) { int i; test_decode_random_header_state st; gpr_slice_buffer output; gpr_slice merged; grpc_stream_op_buffer encops; grpc_chttp2_hpack_parser parser; grpc_chttp2_hpack_parser_init(&parser, g_mdctx); grpc_sopb_init(&encops); gpr_log(GPR_INFO, "max_len = %d", max_len); for (i = 0; i < 10000; i++) { randstr(st.key, max_len); randstr(st.value, max_len); add_sopb_headers(1, st.key, st.value); gpr_slice_buffer_init(&output); GPR_ASSERT(0 == grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, 0, &encops)); grpc_chttp2_encode(encops.ops, encops.nops, 0, 0xdeadbeef, &g_compressor, &output); encops.nops = 0; merged = grpc_slice_merge(output.slices, output.count); gpr_slice_buffer_destroy(&output); st.got_hdr = 0; parser.on_header = chk_hdr; parser.on_header_user_data = &st; grpc_chttp2_hpack_parser_parse(&parser, GPR_SLICE_START_PTR(merged) + 9, GPR_SLICE_END_PTR(merged)); GPR_ASSERT(st.got_hdr); gpr_slice_unref(merged); } grpc_chttp2_hpack_parser_destroy(&parser); grpc_sopb_destroy(&encops); }
void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op, grpc_status_code status, gpr_slice *optional_message) { close_message_data *cmd; GPR_ASSERT(status != GRPC_STATUS_OK); if (op->cancel_with_status != GRPC_STATUS_OK || op->close_with_status != GRPC_STATUS_OK) { if (optional_message) { gpr_slice_unref(*optional_message); } return; } if (optional_message) { cmd = gpr_malloc(sizeof(*cmd)); cmd->message = *optional_message; cmd->then_call = op->on_complete; grpc_closure_init(&cmd->closure, free_message, cmd); op->on_complete = &cmd->closure; op->optional_close_message = &cmd->message; } op->close_with_status = status; }
static void test_byte_buffer_from_reader(void) { gpr_slice slice; grpc_byte_buffer *buffer, *buffer_from_reader; grpc_byte_buffer_reader reader; LOG_TEST("test_byte_buffer_from_reader"); slice = gpr_slice_malloc(4); memcpy(GPR_SLICE_START_PTR(slice), "test", 4); buffer = grpc_raw_byte_buffer_create(&slice, 1); gpr_slice_unref(slice); grpc_byte_buffer_reader_init(&reader, buffer); buffer_from_reader = grpc_raw_byte_buffer_from_reader(&reader); GPR_ASSERT(buffer->type == buffer_from_reader->type); GPR_ASSERT(buffer_from_reader->data.raw.compression == GRPC_COMPRESS_NONE); GPR_ASSERT(buffer_from_reader->data.raw.slice_buffer.count == 1); GPR_ASSERT(memcmp(GPR_SLICE_START_PTR( buffer_from_reader->data.raw.slice_buffer.slices[0]), "test", 4) == 0); grpc_byte_buffer_destroy(buffer); grpc_byte_buffer_destroy(buffer_from_reader); }
/* Takes ownership of creds_path if not NULL. */ static grpc_call_credentials *create_default_creds_from_path(char *creds_path) { grpc_json *json = NULL; grpc_auth_json_key key; grpc_auth_refresh_token token; grpc_call_credentials *result = NULL; gpr_slice creds_data = gpr_empty_slice(); int file_ok = 0; if (creds_path == NULL) goto end; creds_data = gpr_load_file(creds_path, 0, &file_ok); if (!file_ok) goto end; json = grpc_json_parse_string_with_len( (char *)GPR_SLICE_START_PTR(creds_data), GPR_SLICE_LENGTH(creds_data)); if (json == NULL) goto end; /* First, try an auth json key. */ key = grpc_auth_json_key_create_from_json(json); if (grpc_auth_json_key_is_valid(&key)) { result = grpc_service_account_jwt_access_credentials_create_from_auth_json_key( key, grpc_max_auth_token_lifetime()); goto end; } /* Then try a refresh token if the auth json key was invalid. */ token = grpc_auth_refresh_token_create_from_json(json); if (grpc_auth_refresh_token_is_valid(&token)) { result = grpc_refresh_token_credentials_create_from_auth_refresh_token(token); goto end; } end: if (creds_path != NULL) gpr_free(creds_path); gpr_slice_unref(creds_data); if (json != NULL) grpc_json_destroy(json); return result; }
static void on_read(void *user_data, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status status) { internal_request *req = user_data; size_t i; gpr_log(GPR_DEBUG, "%s nslices=%d status=%d", __FUNCTION__, nslices, status); for (i = 0; i < nslices; i++) { if (GPR_SLICE_LENGTH(slices[i])) { req->have_read_byte = 1; if (!grpc_httpcli_parser_parse(&req->parser, slices[i])) { finish(req, 0); goto done; } } } switch (status) { case GRPC_ENDPOINT_CB_OK: grpc_endpoint_notify_on_read(req->ep, on_read, req); break; case GRPC_ENDPOINT_CB_EOF: case GRPC_ENDPOINT_CB_ERROR: case GRPC_ENDPOINT_CB_SHUTDOWN: if (!req->have_read_byte) { next_address(req); } else { finish(req, grpc_httpcli_parser_eof(&req->parser)); } break; } done: for (i = 0; i < nslices; i++) { gpr_slice_unref(slices[i]); } }
static void test_load_small_file(void) { FILE *tmp = NULL; gpr_slice slice; int success; char *tmp_name; const char *blah = "blah"; LOG_TEST_NAME(); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(tmp != NULL); GPR_ASSERT(fwrite(blah, 1, strlen(blah), tmp) == strlen(blah)); fclose(tmp); slice = gpr_load_file(tmp_name, &success); GPR_ASSERT(success == 1); GPR_ASSERT(GPR_SLICE_LENGTH(slice) == strlen(blah)); GPR_ASSERT(!memcmp(GPR_SLICE_START_PTR(slice), blah, strlen(blah))); remove(tmp_name); gpr_free(tmp_name); gpr_slice_unref(slice); }
static void check_jwt_signature(const char *b64_signature, RSA *rsa_key, const char *signed_data, size_t signed_data_size) { EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); EVP_PKEY *key = EVP_PKEY_new(); gpr_slice sig = grpc_base64_decode(b64_signature, 1); GPR_ASSERT(!GPR_SLICE_IS_EMPTY(sig)); GPR_ASSERT(GPR_SLICE_LENGTH(sig) == 128); GPR_ASSERT(md_ctx != NULL); GPR_ASSERT(key != NULL); EVP_PKEY_set1_RSA(key, rsa_key); GPR_ASSERT(EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, key) == 1); GPR_ASSERT(EVP_DigestVerifyUpdate(md_ctx, signed_data, signed_data_size) == 1); GPR_ASSERT(EVP_DigestVerifyFinal(md_ctx, GPR_SLICE_START_PTR(sig), GPR_SLICE_LENGTH(sig)) == 1); gpr_slice_unref(sig); if (key != NULL) EVP_PKEY_free(key); if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); }
static int zlib_decompress(gpr_slice_buffer* input, gpr_slice_buffer* output, int gzip) { z_stream zs; int r; size_t i; size_t count_before = output->count; size_t length_before = output->length; memset(&zs, 0, sizeof(zs)); r = inflateInit2(&zs, 15 | (gzip ? 16 : 0)); if (r != Z_OK) { gpr_log(GPR_ERROR, "inflateInit2 returns %d", r); return 0; } r = zlib_body(&zs, input, output, inflate); if (!r) { for (i = count_before; i < output->count; i++) { gpr_slice_unref(output->slices[i]); } output->count = count_before; output->length = length_before; } inflateEnd(&zs); return r; }
static void test_format_post_request_no_body(void) { grpc_http_header hdr = {"x-yz", "abc"}; grpc_httpcli_request req; gpr_slice slice; memset(&req, 0, sizeof(req)); req.host = "example.com"; req.http.path = "/index.html"; req.http.hdr_count = 1; req.http.hdrs = &hdr; slice = grpc_httpcli_format_post_request(&req, NULL, 0); GPR_ASSERT(0 == gpr_slice_str_cmp(slice, "POST /index.html HTTP/1.0\r\n" "Host: example.com\r\n" "Connection: close\r\n" "User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n" "x-yz: abc\r\n" "\r\n")); gpr_slice_unref(slice); }
/* tcp read callback */ static void recv_data(void *tp, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status error) { grpc_chttp2_transport *t = tp; size_t i; int unref = 0; switch (error) { case GRPC_ENDPOINT_CB_SHUTDOWN: case GRPC_ENDPOINT_CB_EOF: case GRPC_ENDPOINT_CB_ERROR: lock(t); drop_connection(t); read_error_locked(t); unlock(t); unref = 1; for (i = 0; i < nslices; i++) gpr_slice_unref(slices[i]); break; case GRPC_ENDPOINT_CB_OK: lock(t); i = 0; GPR_ASSERT(!t->parsing_active); if (t->global.error_state == GRPC_CHTTP2_ERROR_STATE_NONE) { t->parsing_active = 1; /* merge stream lists */ grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); grpc_chttp2_prepare_to_read(&t->global, &t->parsing); gpr_mu_unlock(&t->mu); for (; i < nslices && grpc_chttp2_perform_read(&t->parsing, slices[i]); i++) { gpr_slice_unref(slices[i]); } gpr_mu_lock(&t->mu); if (i != nslices) { drop_connection(t); } /* merge stream lists */ grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); t->global.concurrent_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map); if (t->parsing.initial_window_update != 0) { grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, update_global_window, t); } /* handle higher level things */ grpc_chttp2_publish_reads(&t->global, &t->parsing); t->parsing_active = 0; } if (i == nslices) { grpc_chttp2_schedule_closure(&t->global, &t->reading_action, 1); } else { read_error_locked(t); unref = 1; } unlock(t); for (; i < nslices; i++) gpr_slice_unref(slices[i]); break; } if (unref) { UNREF_TRANSPORT(t, "recv_data"); } }
static void test_invoke_large_request(grpc_end2end_test_config config) { grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); gpr_slice request_payload_slice = large_slice(); gpr_slice response_payload_slice = large_slice(); grpc_call *c; grpc_call *s; grpc_byte_buffer *request_payload = grpc_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer *response_payload = grpc_byte_buffer_create(&response_payload_slice, 1); gpr_timespec deadline = n_seconds_time(30); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_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_byte_buffer *request_payload_recv = NULL; grpc_byte_buffer *response_payload_recv = NULL; grpc_call_details call_details; grpc_status_code status; char *details = NULL; size_t details_capacity = 0; int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); 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); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = request_payload; op++; op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; op++; op->op = GRPC_OP_RECV_INITIAL_METADATA; op->data.recv_initial_metadata = &initial_metadata_recv; op++; op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &response_payload_recv; 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->data.recv_status_on_client.status_details_capacity = &details_capacity; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1))); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; 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_UNIMPLEMENTED; op->data.send_status_from_server.status_details = "xyz"; op++; op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &request_payload_recv; op++; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->data.recv_close_on_server.cancelled = &was_cancelled; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); cq_expect_completion(v_server, tag(102), GRPC_OP_OK); cq_verify(v_server); cq_expect_completion(v_client, tag(1), GRPC_OP_OK); cq_verify(v_client); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); gpr_free(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_destroy(c); grpc_call_destroy(s); cq_verifier_destroy(v_client); cq_verifier_destroy(v_server); grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(response_payload); grpc_byte_buffer_destroy(request_payload_recv); grpc_byte_buffer_destroy(response_payload_recv); gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); end_test(&f); config.tear_down_data(&f); }