Example #1
0
/* 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;
}
Example #2
0
/* grpc_rb_op_update_status_from_server adds the values in a ruby status
   struct to the 'send_status_from_server' portion of an op.
*/
static void grpc_rb_op_update_status_from_server(
    grpc_op *op, grpc_metadata_array *md_ary, grpc_slice *send_status_details,
    VALUE status) {
  VALUE code = rb_struct_aref(status, sym_code);
  VALUE details = rb_struct_aref(status, sym_details);
  VALUE metadata_hash = rb_struct_aref(status, sym_metadata);

  /* TODO: add check to ensure status is the correct struct type */
  if (TYPE(code) != T_FIXNUM) {
    rb_raise(rb_eTypeError, "invalid code : got <%s>, want <Fixnum>",
             rb_obj_classname(code));
    return;
  }
  if (TYPE(details) != T_STRING) {
    rb_raise(rb_eTypeError, "invalid details : got <%s>, want <String>",
             rb_obj_classname(code));
    return;
  }

  *send_status_details =
      grpc_slice_from_copied_buffer(RSTRING_PTR(details), RSTRING_LEN(details));

  op->data.send_status_from_server.status = NUM2INT(code);
  op->data.send_status_from_server.status_details = send_status_details;
  grpc_rb_md_ary_convert(metadata_hash, md_ary);
  op->data.send_status_from_server.trailing_metadata_count = md_ary->count;
  op->data.send_status_from_server.trailing_metadata = md_ary->metadata;
}
Example #3
0
static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx,
                                                       security_handshaker *h) {
  // Get data to send.
  tsi_result result = TSI_OK;
  size_t offset = 0;
  do {
    size_t to_send_size = h->handshake_buffer_size - offset;
    result = tsi_handshaker_get_bytes_to_send_to_peer(
        h->handshaker, h->handshake_buffer + offset, &to_send_size);
    offset += to_send_size;
    if (result == TSI_INCOMPLETE_DATA) {
      h->handshake_buffer_size *= 2;
      h->handshake_buffer =
          gpr_realloc(h->handshake_buffer, h->handshake_buffer_size);
    }
  } while (result == TSI_INCOMPLETE_DATA);
  if (result != TSI_OK) {
    return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"),
                                     result);
  }
  // Send data.
  grpc_slice to_send =
      grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
  grpc_slice_buffer_reset_and_unref(&h->outgoing);
  grpc_slice_buffer_add(&h->outgoing, to_send);
  grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
                      &h->on_handshake_data_sent_to_peer);
  return GRPC_ERROR_NONE;
}
/* 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);
}
Example #5
0
GPR_EXPORT void GPR_CALLTYPE
grpcsharp_metadata_array_add(grpc_metadata_array* array, const char* key,
                             const char* value, size_t value_length) {
  size_t i = array->count;
  GPR_ASSERT(array->count < array->capacity);
  array->metadata[i].key = grpc_slice_from_copied_string(key);
  array->metadata[i].value = grpc_slice_from_copied_buffer(value, value_length);
  array->count++;
}
Example #6
0
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;
}
Example #7
0
static void test_dump_slice(void) {
  static const char *text = "HELLO WORLD!";
  static const char *long_text =
      "It was a bright cold day in April, and the clocks were striking "
      "thirteen. Winston Smith, his chin nuzzled into his breast in an effort "
      "to escape the vile wind, slipped quickly through the glass doors of "
      "Victory Mansions, though not quickly enough to prevent a swirl of "
      "gritty dust from entering along with him.";

  LOG_TEST_NAME("test_dump_slice");

  expect_slice_dump(grpc_slice_from_copied_string(text), GPR_DUMP_ASCII, text);
  expect_slice_dump(grpc_slice_from_copied_string(long_text), GPR_DUMP_ASCII,
                    long_text);
  expect_slice_dump(grpc_slice_from_copied_buffer("\x01", 1), GPR_DUMP_HEX,
                    "01");
  expect_slice_dump(grpc_slice_from_copied_buffer("\x01", 1),
                    GPR_DUMP_HEX | GPR_DUMP_ASCII, "01 '.'");
}
Example #8
0
static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
                            grpc_error *error) {
  security_handshaker *h = arg;
  gpr_mu_lock(&h->mu);
  if (error != GRPC_ERROR_NONE || h->shutdown) {
    security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error));
    goto done;
  }
  // Create frame protector.
  tsi_frame_protector *protector;
  tsi_result result = tsi_handshaker_result_create_frame_protector(
      h->handshaker_result, NULL, &protector);
  if (result != TSI_OK) {
    error = grpc_set_tsi_error_result(
        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"),
        result);
    security_handshake_failed_locked(exec_ctx, h, error);
    goto done;
  }
  // Get unused bytes.
  unsigned char *unused_bytes = NULL;
  size_t unused_bytes_size = 0;
  result = tsi_handshaker_result_get_unused_bytes(
      h->handshaker_result, &unused_bytes, &unused_bytes_size);
  // Create secure endpoint.
  if (unused_bytes_size > 0) {
    grpc_slice slice =
        grpc_slice_from_copied_buffer((char *)unused_bytes, unused_bytes_size);
    h->args->endpoint =
        grpc_secure_endpoint_create(protector, h->args->endpoint, &slice, 1);
    grpc_slice_unref_internal(exec_ctx, slice);
  } else {
    h->args->endpoint =
        grpc_secure_endpoint_create(protector, h->args->endpoint, NULL, 0);
  }
  tsi_handshaker_result_destroy(h->handshaker_result);
  h->handshaker_result = NULL;
  // Clear out the read buffer before it gets passed to the transport.
  grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer);
  // Add auth context to channel args.
  grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context);
  grpc_channel_args *tmp_args = h->args->args;
  h->args->args =
      grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1);
  grpc_channel_args_destroy(exec_ctx, tmp_args);
  // Invoke callback.
  GRPC_CLOSURE_SCHED(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE);
  // Set shutdown to true so that subsequent calls to
  // security_handshaker_shutdown() do nothing.
  h->shutdown = true;
done:
  gpr_mu_unlock(&h->mu);
  security_handshaker_unref(exec_ctx, h);
}
/** Returns a copy of percent decoded \a src[begin, end) */
static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src,
                                       size_t begin, size_t end) {
  grpc_slice component =
      grpc_slice_from_copied_buffer(src + begin, end - begin);
  grpc_slice decoded_component =
      grpc_permissive_percent_decode_slice(component);
  char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
  grpc_slice_unref_internal(exec_ctx, component);
  grpc_slice_unref_internal(exec_ctx, decoded_component);
  return out;
}
Example #10
0
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);
}
Example #11
0
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;
}
Example #12
0
/* Takes ownership of the header, claims and signature. */
static verifier_cb_ctx *verifier_cb_ctx_create(
    grpc_jwt_verifier *verifier, grpc_pollset *pollset, jose_header *header,
    grpc_jwt_claims *claims, const char *audience, grpc_slice signature,
    const char *signed_jwt, size_t signed_jwt_len, void *user_data,
    grpc_jwt_verification_done_cb cb) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
  memset(ctx, 0, sizeof(verifier_cb_ctx));
  ctx->verifier = verifier;
  ctx->pollent = grpc_polling_entity_create_from_pollset(pollset);
  ctx->header = header;
  ctx->audience = gpr_strdup(audience);
  ctx->claims = claims;
  ctx->signature = signature;
  ctx->signed_data = grpc_slice_from_copied_buffer(signed_jwt, signed_jwt_len);
  ctx->user_data = user_data;
  ctx->user_cb = cb;
  grpc_exec_ctx_finish(&exec_ctx);
  return ctx;
}
Example #13
0
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;
}
Example #14
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);
}
Example #15
0
static grpc_error *on_handshake_next_done_locked(
    grpc_exec_ctx *exec_ctx, security_handshaker *h, tsi_result result,
    const unsigned char *bytes_to_send, size_t bytes_to_send_size,
    tsi_handshaker_result *handshaker_result) {
  grpc_error *error = GRPC_ERROR_NONE;
  // Read more if we need to.
  if (result == TSI_INCOMPLETE_DATA) {
    GPR_ASSERT(bytes_to_send_size == 0);
    grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
                       &h->on_handshake_data_received_from_peer);
    return error;
  }
  if (result != TSI_OK) {
    return grpc_set_tsi_error_result(
        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result);
  }
  // Update handshaker result.
  if (handshaker_result != NULL) {
    GPR_ASSERT(h->handshaker_result == NULL);
    h->handshaker_result = handshaker_result;
  }
  if (bytes_to_send_size > 0) {
    // Send data to peer, if needed.
    grpc_slice to_send = grpc_slice_from_copied_buffer(
        (const char *)bytes_to_send, bytes_to_send_size);
    grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing);
    grpc_slice_buffer_add(&h->outgoing, to_send);
    grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
                        &h->on_handshake_data_sent_to_peer);
  } else if (handshaker_result == NULL) {
    // There is nothing to send, but need to read from peer.
    grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
                       &h->on_handshake_data_received_from_peer);
  } else {
    // Handshake has finished, check peer and so on.
    error = check_peer_locked(exec_ctx, h);
  }
  return error;
}
Example #16
0
grpc_byte_buffer* string_to_byte_buffer(const char* buffer, size_t len) {
  grpc_slice slice = grpc_slice_from_copied_buffer(buffer, len);
  grpc_byte_buffer* bb = grpc_raw_byte_buffer_create(&slice, 1);
  grpc_slice_unref(slice);
  return bb;
}
Example #17
0
File: slice.c Project: Indifer/grpc
grpc_slice grpc_slice_from_copied_string(const char *source) {
  return grpc_slice_from_copied_buffer(source, strlen(source));
}
Example #18
0
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  grpc_test_only_set_slice_hash_seed(0);
  struct grpc_memory_counters counters;
  if (squelch) gpr_set_log_function(dont_log);
  if (leak_check) grpc_memory_counters_init();
  grpc_init();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_executor_set_threading(&exec_ctx, false);

  grpc_resource_quota *resource_quota =
      grpc_resource_quota_create("server_fuzzer");
  grpc_endpoint *mock_endpoint =
      grpc_mock_endpoint_create(discard_write, resource_quota);
  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
  grpc_mock_endpoint_put_read(
      &exec_ctx, mock_endpoint,
      grpc_slice_from_copied_buffer((const char *)data, size));

  grpc_server *server = grpc_server_create(NULL, NULL);
  grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL);
  grpc_server_register_completion_queue(server, cq, NULL);
  // TODO(ctiller): add registered methods (one for POST, one for PUT)
  // void *registered_method =
  //    grpc_server_register_method(server, "/reg", NULL, 0);
  grpc_server_start(server);
  grpc_transport *transport =
      grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 0);
  grpc_server_setup_transport(&exec_ctx, server, transport, NULL, NULL);
  grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL);

  grpc_call *call1 = NULL;
  grpc_call_details call_details1;
  grpc_metadata_array request_metadata1;
  grpc_call_details_init(&call_details1);
  grpc_metadata_array_init(&request_metadata1);
  int requested_calls = 0;

  GPR_ASSERT(GRPC_CALL_OK ==
             grpc_server_request_call(server, &call1, &call_details1,
                                      &request_metadata1, cq, cq, tag(1)));
  requested_calls++;

  grpc_event ev;
  while (1) {
    grpc_exec_ctx_flush(&exec_ctx);
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    switch (ev.type) {
      case GRPC_QUEUE_TIMEOUT:
        goto done;
      case GRPC_QUEUE_SHUTDOWN:
        break;
      case GRPC_OP_COMPLETE:
        switch (detag(ev.tag)) {
          case 1:
            requested_calls--;
            // TODO(ctiller): keep reading that call!
            break;
        }
    }
  }

