Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
// Start transport stream op.
static void start_transport_stream_op(grpc_exec_ctx* exec_ctx,
                                      grpc_call_element* elem,
                                      grpc_transport_stream_op* op) {
  call_data* calld = elem->call_data;
  // Check max send message size.
  if (op->send_message != NULL && calld->max_send_size >= 0 &&
      op->send_message->length > (size_t)calld->max_send_size) {
    char* message_string;
    gpr_asprintf(&message_string, "Sent message larger than max (%u vs. %d)",
                 op->send_message->length, calld->max_send_size);
    gpr_slice message = gpr_slice_from_copied_string(message_string);
    gpr_free(message_string);
    grpc_call_element_send_close_with_message(
        exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT, &message);
  }
  // Inject callback for receiving a message.
  if (op->recv_message_ready != NULL) {
    calld->next_recv_message_ready = op->recv_message_ready;
    calld->recv_message = op->recv_message;
    op->recv_message_ready = &calld->recv_message_ready;
  }
  // Chain to the next filter.
  grpc_call_next_op(exec_ctx, elem, op);
}