static void test_load_empty_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_slice slice_with_null_term; grpc_error *error; char *tmp_name; LOG_TEST_NAME("test_load_empty_file"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(tmp != NULL); fclose(tmp); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == 0); error = grpc_load_file(tmp_name, 1, &slice_with_null_term); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == 1); GPR_ASSERT(GRPC_SLICE_START_PTR(slice_with_null_term)[0] == 0); remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); grpc_slice_unref(slice_with_null_term); }
static void test_vector(grpc_chttp2_hpack_parser *parser, grpc_slice_split_mode mode, const char *hexstring, ... /* char *key, char *value */) { grpc_slice input = parse_hexstring(hexstring); grpc_slice *slices; size_t nslices; size_t i; test_checker chk; va_start(chk.args, hexstring); parser->on_header = onhdr; parser->on_header_user_data = &chk; grpc_split_slices(mode, &input, 1, &slices, &nslices); grpc_slice_unref(input); for (i = 0; i < nslices; i++) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GPR_ASSERT(grpc_chttp2_hpack_parser_parse(&exec_ctx, parser, slices[i]) == GRPC_ERROR_NONE); grpc_exec_ctx_finish(&exec_ctx); } for (i = 0; i < nslices; i++) { grpc_slice_unref(slices[i]); } gpr_free(slices); GPR_ASSERT(NULL == va_arg(chk.args, char *)); va_end(chk.args); }
/* Create a call given a grpc_channel, in order to call method. The request is not sent until grpc_call_invoke is called. */ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask, VALUE method, VALUE host, VALUE deadline) { VALUE res = Qnil; grpc_rb_channel *wrapper = NULL; grpc_call *call = NULL; grpc_call *parent_call = NULL; grpc_completion_queue *cq = NULL; int flags = GRPC_PROPAGATE_DEFAULTS; grpc_slice method_slice; grpc_slice host_slice; grpc_slice *host_slice_ptr = NULL; char *tmp_str = NULL; if (host != Qnil) { host_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host)); host_slice_ptr = &host_slice; } if (mask != Qnil) { flags = NUM2UINT(mask); } if (parent != Qnil) { parent_call = grpc_rb_get_wrapped_call(parent); } cq = grpc_completion_queue_create_for_pluck(NULL); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper); if (wrapper->bg_wrapped == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; } method_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(method), RSTRING_LEN(method)); call = grpc_channel_create_call(wrapper->bg_wrapped->channel, parent_call, flags, cq, method_slice, host_slice_ptr, grpc_rb_time_timeval(deadline, /* absolute time */ 0), NULL); if (call == NULL) { tmp_str = grpc_slice_to_c_string(method_slice); rb_raise(rb_eRuntimeError, "cannot create call with method %s", tmp_str); return Qnil; } grpc_slice_unref(method_slice); if (host_slice_ptr != NULL) { grpc_slice_unref(host_slice); } res = grpc_rb_wrap_call(call, cq); /* Make this channel an instance attribute of the call so that it is not GCed * before the call. */ rb_ivar_set(res, id_channel, self); return res; }
/* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly * cleaned up */ static void grpc_run_batch_stack_cleanup(run_batch_stack *st) { size_t i = 0; grpc_metadata_array_destroy(&st->send_metadata); grpc_metadata_array_destroy(&st->send_trailing_metadata); grpc_metadata_array_destroy(&st->recv_metadata); grpc_metadata_array_destroy(&st->recv_trailing_metadata); if (GRPC_SLICE_START_PTR(st->send_status_details) != NULL) { grpc_slice_unref(st->send_status_details); } if (GRPC_SLICE_START_PTR(st->recv_status_details) != NULL) { grpc_slice_unref(st->recv_status_details); } if (st->recv_message != NULL) { grpc_byte_buffer_destroy(st->recv_message); } for (i = 0; i < st->op_num; i++) { if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) { grpc_byte_buffer_destroy(st->ops[i].data.send_message.send_message); } } }
static void test_load_small_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_slice slice_with_null_term; grpc_error *error; char *tmp_name; const char *blah = "blah"; LOG_TEST_NAME("test_load_small_file"); 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); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == strlen(blah)); GPR_ASSERT(!memcmp(GRPC_SLICE_START_PTR(slice), blah, strlen(blah))); error = grpc_load_file(tmp_name, 1, &slice_with_null_term); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == (strlen(blah) + 1)); GPR_ASSERT(strcmp((const char *)GRPC_SLICE_START_PTR(slice_with_null_term), blah) == 0); remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); grpc_slice_unref(slice_with_null_term); }
/* Asynchronous callback from the IOCP, or the background thread. */ static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) { grpc_tcp *tcp = tcpp; grpc_closure *cb = tcp->read_cb; grpc_winsocket *socket = tcp->socket; grpc_slice sub; grpc_winsocket_callback_info *info = &socket->read_info; GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { if (info->wsa_error != 0 && !tcp->shutting_down) { char *utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE(utf8_message); gpr_free(utf8_message); grpc_slice_unref(tcp->read_slice); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); grpc_slice_buffer_add(tcp->read_slices, sub); } else { grpc_slice_unref(tcp->read_slice); error = GRPC_ERROR_CREATE("End of TCP stream"); } } } tcp->read_cb = NULL; TCP_UNREF(exec_ctx, tcp, "read"); grpc_exec_ctx_sched(exec_ctx, cb, error, NULL); }
/* verify that the output generated by encoding the stream matches the hexstring passed in */ static void verify(size_t window_available, int eof, size_t expect_window_used, const char *expected, size_t nheaders, ...) { grpc_slice_buffer output; grpc_slice merged; grpc_slice expect = parse_hexstring(expected); size_t i; va_list l; grpc_linked_mdelem *e = gpr_malloc(sizeof(*e) * nheaders); grpc_metadata_batch b; grpc_metadata_batch_init(&b); va_start(l, nheaders); for (i = 0; i < nheaders; i++) { char *key = va_arg(l, char *); char *value = va_arg(l, char *); if (i) { e[i - 1].next = &e[i]; e[i].prev = &e[i - 1]; } e[i].md = grpc_mdelem_from_strings(key, value); } e[0].prev = NULL; e[nheaders - 1].next = NULL; va_end(l); b.list.head = &e[0]; b.list.tail = &e[nheaders - 1]; if (cap_to_delete == num_to_delete) { cap_to_delete = GPR_MAX(2 * cap_to_delete, 1000); to_delete = gpr_realloc(to_delete, sizeof(*to_delete) * cap_to_delete); } to_delete[num_to_delete++] = e; grpc_slice_buffer_init(&output); grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats, &output); merged = grpc_slice_merge(output.slices, output.count); grpc_slice_buffer_destroy(&output); grpc_metadata_batch_destroy(&b); if (0 != grpc_slice_cmp(merged, expect)) { char *expect_str = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *got_str = grpc_dump_slice(merged, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "mismatched output for %s", expected); gpr_log(GPR_ERROR, "EXPECT: %s", expect_str); gpr_log(GPR_ERROR, "GOT: %s", got_str); gpr_free(expect_str); gpr_free(got_str); g_failure = 1; } grpc_slice_unref(merged); grpc_slice_unref(expect); }
/* * Destroys keys, values and array->metadata. * The array pointer itself is not freed. */ void grpcsharp_metadata_array_destroy_metadata_including_entries( grpc_metadata_array* array) { size_t i; if (array->metadata) { for (i = 0; i < array->count; i++) { grpc_slice_unref(array->metadata[i].key); grpc_slice_unref(array->metadata[i].value); } } gpr_free(array->metadata); }
void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) { if (ctx->audience != NULL) gpr_free(ctx->audience); if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims); grpc_slice_unref(ctx->signature); grpc_slice_unref(ctx->signed_data); jose_header_destroy(ctx->header); for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) { grpc_http_response_destroy(&ctx->responses[i]); } /* TODO: see what to do with claims... */ gpr_free(ctx); }
static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) { secure_endpoint *ep = secure_ep; grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep); tsi_frame_protector_destroy(ep->protector); grpc_slice_buffer_destroy(&ep->leftover_bytes); grpc_slice_unref(ep->read_staging_buffer); grpc_slice_unref(ep->write_staging_buffer); grpc_slice_buffer_destroy(&ep->output_buffer); grpc_slice_buffer_destroy(&ep->source_buffer); gpr_mu_destroy(&ep->protector_mu); gpr_free(ep); }
static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug, int line) { if (0 != grpc_slice_cmp(slice, expected)) { char *hs = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *he = grpc_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "FAILED:%d: %s\ngot: %s\nwant: %s", line, debug, hs, he); gpr_free(hs); gpr_free(he); all_ok = 0; } grpc_slice_unref(expected); grpc_slice_unref(slice); }
static void test_varint(uint32_t value, uint32_t prefix_bits, uint8_t prefix_or, const char *expect_bytes, size_t expect_length) { uint32_t nbytes = GRPC_CHTTP2_VARINT_LENGTH(value, prefix_bits); grpc_slice expect = grpc_slice_from_copied_buffer(expect_bytes, expect_length); grpc_slice slice; gpr_log(GPR_DEBUG, "Test: 0x%08x", value); GPR_ASSERT(nbytes == expect_length); slice = grpc_slice_malloc(nbytes); GRPC_CHTTP2_WRITE_VARINT(value, prefix_bits, prefix_or, GRPC_SLICE_START_PTR(slice), nbytes); GPR_ASSERT(grpc_slice_cmp(expect, slice) == 0); grpc_slice_unref(expect); grpc_slice_unref(slice); }
void create_jwt(const char *json_key_file_path, const char *service_url, const char *scope) { grpc_auth_json_key key; char *jwt; grpc_slice json_key_data; GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_key_file_path, 1, &json_key_data))); key = grpc_auth_json_key_create_from_string( (const char *)GRPC_SLICE_START_PTR(json_key_data)); grpc_slice_unref(json_key_data); if (!grpc_auth_json_key_is_valid(&key)) { fprintf(stderr, "Could not parse json key.\n"); exit(1); } jwt = grpc_jwt_encode_and_sign( &key, service_url == NULL ? GRPC_JWT_OAUTH2_AUDIENCE : service_url, grpc_max_auth_token_lifetime(), scope); grpc_auth_json_key_destruct(&key); if (jwt == NULL) { fprintf(stderr, "Could not create JWT.\n"); exit(1); } fprintf(stdout, "%s\n", jwt); gpr_free(jwt); }
static void expect_slice_dump(grpc_slice slice, uint32_t flags, const char *result) { char *got = grpc_dump_slice(slice, flags); GPR_ASSERT(0 == strcmp(got, result)); gpr_free(got); grpc_slice_unref(slice); }
/* Gets the internal value of a compression algorithm suitable as the value * in a GRPC core channel arguments hash. * algorithm_value is an out parameter. * Raises an error if the name of the algorithm passed in is invalid. */ void grpc_rb_compression_options_algorithm_name_to_value_internal( grpc_compression_algorithm* algorithm_value, VALUE algorithm_name) { grpc_slice name_slice; VALUE algorithm_name_as_string = Qnil; Check_Type(algorithm_name, T_SYMBOL); /* Convert the algorithm symbol to a ruby string, so that we can get the * correct C string out of it. */ algorithm_name_as_string = rb_funcall(algorithm_name, rb_intern("to_s"), 0); name_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(algorithm_name_as_string), RSTRING_LEN(algorithm_name_as_string)); /* Raise an error if the name isn't recognized as a compression algorithm by * the algorithm parse function * in GRPC core. */ if (!grpc_compression_algorithm_parse(name_slice, algorithm_value)) { char* name_slice_str = grpc_slice_to_c_string(name_slice); char* error_message_str = NULL; VALUE error_message_ruby_str = Qnil; GPR_ASSERT(gpr_asprintf(&error_message_str, "Invalid compression algorithm name: %s", name_slice_str) != -1); gpr_free(name_slice_str); error_message_ruby_str = rb_str_new(error_message_str, strlen(error_message_str)); gpr_free(error_message_str); rb_raise(rb_eNameError, "%s", StringValueCStr(error_message_ruby_str)); } grpc_slice_unref(name_slice); }
static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) { grpc_endpoint_test_fixture f = config.create_fixture(slice_size); grpc_slice_buffer incoming; grpc_slice s = grpc_slice_from_copied_string("hello world 12345678900987654321"); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; int n = 0; grpc_closure done_closure; gpr_log(GPR_INFO, "Start test left over"); grpc_slice_buffer_init(&incoming); grpc_closure_init(&done_closure, inc_call_ctr, &n); grpc_endpoint_read(&exec_ctx, f.client_ep, &incoming, &done_closure); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT(n == 1); GPR_ASSERT(incoming.count == 1); GPR_ASSERT(0 == grpc_slice_cmp(s, incoming.slices[0])); grpc_endpoint_shutdown(&exec_ctx, f.client_ep); grpc_endpoint_shutdown(&exec_ctx, f.server_ep); grpc_endpoint_destroy(&exec_ctx, f.client_ep); grpc_endpoint_destroy(&exec_ctx, f.server_ep); grpc_exec_ctx_finish(&exec_ctx); grpc_slice_unref(s); grpc_slice_buffer_destroy(&incoming); clean_up(); }
static void test_load_big_file(void) { FILE *tmp = NULL; grpc_slice slice; grpc_error *error; char *tmp_name; static const size_t buffer_size = 124631; unsigned char *buffer = gpr_malloc(buffer_size); unsigned char *current; size_t i; LOG_TEST_NAME("test_load_big_file"); memset(buffer, 42, buffer_size); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp != NULL); GPR_ASSERT(tmp_name != NULL); GPR_ASSERT(fwrite(buffer, 1, buffer_size, tmp) == buffer_size); fclose(tmp); error = grpc_load_file(tmp_name, 0, &slice); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == buffer_size); current = GRPC_SLICE_START_PTR(slice); for (i = 0; i < buffer_size; i++) { GPR_ASSERT(current[i] == 42); } remove(tmp_name); gpr_free(tmp_name); grpc_slice_unref(slice); gpr_free(buffer); }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (squelch) gpr_set_log_function(dont_log); grpc_slice slice = grpc_slice_from_copied_buffer((const char *)data, size); grpc_grpclb_serverlist *serverlist; if ((serverlist = grpc_grpclb_response_parse_serverlist(slice))) { grpc_grpclb_destroy_serverlist(serverlist); } grpc_slice_unref(slice); return 0; }
static void check_values(const test_entry* input, size_t num_entries, grpc_slice_hash_table* table) { for (size_t i = 0; i < num_entries; ++i) { grpc_slice key = grpc_slice_from_static_string(input[i].key); char* actual = grpc_slice_hash_table_get(table, key); GPR_ASSERT(actual != NULL); GPR_ASSERT(strcmp(actual, input[i].value) == 0); grpc_slice_unref(key); } }
GPR_EXPORT grpc_call* GPR_CALLTYPE grpcsharp_channel_create_call( grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask, grpc_completion_queue* cq, const char* method, const char* host, gpr_timespec deadline) { grpc_slice method_slice = grpc_slice_from_copied_string(method); grpc_slice* host_slice_ptr = NULL; grpc_slice host_slice; if (host != NULL) { host_slice = grpc_slice_from_copied_string(host); host_slice_ptr = &host_slice; } grpc_call* ret = grpc_channel_create_call(channel, parent_call, propagation_mask, cq, method_slice, host_slice_ptr, deadline, NULL); grpc_slice_unref(method_slice); if (host != NULL) { grpc_slice_unref(host_slice); } return ret; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { struct grpc_memory_counters counters; grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer((const char *)data, size); grpc_slice output; if (grpc_strict_percent_decode_slice( input, grpc_url_percent_encoding_unreserved_bytes, &output)) { grpc_slice_unref(output); } if (grpc_strict_percent_decode_slice( input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { grpc_slice_unref(output); } grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); grpc_slice_unref(input); counters = grpc_memory_counters_snapshot(); grpc_memory_counters_destroy(); GPR_ASSERT(counters.total_size_relative == 0); return 0; }
static void expect_combined_equiv(const char *s, size_t len, int line) { grpc_slice input = grpc_slice_from_copied_buffer(s, len); grpc_slice base64 = grpc_chttp2_base64_encode(input); grpc_slice expect = grpc_chttp2_huffman_compress(base64); grpc_slice got = grpc_chttp2_base64_encode_and_huffman_compress_impl(input); if (0 != grpc_slice_cmp(expect, got)) { char *t = grpc_dump_slice(input, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *e = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII); char *g = grpc_dump_slice(got, GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "FAILED:%d:\ntest: %s\ngot: %s\nwant: %s", line, t, g, e); gpr_free(t); gpr_free(e); gpr_free(g); all_ok = 0; } grpc_slice_unref(input); grpc_slice_unref(base64); grpc_slice_unref(expect); grpc_slice_unref(got); }
static BIGNUM *bignum_from_base64(const char *b64) { BIGNUM *result = NULL; grpc_slice bin; if (b64 == NULL) return NULL; bin = grpc_base64_decode(b64, 1); if (GRPC_SLICE_IS_EMPTY(bin)) { gpr_log(GPR_ERROR, "Invalid base64 for big num."); return NULL; } result = BN_bin2bn(GRPC_SLICE_START_PTR(bin), TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL); grpc_slice_unref(bin); return result; }
static int zlib_body(z_stream* zs, grpc_slice_buffer* input, grpc_slice_buffer* output, int (*flate)(z_stream* zs, int flush)) { int r; int flush; size_t i; grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); const uInt uint_max = ~(uInt)0; GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_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(GRPC_SLICE_LENGTH(input->slices[i]) <= uint_max); zs->avail_in = (uInt)GRPC_SLICE_LENGTH(input->slices[i]); zs->next_in = GRPC_SLICE_START_PTR(input->slices[i]); do { if (zs->avail_out == 0) { grpc_slice_buffer_add_indexed(output, outbuf); outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE); GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max); zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf); zs->next_out = GRPC_SLICE_START_PTR(outbuf); } r = flate(zs, flush); if (r < 0 && r != Z_BUF_ERROR /* not fatal */) { gpr_log(GPR_INFO, "zlib error (%d)", r); 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; grpc_slice_buffer_add_indexed(output, outbuf); return 1; error: grpc_slice_unref(outbuf); return 0; }
grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) { grpc_slice in_slice; size_t bytes_read = 0; const size_t input_size = grpc_byte_buffer_length(reader->buffer_out); grpc_slice out_slice = grpc_slice_malloc(input_size); uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */ while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) { const size_t slice_length = GRPC_SLICE_LENGTH(in_slice); memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length); bytes_read += slice_length; grpc_slice_unref(in_slice); GPR_ASSERT(bytes_read <= input_size); } return out_slice; }
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len, grpc_slice *buffer) { grpc_json *json; *buffer = grpc_base64_decode_with_len(str, len, 1); if (GRPC_SLICE_IS_EMPTY(*buffer)) { gpr_log(GPR_ERROR, "Invalid base64."); return NULL; } json = grpc_json_parse_string_with_len((char *)GRPC_SLICE_START_PTR(*buffer), GRPC_SLICE_LENGTH(*buffer)); if (json == NULL) { grpc_slice_unref(*buffer); gpr_log(GPR_ERROR, "JSON parsing error."); } return json; }
static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) { client_recv_filter_args *a = user_data; if (md == GRPC_MDELEM_STATUS_200) { return NULL; } else if (md->key == GRPC_MDSTR_STATUS) { char *message_string; gpr_asprintf(&message_string, "Received http2 header with status: %s", grpc_mdstr_as_c_string(md->value)); grpc_slice message = grpc_slice_from_copied_string(message_string); gpr_free(message_string); grpc_call_element_send_close_with_message(a->exec_ctx, a->elem, GRPC_STATUS_CANCELLED, &message); return NULL; } else if (md->key == GRPC_MDSTR_GRPC_MESSAGE) { grpc_slice pct_decoded_msg = grpc_permissive_percent_decode_slice(md->value->slice); if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) { grpc_slice_unref(pct_decoded_msg); return md; } else { return grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_MESSAGE, grpc_mdstr_from_slice(pct_decoded_msg)); } } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { return NULL; } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { const char *value_str = grpc_mdstr_as_c_string(md->value); if (strncmp(value_str, EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) == 0 && (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) { /* Although the C implementation doesn't (currently) generate them, any custom +-suffix is explicitly valid. */ /* TODO(klempner): We should consider preallocating common values such as +proto or +json, or at least stashing them if we see them. */ /* TODO(klempner): Should we be surfacing this to application code? */ } else { /* TODO(klempner): We're currently allowing this, but we shouldn't see it without a proxy so log for now. */ gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str); } return NULL; } return md; }
void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, size_t *out_length) { grpc_byte_buffer_reader reader; if (buffer == NULL || !grpc_byte_buffer_reader_init(&reader, buffer)) { /* TODO(dgq): distinguish between the error cases. */ *out_string = NULL; *out_length = 0; return; } grpc_slice slice = grpc_byte_buffer_reader_readall(&reader); size_t length = GRPC_SLICE_LENGTH(slice); char *string = ecalloc(length + 1, sizeof(char)); memcpy(string, GRPC_SLICE_START_PTR(slice), length); grpc_slice_unref(slice); *out_string = string; *out_length = length; }
static void parse_query_parts(grpc_uri *uri) { static const char *QUERY_PARTS_SEPARATOR = "&"; static const char *QUERY_PARTS_VALUE_SEPARATOR = "="; GPR_ASSERT(uri->query != NULL); if (uri->query[0] == '\0') { uri->query_parts = NULL; uri->query_parts_values = NULL; uri->num_query_parts = 0; return; } grpc_slice query_slice = grpc_slice_new(uri->query, strlen(uri->query), do_nothing); grpc_slice_buffer query_parts; /* the &-separated elements of the query */ grpc_slice_buffer query_param_parts; /* the =-separated subelements */ grpc_slice_buffer_init(&query_parts); grpc_slice_buffer_init(&query_param_parts); grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts); uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *)); uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *)); uri->num_query_parts = query_parts.count; for (size_t i = 0; i < query_parts.count; i++) { grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts); GPR_ASSERT(query_param_parts.count > 0); uri->query_parts[i] = grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII); if (query_param_parts.count > 1) { /* TODO(dgq): only the first value after the separator is considered. * Perhaps all chars after the first separator for the query part should * be included, even if they include the separator. */ uri->query_parts_values[i] = grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII); } else { uri->query_parts_values[i] = NULL; } grpc_slice_buffer_reset_and_unref(&query_param_parts); } grpc_slice_buffer_destroy(&query_parts); grpc_slice_buffer_destroy(&query_param_parts); grpc_slice_unref(query_slice); }
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server( grpc_call* call, grpcsharp_batch_context* ctx, grpc_status_code status_code, const char* status_details, size_t status_details_len, grpc_metadata_array* trailing_metadata, int32_t send_empty_initial_metadata, const char* optional_send_buffer, size_t optional_send_buffer_len, uint32_t write_flags) { /* TODO: don't use magic number */ grpc_op ops[3]; memset(ops, 0, sizeof(ops)); size_t nops = 1; grpc_slice status_details_slice = grpc_slice_from_copied_buffer(status_details, status_details_len); ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER; ops[0].data.send_status_from_server.status = status_code; ops[0].data.send_status_from_server.status_details = &status_details_slice; grpcsharp_metadata_array_move( &(ctx->send_status_from_server.trailing_metadata), trailing_metadata); ops[0].data.send_status_from_server.trailing_metadata_count = ctx->send_status_from_server.trailing_metadata.count; ops[0].data.send_status_from_server.trailing_metadata = ctx->send_status_from_server.trailing_metadata.metadata; ops[0].flags = 0; ops[0].reserved = NULL; if (optional_send_buffer) { ops[nops].op = GRPC_OP_SEND_MESSAGE; ctx->send_message = string_to_byte_buffer(optional_send_buffer, optional_send_buffer_len); ops[nops].data.send_message.send_message = ctx->send_message; ops[nops].flags = write_flags; ops[nops].reserved = NULL; nops++; } if (send_empty_initial_metadata) { ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA; ops[nops].flags = 0; ops[nops].reserved = NULL; nops++; } grpc_call_error ret = grpcsharp_call_start_batch(call, ops, nops, ctx, NULL); grpc_slice_unref(status_details_slice); return ret; }