Example #1
0
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);
}
Example #2
0
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);
  }
}
Example #3
0
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);
  }
}
Example #4
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);
  }
}
Example #5
0
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));
  }
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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();
}
Example #9
0
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));
}
Example #10
0
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
}
Example #11
0
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);
}
Example #12
0
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);
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
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);
}
Example #16
0
/* 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);
}
Example #17
0
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;
  }
}
Example #18
0
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;
}
Example #19
0
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);
}
Example #20
0
File: call.c Project: qioixiy/grpc
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;
  }
}
Example #21
0
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;
}
Example #22
0
static void output_num(long num) {
  char buf[GPR_LTOA_MIN_BUFSIZE];
  gpr_ltoa(num, buf);
  output_string(buf);
}