static void test_create_many_persistant_metadata(void) { grpc_mdctx *ctx; char buffer[GPR_LTOA_MIN_BUFSIZE]; long i; grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY); grpc_mdelem *md; LOG_TEST("test_create_many_persistant_metadata"); ctx = grpc_mdctx_create(); /* add phase */ for (i = 0; i < MANY; i++) { gpr_ltoa(i, buffer); created[i] = grpc_mdelem_from_strings(ctx, "a", buffer); } /* verify phase */ for (i = 0; i < MANY; i++) { gpr_ltoa(i, buffer); md = grpc_mdelem_from_strings(ctx, "a", buffer); GPR_ASSERT(md == created[i]); GRPC_MDELEM_UNREF(md); } /* cleanup phase */ for (i = 0; i < MANY; i++) { GRPC_MDELEM_UNREF(created[i]); } grpc_mdctx_unref(ctx); gpr_free(created); }
static void handle_op_after_cancellation(grpc_call_element *elem, grpc_transport_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; if (op->send_ops) { grpc_stream_ops_unref_owned_objects(op->send_ops->ops, op->send_ops->nops); op->on_done_send(op->send_user_data, 0); } if (op->recv_ops) { char status[GPR_LTOA_MIN_BUFSIZE]; grpc_metadata_batch mdb; gpr_ltoa(GRPC_STATUS_CANCELLED, status); calld->s.cancelled.status.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-status", status); calld->s.cancelled.details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message", "Cancelled"); calld->s.cancelled.status.prev = calld->s.cancelled.details.next = NULL; calld->s.cancelled.status.next = &calld->s.cancelled.details; calld->s.cancelled.details.prev = &calld->s.cancelled.status; mdb.list.head = &calld->s.cancelled.status; mdb.list.tail = &calld->s.cancelled.details; mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = gpr_inf_future; grpc_sopb_add_metadata(op->recv_ops, mdb); *op->recv_state = GRPC_STREAM_CLOSED; op->on_done_recv(op->recv_user_data, 1); } }
static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; GRPC_CALL_LOG_OP(GPR_INFO, elem, op); if (op->send_ops != NULL) { grpc_stream_ops_unref_owned_objects(op->send_ops->ops, op->send_ops->nops); op->on_done_send->cb(exec_ctx, op->on_done_send->cb_arg, 0); } if (op->recv_ops != NULL) { char tmp[GPR_LTOA_MIN_BUFSIZE]; grpc_metadata_batch mdb; gpr_ltoa(chand->error_code, tmp); calld->status.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-status", tmp); calld->details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message", chand->error_message); calld->status.prev = calld->details.next = NULL; calld->status.next = &calld->details; calld->details.prev = &calld->status; mdb.list.head = &calld->status; mdb.list.tail = &calld->details; mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = gpr_inf_future(GPR_CLOCK_REALTIME); grpc_sopb_add_metadata(op->recv_ops, mdb); *op->recv_state = GRPC_STREAM_CLOSED; op->on_done_recv->cb(exec_ctx, op->on_done_recv->cb_arg, 1); } if (op->on_consumed != NULL) { op->on_consumed->cb(exec_ctx, op->on_consumed->cb_arg, 0); } }
static void lame_start_transport_op(grpc_call_element *elem, grpc_transport_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; GRPC_CALL_LOG_OP(GPR_INFO, elem, op); if (op->send_ops) { op->on_done_send(op->send_user_data, 0); } if (op->recv_ops) { char tmp[GPR_LTOA_MIN_BUFSIZE]; grpc_metadata_batch mdb; gpr_ltoa(GRPC_STATUS_UNKNOWN, tmp); calld->status.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-status", tmp); calld->details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message", "Rpc sent on a lame channel."); calld->status.prev = calld->details.next = NULL; calld->status.next = &calld->details; calld->details.prev = &calld->status; mdb.list.head = &calld->status; mdb.list.tail = &calld->details; mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = gpr_inf_future; grpc_sopb_add_metadata(op->recv_ops, mdb); *op->recv_state = GRPC_STREAM_CLOSED; op->on_done_recv(op->recv_user_data, 1); } }
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) { if (i >= 0 && i < NUM_CACHED_STATUS_ELEMS) { return grpc_mdelem_ref(channel->grpc_status_elem[i]); } else { char tmp[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(i, tmp); return grpc_mdelem_from_metadata_strings( channel->metadata_context, grpc_mdstr_ref(channel->grpc_status_string), grpc_mdstr_from_string(channel->metadata_context, tmp)); } }
grpc_channel *grpc_channel_create_from_filters( const char *target, const grpc_channel_filter **filters, size_t num_filters, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client) { size_t i; size_t size = sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters); grpc_channel *channel = gpr_malloc(size); memset(channel, 0, sizeof(*channel)); channel->target = gpr_strdup(target); GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); channel->is_client = is_client; /* decremented by grpc_channel_destroy */ gpr_ref_init(&channel->refs, 1); channel->metadata_context = mdctx; channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status", 0); channel->grpc_compression_algorithm_string = grpc_mdstr_from_string(mdctx, "grpc-encoding", 0); channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message", 0); for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) { char buf[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(i, buf); channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings( mdctx, GRPC_MDSTR_REF(channel->grpc_status_string), grpc_mdstr_from_string(mdctx, buf, 0)); } channel->path_string = grpc_mdstr_from_string(mdctx, ":path", 0); channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority", 0); gpr_mu_init(&channel->registered_call_mu); channel->registered_calls = NULL; channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH; if (args) { for (i = 0; i < args->num_args; i++) { if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) { if (args->args[i].type != GRPC_ARG_INTEGER) { gpr_log(GPR_ERROR, "%s ignored: it must be an integer", GRPC_ARG_MAX_MESSAGE_LENGTH); } else if (args->args[i].value.integer < 0) { gpr_log(GPR_ERROR, "%s ignored: it must be >= 0", GRPC_ARG_MAX_MESSAGE_LENGTH); } else { channel->max_message_length = args->args[i].value.integer; } } } } grpc_channel_stack_init(filters, num_filters, channel, args, channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); return channel; }
static char *encoded_jwt_claim(const grpc_auth_json_key *json_key, const char *audience, gpr_timespec token_lifetime, const char *scope) { grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json *child = NULL; char *json_str = NULL; char *result = NULL; gpr_timespec now = gpr_now(); gpr_timespec expiration = gpr_time_add(now, token_lifetime); char now_str[GPR_LTOA_MIN_BUFSIZE]; char expiration_str[GPR_LTOA_MIN_BUFSIZE]; if (gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime) > 0) { gpr_log(GPR_INFO, "Cropping token lifetime to maximum allowed value."); expiration = gpr_time_add(now, grpc_max_auth_token_lifetime); } gpr_ltoa(now.tv_sec, now_str); gpr_ltoa(expiration.tv_sec, expiration_str); child = create_child(NULL, json, "iss", json_key->client_email, GRPC_JSON_STRING); if (scope != NULL) { child = create_child(child, json, "scope", scope, GRPC_JSON_STRING); } else { /* Unscoped JWTs need a sub field. */ child = create_child(child, json, "sub", json_key->client_email, GRPC_JSON_STRING); } child = create_child(child, json, "aud", audience, GRPC_JSON_STRING); child = create_child(child, json, "iat", now_str, GRPC_JSON_NUMBER); create_child(child, json, "exp", expiration_str, GRPC_JSON_NUMBER); json_str = grpc_json_dump_to_string(json, 0); result = grpc_base64_encode(json_str, strlen(json_str), 1, 0); gpr_free(json_str); grpc_json_destroy(json); return result; }
static void test_create_many_ephemeral_metadata(void) { char buffer[GPR_LTOA_MIN_BUFSIZE]; long i; LOG_TEST("test_create_many_ephemeral_metadata"); grpc_init(); /* add, and immediately delete a bunch of different elements */ for (i = 0; i < MANY; i++) { gpr_ltoa(i, buffer); GRPC_MDELEM_UNREF(grpc_mdelem_from_strings("a", buffer)); } grpc_shutdown(); }
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) { char tmp[GPR_LTOA_MIN_BUFSIZE]; switch (i) { case 0: return GRPC_MDELEM_GRPC_STATUS_0; case 1: return GRPC_MDELEM_GRPC_STATUS_1; case 2: return GRPC_MDELEM_GRPC_STATUS_2; } gpr_ltoa(i, tmp); return grpc_mdelem_from_metadata_strings(GRPC_MDSTR_GRPC_STATUS, grpc_mdstr_from_string(tmp)); }
void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) { #ifndef NDEBUG char tmp[GRPC_COMPLETION_DO_NOT_USE * (1 + GPR_LTOA_MIN_BUFSIZE)]; char *p = tmp; int i; for (i = 0; i < GRPC_COMPLETION_DO_NOT_USE; i++) { *p++ = ' '; p += gpr_ltoa(cc->pending_op_count[i], p); } gpr_log(GPR_INFO, "pending ops:%s", tmp); #endif }
static void init_channel_elem(grpc_channel_element *elem, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { channel_data *channeld = elem->channel_data; char status[12]; GPR_ASSERT(is_first); GPR_ASSERT(is_last); channeld->message = grpc_mdelem_from_strings(mdctx, "grpc-message", "Rpc sent on a lame channel."); gpr_ltoa(GRPC_STATUS_UNKNOWN, status); channeld->status = grpc_mdelem_from_strings(mdctx, "grpc-status", status); }
static void test_ltoa() { char *str; char buf[GPR_LTOA_MIN_BUFSIZE]; LOG_TEST_NAME("test_ltoa"); /* zero */ GPR_ASSERT(1 == gpr_ltoa(0, buf)); GPR_ASSERT(0 == strcmp("0", buf)); /* positive number */ GPR_ASSERT(3 == gpr_ltoa(123, buf)); GPR_ASSERT(0 == strcmp("123", buf)); /* negative number */ GPR_ASSERT(6 == gpr_ltoa(-12345, buf)); GPR_ASSERT(0 == strcmp("-12345", buf)); /* large negative - we don't know the size of long in advance */ GPR_ASSERT(gpr_asprintf(&str, "%lld", (long long)LONG_MIN)); GPR_ASSERT(strlen(str) == (size_t)gpr_ltoa(LONG_MIN, buf)); GPR_ASSERT(0 == strcmp(str, buf)); gpr_free(str); }
static void fill_metadata(grpc_call_element *elem, grpc_metadata_batch *mdb) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; char tmp[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(chand->error_code, tmp); calld->status.md = grpc_mdelem_from_strings("grpc-status", tmp); calld->details.md = grpc_mdelem_from_strings("grpc-message", chand->error_message); calld->status.prev = calld->details.next = NULL; calld->status.next = &calld->details; calld->details.prev = &calld->status; mdb->list.head = &calld->status; mdb->list.tail = &calld->details; mdb->deadline = gpr_inf_future(GPR_CLOCK_REALTIME); }
static void test_create_many_ephemeral_metadata(void) { grpc_mdctx *ctx; char buffer[GPR_LTOA_MIN_BUFSIZE]; long i; size_t mdtab_capacity_before; LOG_TEST("test_create_many_ephemeral_metadata"); ctx = grpc_mdctx_create(); mdtab_capacity_before = grpc_mdctx_get_mdtab_capacity_test_only(ctx); /* add, and immediately delete a bunch of different elements */ for (i = 0; i < MANY; i++) { gpr_ltoa(i, buffer); GRPC_MDELEM_UNREF(grpc_mdelem_from_strings(ctx, "a", buffer)); } /* capacity should not grow */ GPR_ASSERT(mdtab_capacity_before == grpc_mdctx_get_mdtab_capacity_test_only(ctx)); grpc_mdctx_unref(ctx); }
static void test_insertion_and_deletion_with_high_collision_rate(void) { census_ht_option opt = {CENSUS_HT_POINTER, 13, &force_collision, &cmp_str_keys, NULL, NULL}; census_ht *ht = census_ht_create(&opt); char key_str[1000][GPR_LTOA_MIN_BUFSIZE]; uint64_t val = 0; unsigned i = 0; for (i = 0; i < 1000; i++) { census_ht_key key; key.ptr = key_str[i]; gpr_ltoa(i, key_str[i]); census_ht_insert(ht, key, (void *)(&val)); gpr_log(GPR_INFO, "%d\n", i); GPR_ASSERT(census_ht_get_size(ht) == (i + 1)); } for (i = 0; i < 1000; i++) { census_ht_key key; key.ptr = key_str[i]; census_ht_erase(ht, key); GPR_ASSERT(census_ht_get_size(ht) == (999 - i)); } census_ht_destroy(ht); }
/* Constructor for channel_data */ static void init_channel_elem(grpc_channel_element *elem, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { channel_data *chand = elem->channel_data; char temp[GPR_LTOA_MIN_BUFSIZE]; GPR_ASSERT(!is_first); GPR_ASSERT(is_last); GPR_ASSERT(elem->filter == &grpc_client_channel_filter); gpr_mu_init(&chand->mu); chand->active_child = NULL; chand->waiting_children = NULL; chand->waiting_child_count = 0; chand->waiting_child_capacity = 0; chand->transport_setup = NULL; chand->transport_setup_initiated = 0; chand->args = grpc_channel_args_copy(args); gpr_ltoa(GRPC_STATUS_CANCELLED, temp); chand->cancel_status = grpc_mdelem_from_strings(metadata_context, "grpc-status", temp); }
static void unlock_check_read_write_state(grpc_chttp2_transport *t) { grpc_chttp2_transport_global *transport_global = &t->global; grpc_chttp2_stream_global *stream_global; grpc_stream_state state; if (!t->parsing_active) { /* if a stream is in the stream map, and gets cancelled, we need to ensure we are not parsing before continuing the cancellation to keep things in a sane state */ while (grpc_chttp2_list_pop_closed_waiting_for_parsing(transport_global, &stream_global)) { GPR_ASSERT(stream_global->in_stream_map); GPR_ASSERT(stream_global->write_state != GRPC_WRITE_STATE_OPEN); GPR_ASSERT(stream_global->read_closed); remove_stream(t, stream_global->id); grpc_chttp2_list_add_read_write_state_changed(transport_global, stream_global); } } while (grpc_chttp2_list_pop_read_write_state_changed(transport_global, &stream_global)) { if (stream_global->cancelled) { stream_global->write_state = GRPC_WRITE_STATE_SENT_CLOSE; stream_global->read_closed = 1; if (!stream_global->published_cancelled) { char buffer[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(stream_global->cancelled_status, buffer); grpc_chttp2_incoming_metadata_buffer_add(&stream_global->incoming_metadata, grpc_mdelem_from_strings(t->metadata_context, "grpc-status", buffer)); grpc_chttp2_incoming_metadata_buffer_place_metadata_batch_into( &stream_global->incoming_metadata, &stream_global->incoming_sopb); stream_global->published_cancelled = 1; } } if (stream_global->write_state == GRPC_WRITE_STATE_SENT_CLOSE && stream_global->read_closed && stream_global->in_stream_map) { if (t->parsing_active) { grpc_chttp2_list_add_closed_waiting_for_parsing(transport_global, stream_global); } else { remove_stream(t, stream_global->id); } } if (!stream_global->publish_sopb) { continue; } /* FIXME(ctiller): we include in_stream_map in our computation of whether the stream is write-closed. This is completely bogus, but has the effect of delaying stream-closed until the stream is indeed evicted from the stream map, making it safe to delete. To fix this will require having an edge after stream-closed indicating that the stream is closed AND safe to delete. */ state = compute_state( stream_global->write_state == GRPC_WRITE_STATE_SENT_CLOSE && !stream_global->in_stream_map, stream_global->read_closed); if (stream_global->incoming_sopb.nops == 0 && state == stream_global->published_state) { continue; } grpc_chttp2_incoming_metadata_buffer_postprocess_sopb_and_begin_live_op( &stream_global->incoming_metadata, &stream_global->incoming_sopb, &stream_global->outstanding_metadata); grpc_sopb_swap(stream_global->publish_sopb, &stream_global->incoming_sopb); stream_global->published_state = *stream_global->publish_state = state; grpc_chttp2_schedule_closure(transport_global, stream_global->recv_done_closure, 1); stream_global->recv_done_closure = NULL; stream_global->publish_sopb = NULL; stream_global->publish_state = NULL; } }
static int fill_send_ops(grpc_call *call, grpc_transport_op *op) { grpc_ioreq_data data; grpc_metadata_batch mdb; size_t i; char status_str[GPR_LTOA_MIN_BUFSIZE]; GPR_ASSERT(op->send_ops == NULL); switch (call->write_state) { case WRITE_STATE_INITIAL: if (!is_op_live(call, GRPC_IOREQ_SEND_INITIAL_METADATA)) { break; } data = call->request_data[GRPC_IOREQ_SEND_INITIAL_METADATA]; mdb.list = chain_metadata_from_app(call, data.send_metadata.count, data.send_metadata.metadata); mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = call->send_deadline; for (i = 0; i < call->send_initial_metadata_count; i++) { grpc_metadata_batch_link_head(&mdb, &call->send_initial_metadata[i]); } grpc_sopb_add_metadata(&call->send_ops, mdb); op->send_ops = &call->send_ops; op->bind_pollset = grpc_cq_pollset(call->cq); call->last_send_contains |= 1 << GRPC_IOREQ_SEND_INITIAL_METADATA; call->write_state = WRITE_STATE_STARTED; call->send_initial_metadata_count = 0; /* fall through intended */ case WRITE_STATE_STARTED: if (is_op_live(call, GRPC_IOREQ_SEND_MESSAGE)) { data = call->request_data[GRPC_IOREQ_SEND_MESSAGE]; grpc_sopb_add_begin_message( &call->send_ops, grpc_byte_buffer_length(data.send_message), 0); copy_byte_buffer_to_stream_ops(data.send_message, &call->send_ops); op->send_ops = &call->send_ops; call->last_send_contains |= 1 << GRPC_IOREQ_SEND_MESSAGE; } if (is_op_live(call, GRPC_IOREQ_SEND_CLOSE)) { op->is_last_send = 1; op->send_ops = &call->send_ops; call->last_send_contains |= 1 << GRPC_IOREQ_SEND_CLOSE; call->write_state = WRITE_STATE_WRITE_CLOSED; if (!call->is_client) { /* send trailing metadata */ data = call->request_data[GRPC_IOREQ_SEND_TRAILING_METADATA]; mdb.list = chain_metadata_from_app(call, data.send_metadata.count, data.send_metadata.metadata); mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = gpr_inf_future; /* send status */ /* TODO(ctiller): cache common status values */ data = call->request_data[GRPC_IOREQ_SEND_STATUS]; gpr_ltoa(data.send_status.code, status_str); grpc_metadata_batch_add_tail( &mdb, &call->status_link, grpc_mdelem_from_metadata_strings( call->metadata_context, grpc_mdstr_ref(grpc_channel_get_status_string(call->channel)), grpc_mdstr_from_string(call->metadata_context, status_str))); if (data.send_status.details) { grpc_metadata_batch_add_tail( &mdb, &call->details_link, grpc_mdelem_from_metadata_strings( call->metadata_context, grpc_mdstr_ref( grpc_channel_get_message_string(call->channel)), grpc_mdstr_from_string(call->metadata_context, data.send_status.details))); } grpc_sopb_add_metadata(&call->send_ops, mdb); } } break; case WRITE_STATE_WRITE_CLOSED: break; } if (op->send_ops) { op->on_done_send = call_on_done_send; op->send_user_data = call; } return op->send_ops != NULL; }
static void test_find(void) { grpc_chttp2_hptbl tbl; int i; char buffer[32]; grpc_mdctx *mdctx; grpc_chttp2_hptbl_find_result r; LOG_TEST("test_find"); mdctx = grpc_mdctx_create(); grpc_chttp2_hptbl_init(&tbl, mdctx); grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "abc", "xyz")); grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "abc", "123")); grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "x", "1")); r = find_simple(&tbl, "abc", "123"); GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, "abc", "xyz"); GPR_ASSERT(r.index == 3 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, "x", "1"); GPR_ASSERT(r.index == 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, "x", "2"); GPR_ASSERT(r.index == 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 0); r = find_simple(&tbl, "vary", "some-vary-arg"); GPR_ASSERT(r.index == 59); GPR_ASSERT(r.has_value == 0); r = find_simple(&tbl, "accept-encoding", "gzip, deflate"); GPR_ASSERT(r.index == 16); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, "accept-encoding", "gzip"); GPR_ASSERT(r.index == 16); GPR_ASSERT(r.has_value == 0); r = find_simple(&tbl, ":method", "GET"); GPR_ASSERT(r.index == 2); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, ":method", "POST"); GPR_ASSERT(r.index == 3); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, ":method", "PUT"); GPR_ASSERT(r.index == 2 || r.index == 3); GPR_ASSERT(r.has_value == 0); r = find_simple(&tbl, "this-does-not-exist", ""); GPR_ASSERT(r.index == 0); GPR_ASSERT(r.has_value == 0); /* overflow the string buffer, check find still works */ for (i = 0; i < 10000; i++) { gpr_ltoa(i, buffer); grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "test", buffer)); } r = find_simple(&tbl, "abc", "123"); GPR_ASSERT(r.index == 0); GPR_ASSERT(r.has_value == 0); r = find_simple(&tbl, "test", "9999"); GPR_ASSERT(r.index == 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); r = find_simple(&tbl, "test", "9998"); GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); for (i = 0; i < tbl.num_ents; i++) { int expect = 9999 - i; gpr_ltoa(expect, buffer); r = find_simple(&tbl, "test", buffer); GPR_ASSERT(r.index == i + 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY); GPR_ASSERT(r.has_value == 1); } r = find_simple(&tbl, "test", "10000"); GPR_ASSERT(r.index != 0); GPR_ASSERT(r.has_value == 0); grpc_chttp2_hptbl_destroy(&tbl); grpc_mdctx_unref(mdctx); }
static void enact_send_action(grpc_call *call, send_action sa) { grpc_ioreq_data data; grpc_call_op op; size_t i; gpr_uint32 flags = 0; char status_str[GPR_LTOA_MIN_BUFSIZE]; switch (sa) { case SEND_NOTHING: abort(); break; case SEND_BUFFERED_INITIAL_METADATA: flags |= GRPC_WRITE_BUFFER_HINT; /* fallthrough */ case SEND_INITIAL_METADATA: data = call->request_data[GRPC_IOREQ_SEND_INITIAL_METADATA]; for (i = 0; i < data.send_metadata.count; i++) { const grpc_metadata *md = &data.send_metadata.metadata[i]; send_metadata(call, grpc_mdelem_from_string_and_buffer( call->metadata_context, md->key, (const gpr_uint8 *)md->value, md->value_length)); } op.type = GRPC_SEND_START; op.dir = GRPC_CALL_DOWN; op.flags = flags; op.data.start.pollset = grpc_cq_pollset(call->cq); op.done_cb = finish_start_step; op.user_data = call; grpc_call_execute_op(call, &op); break; case SEND_BUFFERED_MESSAGE: flags |= GRPC_WRITE_BUFFER_HINT; /* fallthrough */ case SEND_MESSAGE: data = call->request_data[GRPC_IOREQ_SEND_MESSAGE]; op.type = GRPC_SEND_MESSAGE; op.dir = GRPC_CALL_DOWN; op.flags = flags; op.data.message = data.send_message; op.done_cb = finish_write_step; op.user_data = call; grpc_call_execute_op(call, &op); break; case SEND_TRAILING_METADATA_AND_FINISH: /* send trailing metadata */ data = call->request_data[GRPC_IOREQ_SEND_TRAILING_METADATA]; for (i = 0; i < data.send_metadata.count; i++) { const grpc_metadata *md = &data.send_metadata.metadata[i]; send_metadata(call, grpc_mdelem_from_string_and_buffer( call->metadata_context, md->key, (const gpr_uint8 *)md->value, md->value_length)); } /* send status */ /* TODO(ctiller): cache common status values */ data = call->request_data[GRPC_IOREQ_SEND_STATUS]; gpr_ltoa(data.send_status.code, status_str); send_metadata( call, grpc_mdelem_from_metadata_strings( call->metadata_context, grpc_mdstr_ref(grpc_channel_get_status_string(call->channel)), grpc_mdstr_from_string(call->metadata_context, status_str))); if (data.send_status.details) { send_metadata( call, grpc_mdelem_from_metadata_strings( call->metadata_context, grpc_mdstr_ref(grpc_channel_get_message_string(call->channel)), grpc_mdstr_from_string(call->metadata_context, data.send_status.details))); } /* fallthrough: see choose_send_action for details */ case SEND_FINISH: op.type = GRPC_SEND_FINISH; op.dir = GRPC_CALL_DOWN; op.flags = 0; op.done_cb = finish_finish_step; op.user_data = call; grpc_call_execute_op(call, &op); break; } }
grpc_channel *grpc_channel_create_from_filters( grpc_exec_ctx *exec_ctx, const char *target, const grpc_channel_filter **filters, size_t num_filters, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_client) { size_t i; size_t size = sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters); grpc_channel *channel = gpr_malloc(size); memset(channel, 0, sizeof(*channel)); channel->target = gpr_strdup(target); GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); channel->is_client = is_client; /* decremented by grpc_channel_destroy */ gpr_ref_init(&channel->refs, 1); channel->metadata_context = mdctx; channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status", 0); channel->grpc_compression_algorithm_string = grpc_mdstr_from_string(mdctx, "grpc-encoding", 0); channel->grpc_encodings_accepted_by_peer_string = grpc_mdstr_from_string(mdctx, "grpc-accept-encoding", 0); channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message", 0); for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) { char buf[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa((long)i, buf); channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings( mdctx, GRPC_MDSTR_REF(channel->grpc_status_string), grpc_mdstr_from_string(mdctx, buf, 0)); } channel->path_string = grpc_mdstr_from_string(mdctx, ":path", 0); channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority", 0); gpr_mu_init(&channel->registered_call_mu); channel->registered_calls = NULL; channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH; if (args) { for (i = 0; i < args->num_args; i++) { if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) { if (args->args[i].type != GRPC_ARG_INTEGER) { gpr_log(GPR_ERROR, "%s ignored: it must be an integer", GRPC_ARG_MAX_MESSAGE_LENGTH); } else if (args->args[i].value.integer < 0) { gpr_log(GPR_ERROR, "%s ignored: it must be >= 0", GRPC_ARG_MAX_MESSAGE_LENGTH); } else { channel->max_message_length = (gpr_uint32)args->args[i].value.integer; } } else if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { if (args->args[i].type != GRPC_ARG_STRING) { gpr_log(GPR_ERROR, "%s: must be an string", GRPC_ARG_DEFAULT_AUTHORITY); } else { if (channel->default_authority) { /* setting this takes precedence over anything else */ GRPC_MDELEM_UNREF(channel->default_authority); } channel->default_authority = grpc_mdelem_from_strings( mdctx, ":authority", args->args[i].value.string); } } else if (0 == strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { if (args->args[i].type != GRPC_ARG_STRING) { gpr_log(GPR_ERROR, "%s: must be an string", GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); } else { if (channel->default_authority) { /* other ways of setting this (notably ssl) take precedence */ gpr_log(GPR_ERROR, "%s: default host already set some other way", GRPC_ARG_DEFAULT_AUTHORITY); } else { channel->default_authority = grpc_mdelem_from_strings( mdctx, ":authority", args->args[i].value.string); } } } } } if (channel->is_client && channel->default_authority == NULL && target != NULL) { char *default_authority = grpc_get_default_authority(target); if (default_authority) { channel->default_authority = grpc_mdelem_from_strings( channel->metadata_context, ":authority", default_authority); } gpr_free(default_authority); } grpc_channel_stack_init(exec_ctx, filters, num_filters, channel, args, channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); return channel; }
static void output_num(long num) { char buf[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(num, buf); output_string(buf); }