Пример #1
0
static int prepare_application_metadata(grpc_call *call, size_t count,
                                        grpc_metadata *metadata) {
  size_t i;
  for (i = 0; i < count; i++) {
    grpc_metadata *md = &metadata[i];
    grpc_metadata *next_md = (i == count - 1) ? NULL : &metadata[i + 1];
    grpc_metadata *prev_md = (i == 0) ? NULL : &metadata[i - 1];
    grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
    GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
    l->md = grpc_mdelem_from_string_and_buffer(call->metadata_context, md->key,
                                               (const gpr_uint8 *)md->value,
                                               md->value_length);
    if (!grpc_mdstr_is_legal_header(l->md->key)) {
      gpr_log(GPR_ERROR, "attempt to send invalid metadata key");
      return 0;
    } else if (!grpc_mdstr_is_bin_suffixed(l->md->key) &&
               !grpc_mdstr_is_legal_header(l->md->value)) {
      gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
      return 0;
    }
    l->next = next_md ? (grpc_linked_mdelem *)&next_md->internal_data : NULL;
    l->prev = prev_md ? (grpc_linked_mdelem *)&prev_md->internal_data : NULL;
  }
  return 1;
}
Пример #2
0
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;
  }
}
Пример #3
0
static int prepare_application_metadata(grpc_call *call, int count,
                                        grpc_metadata *metadata,
                                        int is_trailing,
                                        int prepend_extra_metadata) {
  int i;
  grpc_metadata_batch *batch =
      &call->metadata_batch[0 /* is_receiving */][is_trailing];
  if (prepend_extra_metadata) {
    if (call->send_extra_metadata_count == 0) {
      prepend_extra_metadata = 0;
    } else {
      for (i = 0; i < call->send_extra_metadata_count; i++) {
        GRPC_MDELEM_REF(call->send_extra_metadata[i].md);
      }
      for (i = 1; i < call->send_extra_metadata_count; i++) {
        call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1];
      }
      for (i = 0; i < call->send_extra_metadata_count - 1; i++) {
        call->send_extra_metadata[i].next = &call->send_extra_metadata[i + 1];
      }
    }
  }
  for (i = 0; i < count; i++) {
    grpc_metadata *md = &metadata[i];
    grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
    GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
    l->md = grpc_mdelem_from_string_and_buffer(call->metadata_context, md->key,
                                               (const gpr_uint8 *)md->value,
                                               md->value_length);
    if (!grpc_mdstr_is_legal_header(l->md->key)) {
      gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
              grpc_mdstr_as_c_string(l->md->key));
      return 0;
    } else if (!grpc_mdstr_is_bin_suffixed(l->md->key) &&
               !grpc_mdstr_is_legal_nonbin_header(l->md->value)) {
      gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
      return 0;
    }
  }
  for (i = 1; i < count; i++) {
    linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]);
  }
  for (i = 0; i < count - 1; i++) {
    linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]);
  }
  switch (prepend_extra_metadata * 2 + (count != 0)) {
    case 0:
      /* no prepend, no metadata => nothing to do */
      batch->list.head = batch->list.tail = NULL;
      break;
    case 1:
      /* metadata, but no prepend */
      batch->list.head = linked_from_md(&metadata[0]);
      batch->list.tail = linked_from_md(&metadata[count - 1]);
      batch->list.head->prev = NULL;
      batch->list.tail->next = NULL;
      break;
    case 2:
      /* prepend, but no md */
      batch->list.head = &call->send_extra_metadata[0];
      batch->list.tail =
          &call->send_extra_metadata[call->send_extra_metadata_count - 1];
      batch->list.head->prev = NULL;
      batch->list.tail->next = NULL;
      break;
    case 3:
      /* prepend AND md */
      batch->list.head = &call->send_extra_metadata[0];
      call->send_extra_metadata[call->send_extra_metadata_count - 1].next =
          linked_from_md(&metadata[0]);
      linked_from_md(&metadata[0])->prev =
          &call->send_extra_metadata[call->send_extra_metadata_count - 1];
      batch->list.tail = linked_from_md(&metadata[count - 1]);
      batch->list.head->prev = NULL;
      batch->list.tail->next = NULL;
      break;
    default:
      GPR_UNREACHABLE_CODE(return 0);
  }

  return 1;
}