done:
  if (call1 != NULL) grpc_call_unref(call1);
  grpc_call_details_destroy(&call_details1);
  grpc_metadata_array_destroy(&request_metadata1);
  grpc_server_shutdown_and_notify(server, cq, tag(0xdead));
  grpc_server_cancel_all_calls(server);
  for (int i = 0; i <= requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  }
  grpc_completion_queue_shutdown(cq);
  for (int i = 0; i <= requested_calls; i++) {
    ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
  }
  grpc_server_destroy(server);
  grpc_completion_queue_destroy(cq);
  grpc_shutdown();
  if (leak_check) {
    counters = grpc_memory_counters_snapshot();
    grpc_memory_counters_destroy();
    GPR_ASSERT(counters.total_size_relative == 0);
  }
  return 0;
}
Example #19
0
/* grpc_rb_md_ary_fill_hash_cb is the hash iteration callback used
   to fill grpc_metadata_array.

   it's capacity should have been computed via a prior call to
   grpc_rb_md_ary_fill_hash_cb
*/
static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
  grpc_metadata_array *md_ary = NULL;
  long array_length;
  long i;
  grpc_slice key_slice;
  grpc_slice value_slice;
  char *tmp_str;

  if (TYPE(key) == T_SYMBOL) {
    key_slice = grpc_slice_from_static_string(rb_id2name(SYM2ID(key)));
  } else if (TYPE(key) == T_STRING) {
    key_slice =
        grpc_slice_from_copied_buffer(RSTRING_PTR(key), RSTRING_LEN(key));
  } else {
    rb_raise(rb_eTypeError,
             "grpc_rb_md_ary_fill_hash_cb: bad type for key parameter");
  }

  if (!grpc_header_key_is_legal(key_slice)) {
    tmp_str = grpc_slice_to_c_string(key_slice);
    rb_raise(rb_eArgError,
             "'%s' is an invalid header key, must match [a-z0-9-_.]+", tmp_str);
    return ST_STOP;
  }

  /* Construct a metadata object from key and value and add it */
  TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
                       &grpc_rb_md_ary_data_type, md_ary);

  if (TYPE(val) == T_ARRAY) {
    array_length = RARRAY_LEN(val);
    /* If the value is an array, add capacity for each value in the array */
    for (i = 0; i < array_length; i++) {
      value_slice = grpc_slice_from_copied_buffer(
          RSTRING_PTR(rb_ary_entry(val, i)), RSTRING_LEN(rb_ary_entry(val, i)));
      if (!grpc_is_binary_header(key_slice) &&
          !grpc_header_nonbin_value_is_legal(value_slice)) {
        // The value has invalid characters
        tmp_str = grpc_slice_to_c_string(value_slice);
        rb_raise(rb_eArgError, "Header value '%s' has invalid characters",
                 tmp_str);
        return ST_STOP;
      }
      md_ary->metadata[md_ary->count].key = key_slice;
      md_ary->metadata[md_ary->count].value = value_slice;
      md_ary->count += 1;
    }
  } else if (TYPE(val) == T_STRING) {
    value_slice =
        grpc_slice_from_copied_buffer(RSTRING_PTR(val), RSTRING_LEN(val));
    if (!grpc_is_binary_header(key_slice) &&
        !grpc_header_nonbin_value_is_legal(value_slice)) {
      // The value has invalid characters
      tmp_str = grpc_slice_to_c_string(value_slice);
      rb_raise(rb_eArgError, "Header value '%s' has invalid characters",
               tmp_str);
      return ST_STOP;
    }
    md_ary->metadata[md_ary->count].key = key_slice;
    md_ary->metadata[md_ary->count].value = value_slice;
    md_ary->count += 1;
  } else {
    rb_raise(rb_eArgError, "Header values must be of type string or array");
    return ST_STOP;
  }

  return ST_CONTINUE;
}
Example #20
0
static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
    size_t slice_size, grpc_slice *leftover_slices, size_t leftover_nslices) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  tsi_frame_protector *fake_read_protector = tsi_create_fake_protector(NULL);
  tsi_frame_protector *fake_write_protector = tsi_create_fake_protector(NULL);
  grpc_endpoint_test_fixture f;
  grpc_endpoint_pair tcp;

  grpc_resource_quota *resource_quota =
      grpc_resource_quota_create("secure_endpoint_test");
  tcp = grpc_iomgr_create_endpoint_pair("fixture", resource_quota, slice_size);
  grpc_resource_quota_unref_internal(&exec_ctx, resource_quota);
  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);

  if (leftover_nslices == 0) {
    f.client_ep =
        grpc_secure_endpoint_create(fake_read_protector, tcp.client, NULL, 0);
  } else {
    unsigned i;
    tsi_result result;
    size_t still_pending_size;
    size_t total_buffer_size = 8192;
    size_t buffer_size = total_buffer_size;
    uint8_t *encrypted_buffer = gpr_malloc(buffer_size);
    uint8_t *cur = encrypted_buffer;
    grpc_slice encrypted_leftover;
    for (i = 0; i < leftover_nslices; i++) {
      grpc_slice plain = leftover_slices[i];
      uint8_t *message_bytes = GRPC_SLICE_START_PTR(plain);
      size_t message_size = GRPC_SLICE_LENGTH(plain);
      while (message_size > 0) {
        size_t protected_buffer_size_to_send = buffer_size;
        size_t processed_message_size = message_size;
        result = tsi_frame_protector_protect(
            fake_write_protector, message_bytes, &processed_message_size, cur,
            &protected_buffer_size_to_send);
        GPR_ASSERT(result == TSI_OK);
        message_bytes += processed_message_size;
        message_size -= processed_message_size;
        cur += protected_buffer_size_to_send;
        GPR_ASSERT(buffer_size >= protected_buffer_size_to_send);
        buffer_size -= protected_buffer_size_to_send;
      }
      grpc_slice_unref(plain);
    }
    do {
      size_t protected_buffer_size_to_send = buffer_size;
      result = tsi_frame_protector_protect_flush(fake_write_protector, cur,
                                                 &protected_buffer_size_to_send,
                                                 &still_pending_size);
      GPR_ASSERT(result == TSI_OK);
      cur += protected_buffer_size_to_send;
      GPR_ASSERT(buffer_size >= protected_buffer_size_to_send);
      buffer_size -= protected_buffer_size_to_send;
    } while (still_pending_size > 0);
    encrypted_leftover = grpc_slice_from_copied_buffer(
        (const char *)encrypted_buffer, total_buffer_size - buffer_size);
    f.client_ep = grpc_secure_endpoint_create(fake_read_protector, tcp.client,
                                              &encrypted_leftover, 1);
    grpc_slice_unref(encrypted_leftover);
    gpr_free(encrypted_buffer);
  }

  f.server_ep =
      grpc_secure_endpoint_create(fake_write_protector, tcp.server, NULL, 0);
  grpc_exec_ctx_finish(&exec_ctx);
  return f;
}
Example #21
0
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) {
  grpc_slice slice = grpc_slice_from_copied_buffer(string, length);
  grpc_byte_buffer *buffer = grpc_raw_byte_buffer_create(&slice, 1);
  grpc_slice_unref(slice);
  return buffer;
}