Beispiel #1
0
static void test_load_empty_file(void) {
  FILE *tmp = NULL;
  grpc_slice slice;
  grpc_slice slice_with_null_term;
  grpc_error *error;
  char *tmp_name;

  LOG_TEST_NAME("test_load_empty_file");

  tmp = gpr_tmpfile(prefix, &tmp_name);
  GPR_ASSERT(tmp_name != NULL);
  GPR_ASSERT(tmp != NULL);
  fclose(tmp);

  error = grpc_load_file(tmp_name, 0, &slice);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == 0);

  error = grpc_load_file(tmp_name, 1, &slice_with_null_term);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == 1);
  GPR_ASSERT(GRPC_SLICE_START_PTR(slice_with_null_term)[0] == 0);

  remove(tmp_name);
  gpr_free(tmp_name);
  grpc_slice_unref(slice);
  grpc_slice_unref(slice_with_null_term);
}
Beispiel #2
0
static void test_vector(grpc_chttp2_hpack_parser *parser,
                        grpc_slice_split_mode mode, const char *hexstring,
                        ... /* char *key, char *value */) {
  grpc_slice input = parse_hexstring(hexstring);
  grpc_slice *slices;
  size_t nslices;
  size_t i;
  test_checker chk;

  va_start(chk.args, hexstring);

  parser->on_header = onhdr;
  parser->on_header_user_data = &chk;

  grpc_split_slices(mode, &input, 1, &slices, &nslices);
  grpc_slice_unref(input);

  for (i = 0; i < nslices; i++) {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    GPR_ASSERT(grpc_chttp2_hpack_parser_parse(&exec_ctx, parser, slices[i]) ==
               GRPC_ERROR_NONE);
    grpc_exec_ctx_finish(&exec_ctx);
  }

  for (i = 0; i < nslices; i++) {
    grpc_slice_unref(slices[i]);
  }
  gpr_free(slices);

  GPR_ASSERT(NULL == va_arg(chk.args, char *));

  va_end(chk.args);
}
Beispiel #3
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;
}
Beispiel #4
0
/* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly
 * cleaned up */
static void grpc_run_batch_stack_cleanup(run_batch_stack *st) {
  size_t i = 0;

  grpc_metadata_array_destroy(&st->send_metadata);
  grpc_metadata_array_destroy(&st->send_trailing_metadata);
  grpc_metadata_array_destroy(&st->recv_metadata);
  grpc_metadata_array_destroy(&st->recv_trailing_metadata);

  if (GRPC_SLICE_START_PTR(st->send_status_details) != NULL) {
    grpc_slice_unref(st->send_status_details);
  }

  if (GRPC_SLICE_START_PTR(st->recv_status_details) != NULL) {
    grpc_slice_unref(st->recv_status_details);
  }

  if (st->recv_message != NULL) {
    grpc_byte_buffer_destroy(st->recv_message);
  }

  for (i = 0; i < st->op_num; i++) {
    if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) {
      grpc_byte_buffer_destroy(st->ops[i].data.send_message.send_message);
    }
  }
}
Beispiel #5
0
static void test_load_small_file(void) {
  FILE *tmp = NULL;
  grpc_slice slice;
  grpc_slice slice_with_null_term;
  grpc_error *error;
  char *tmp_name;
  const char *blah = "blah";

  LOG_TEST_NAME("test_load_small_file");

  tmp = gpr_tmpfile(prefix, &tmp_name);
  GPR_ASSERT(tmp_name != NULL);
  GPR_ASSERT(tmp != NULL);
  GPR_ASSERT(fwrite(blah, 1, strlen(blah), tmp) == strlen(blah));
  fclose(tmp);

  error = grpc_load_file(tmp_name, 0, &slice);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == strlen(blah));
  GPR_ASSERT(!memcmp(GRPC_SLICE_START_PTR(slice), blah, strlen(blah)));

  error = grpc_load_file(tmp_name, 1, &slice_with_null_term);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice_with_null_term) == (strlen(blah) + 1));
  GPR_ASSERT(strcmp((const char *)GRPC_SLICE_START_PTR(slice_with_null_term),
                    blah) == 0);

  remove(tmp_name);
  gpr_free(tmp_name);
  grpc_slice_unref(slice);
  grpc_slice_unref(slice_with_null_term);
}
Beispiel #6
0
/* Asynchronous callback from the IOCP, or the background thread. */
static void on_read(grpc_exec_ctx *exec_ctx, void *tcpp, grpc_error *error) {
  grpc_tcp *tcp = tcpp;
  grpc_closure *cb = tcp->read_cb;
  grpc_winsocket *socket = tcp->socket;
  grpc_slice sub;
  grpc_winsocket_callback_info *info = &socket->read_info;

  GRPC_ERROR_REF(error);

  if (error == GRPC_ERROR_NONE) {
    if (info->wsa_error != 0 && !tcp->shutting_down) {
      char *utf8_message = gpr_format_message(info->wsa_error);
      error = GRPC_ERROR_CREATE(utf8_message);
      gpr_free(utf8_message);
      grpc_slice_unref(tcp->read_slice);
    } else {
      if (info->bytes_transfered != 0 && !tcp->shutting_down) {
        sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered);
        grpc_slice_buffer_add(tcp->read_slices, sub);
      } else {
        grpc_slice_unref(tcp->read_slice);
        error = GRPC_ERROR_CREATE("End of TCP stream");
      }
    }
  }

  tcp->read_cb = NULL;
  TCP_UNREF(exec_ctx, tcp, "read");
  grpc_exec_ctx_sched(exec_ctx, cb, error, NULL);
}
Beispiel #7
0
/* verify that the output generated by encoding the stream matches the
   hexstring passed in */
static void verify(size_t window_available, int eof, size_t expect_window_used,
                   const char *expected, size_t nheaders, ...) {
  grpc_slice_buffer output;
  grpc_slice merged;
  grpc_slice expect = parse_hexstring(expected);
  size_t i;
  va_list l;
  grpc_linked_mdelem *e = gpr_malloc(sizeof(*e) * nheaders);
  grpc_metadata_batch b;

  grpc_metadata_batch_init(&b);

  va_start(l, nheaders);
  for (i = 0; i < nheaders; i++) {
    char *key = va_arg(l, char *);
    char *value = va_arg(l, char *);
    if (i) {
      e[i - 1].next = &e[i];
      e[i].prev = &e[i - 1];
    }
    e[i].md = grpc_mdelem_from_strings(key, value);
  }
  e[0].prev = NULL;
  e[nheaders - 1].next = NULL;
  va_end(l);

  b.list.head = &e[0];
  b.list.tail = &e[nheaders - 1];

  if (cap_to_delete == num_to_delete) {
    cap_to_delete = GPR_MAX(2 * cap_to_delete, 1000);
    to_delete = gpr_realloc(to_delete, sizeof(*to_delete) * cap_to_delete);
  }
  to_delete[num_to_delete++] = e;

  grpc_slice_buffer_init(&output);

  grpc_transport_one_way_stats stats;
  memset(&stats, 0, sizeof(stats));
  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
                            &output);
  merged = grpc_slice_merge(output.slices, output.count);
  grpc_slice_buffer_destroy(&output);
  grpc_metadata_batch_destroy(&b);

  if (0 != grpc_slice_cmp(merged, expect)) {
    char *expect_str = grpc_dump_slice(expect, GPR_DUMP_HEX | GPR_DUMP_ASCII);
    char *got_str = grpc_dump_slice(merged, GPR_DUMP_HEX | GPR_DUMP_ASCII);
    gpr_log(GPR_ERROR, "mismatched output for %s", expected);
    gpr_log(GPR_ERROR, "EXPECT: %s", expect_str);
    gpr_log(GPR_ERROR, "GOT:    %s", got_str);
    gpr_free(expect_str);
    gpr_free(got_str);
    g_failure = 1;
  }

  grpc_slice_unref(merged);
  grpc_slice_unref(expect);
}
Beispiel #8
0
/*
 * Destroys keys, values and array->metadata.
 * The array pointer itself is not freed.
 */
void grpcsharp_metadata_array_destroy_metadata_including_entries(
    grpc_metadata_array* array) {
  size_t i;
  if (array->metadata) {
    for (i = 0; i < array->count; i++) {
      grpc_slice_unref(array->metadata[i].key);
      grpc_slice_unref(array->metadata[i].value);
    }
  }
  gpr_free(array->metadata);
}
Beispiel #9
0
void verifier_cb_ctx_destroy(verifier_cb_ctx *ctx) {
  if (ctx->audience != NULL) gpr_free(ctx->audience);
  if (ctx->claims != NULL) grpc_jwt_claims_destroy(ctx->claims);
  grpc_slice_unref(ctx->signature);
  grpc_slice_unref(ctx->signed_data);
  jose_header_destroy(ctx->header);
  for (size_t i = 0; i < HTTP_RESPONSE_COUNT; i++) {
    grpc_http_response_destroy(&ctx->responses[i]);
  }
  /* TODO: see what to do with claims... */
  gpr_free(ctx);
}
Beispiel #10
0
static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) {
  secure_endpoint *ep = secure_ep;
  grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep);
  tsi_frame_protector_destroy(ep->protector);
  grpc_slice_buffer_destroy(&ep->leftover_bytes);
  grpc_slice_unref(ep->read_staging_buffer);
  grpc_slice_unref(ep->write_staging_buffer);
  grpc_slice_buffer_destroy(&ep->output_buffer);
  grpc_slice_buffer_destroy(&ep->source_buffer);
  gpr_mu_destroy(&ep->protector_mu);
  gpr_free(ep);
}
Beispiel #11
0
static void expect_slice_eq(grpc_slice expected, grpc_slice slice, char *debug,
                            int line) {
  if (0 != grpc_slice_cmp(slice, expected)) {
    char *hs = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
    char *he = grpc_dump_slice(expected, GPR_DUMP_HEX | GPR_DUMP_ASCII);
    gpr_log(GPR_ERROR, "FAILED:%d: %s\ngot:  %s\nwant: %s", line, debug, hs,
            he);
    gpr_free(hs);
    gpr_free(he);
    all_ok = 0;
  }
  grpc_slice_unref(expected);
  grpc_slice_unref(slice);
}
Beispiel #12
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);
}
Beispiel #13
0
void create_jwt(const char *json_key_file_path, const char *service_url,
                const char *scope) {
  grpc_auth_json_key key;
  char *jwt;
  grpc_slice json_key_data;
  GPR_ASSERT(GRPC_LOG_IF_ERROR(
      "load_file", grpc_load_file(json_key_file_path, 1, &json_key_data)));
  key = grpc_auth_json_key_create_from_string(
      (const char *)GRPC_SLICE_START_PTR(json_key_data));
  grpc_slice_unref(json_key_data);
  if (!grpc_auth_json_key_is_valid(&key)) {
    fprintf(stderr, "Could not parse json key.\n");
    exit(1);
  }
  jwt = grpc_jwt_encode_and_sign(
      &key, service_url == NULL ? GRPC_JWT_OAUTH2_AUDIENCE : service_url,
      grpc_max_auth_token_lifetime(), scope);
  grpc_auth_json_key_destruct(&key);
  if (jwt == NULL) {
    fprintf(stderr, "Could not create JWT.\n");
    exit(1);
  }
  fprintf(stdout, "%s\n", jwt);
  gpr_free(jwt);
}
static void expect_slice_dump(grpc_slice slice, uint32_t flags,
                              const char *result) {
  char *got = grpc_dump_slice(slice, flags);
  GPR_ASSERT(0 == strcmp(got, result));
  gpr_free(got);
  grpc_slice_unref(slice);
}
/* 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);
}
Beispiel #16
0
static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) {
  grpc_endpoint_test_fixture f = config.create_fixture(slice_size);
  grpc_slice_buffer incoming;
  grpc_slice s =
      grpc_slice_from_copied_string("hello world 12345678900987654321");
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  int n = 0;
  grpc_closure done_closure;
  gpr_log(GPR_INFO, "Start test left over");

  grpc_slice_buffer_init(&incoming);
  grpc_closure_init(&done_closure, inc_call_ctr, &n);
  grpc_endpoint_read(&exec_ctx, f.client_ep, &incoming, &done_closure);
  grpc_exec_ctx_finish(&exec_ctx);
  GPR_ASSERT(n == 1);
  GPR_ASSERT(incoming.count == 1);
  GPR_ASSERT(0 == grpc_slice_cmp(s, incoming.slices[0]));

  grpc_endpoint_shutdown(&exec_ctx, f.client_ep);
  grpc_endpoint_shutdown(&exec_ctx, f.server_ep);
  grpc_endpoint_destroy(&exec_ctx, f.client_ep);
  grpc_endpoint_destroy(&exec_ctx, f.server_ep);
  grpc_exec_ctx_finish(&exec_ctx);
  grpc_slice_unref(s);
  grpc_slice_buffer_destroy(&incoming);

  clean_up();
}
Beispiel #17
0
static void test_load_big_file(void) {
  FILE *tmp = NULL;
  grpc_slice slice;
  grpc_error *error;
  char *tmp_name;
  static const size_t buffer_size = 124631;
  unsigned char *buffer = gpr_malloc(buffer_size);
  unsigned char *current;
  size_t i;

  LOG_TEST_NAME("test_load_big_file");

  memset(buffer, 42, buffer_size);

  tmp = gpr_tmpfile(prefix, &tmp_name);
  GPR_ASSERT(tmp != NULL);
  GPR_ASSERT(tmp_name != NULL);
  GPR_ASSERT(fwrite(buffer, 1, buffer_size, tmp) == buffer_size);
  fclose(tmp);

  error = grpc_load_file(tmp_name, 0, &slice);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == buffer_size);
  current = GRPC_SLICE_START_PTR(slice);
  for (i = 0; i < buffer_size; i++) {
    GPR_ASSERT(current[i] == 42);
  }

  remove(tmp_name);
  gpr_free(tmp_name);
  grpc_slice_unref(slice);
  gpr_free(buffer);
}
Beispiel #18
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;
}
Beispiel #19
0
static void check_values(const test_entry* input, size_t num_entries,
                         grpc_slice_hash_table* table) {
  for (size_t i = 0; i < num_entries; ++i) {
    grpc_slice key = grpc_slice_from_static_string(input[i].key);
    char* actual = grpc_slice_hash_table_get(table, key);
    GPR_ASSERT(actual != NULL);
    GPR_ASSERT(strcmp(actual, input[i].value) == 0);
    grpc_slice_unref(key);
  }
}
Beispiel #20
0
GPR_EXPORT grpc_call* GPR_CALLTYPE grpcsharp_channel_create_call(
    grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
    grpc_completion_queue* cq, const char* method, const char* host,
    gpr_timespec deadline) {
  grpc_slice method_slice = grpc_slice_from_copied_string(method);
  grpc_slice* host_slice_ptr = NULL;
  grpc_slice host_slice;
  if (host != NULL) {
    host_slice = grpc_slice_from_copied_string(host);
    host_slice_ptr = &host_slice;
  }
  grpc_call* ret =
      grpc_channel_create_call(channel, parent_call, propagation_mask, cq,
                               method_slice, host_slice_ptr, deadline, NULL);
  grpc_slice_unref(method_slice);
  if (host != NULL) {
    grpc_slice_unref(host_slice);
  }
  return ret;
}
Beispiel #21
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;
}
Beispiel #22
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);
}
Beispiel #23
0
static BIGNUM *bignum_from_base64(const char *b64) {
  BIGNUM *result = NULL;
  grpc_slice bin;

  if (b64 == NULL) return NULL;
  bin = grpc_base64_decode(b64, 1);
  if (GRPC_SLICE_IS_EMPTY(bin)) {
    gpr_log(GPR_ERROR, "Invalid base64 for big num.");
    return NULL;
  }
  result = BN_bin2bn(GRPC_SLICE_START_PTR(bin),
                     TSI_SIZE_AS_SIZE(GRPC_SLICE_LENGTH(bin)), NULL);
  grpc_slice_unref(bin);
  return result;
}
Beispiel #24
0
static int zlib_body(z_stream* zs, grpc_slice_buffer* input,
                     grpc_slice_buffer* output,
                     int (*flate)(z_stream* zs, int flush)) {
  int r;
  int flush;
  size_t i;
  grpc_slice outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
  const uInt uint_max = ~(uInt)0;

  GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
  zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf);
  zs->next_out = GRPC_SLICE_START_PTR(outbuf);
  flush = Z_NO_FLUSH;
  for (i = 0; i < input->count; i++) {
    if (i == input->count - 1) flush = Z_FINISH;
    GPR_ASSERT(GRPC_SLICE_LENGTH(input->slices[i]) <= uint_max);
    zs->avail_in = (uInt)GRPC_SLICE_LENGTH(input->slices[i]);
    zs->next_in = GRPC_SLICE_START_PTR(input->slices[i]);
    do {
      if (zs->avail_out == 0) {
        grpc_slice_buffer_add_indexed(output, outbuf);
        outbuf = grpc_slice_malloc(OUTPUT_BLOCK_SIZE);
        GPR_ASSERT(GRPC_SLICE_LENGTH(outbuf) <= uint_max);
        zs->avail_out = (uInt)GRPC_SLICE_LENGTH(outbuf);
        zs->next_out = GRPC_SLICE_START_PTR(outbuf);
      }
      r = flate(zs, flush);
      if (r < 0 && r != Z_BUF_ERROR /* not fatal */) {
        gpr_log(GPR_INFO, "zlib error (%d)", r);
        goto error;
      }
    } while (zs->avail_out == 0);
    if (zs->avail_in) {
      gpr_log(GPR_INFO, "zlib: not all input consumed");
      goto error;
    }
  }

  GPR_ASSERT(outbuf.refcount);
  outbuf.data.refcounted.length -= zs->avail_out;
  grpc_slice_buffer_add_indexed(output, outbuf);

  return 1;

error:
  grpc_slice_unref(outbuf);
  return 0;
}
Beispiel #25
0
grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader) {
  grpc_slice in_slice;
  size_t bytes_read = 0;
  const size_t input_size = grpc_byte_buffer_length(reader->buffer_out);
  grpc_slice out_slice = grpc_slice_malloc(input_size);
  uint8_t *const outbuf = GRPC_SLICE_START_PTR(out_slice); /* just an alias */

  while (grpc_byte_buffer_reader_next(reader, &in_slice) != 0) {
    const size_t slice_length = GRPC_SLICE_LENGTH(in_slice);
    memcpy(&(outbuf[bytes_read]), GRPC_SLICE_START_PTR(in_slice), slice_length);
    bytes_read += slice_length;
    grpc_slice_unref(in_slice);
    GPR_ASSERT(bytes_read <= input_size);
  }
  return out_slice;
}
Beispiel #26
0
static grpc_json *parse_json_part_from_jwt(const char *str, size_t len,
                                           grpc_slice *buffer) {
  grpc_json *json;

  *buffer = grpc_base64_decode_with_len(str, len, 1);
  if (GRPC_SLICE_IS_EMPTY(*buffer)) {
    gpr_log(GPR_ERROR, "Invalid base64.");
    return NULL;
  }
  json = grpc_json_parse_string_with_len((char *)GRPC_SLICE_START_PTR(*buffer),
                                         GRPC_SLICE_LENGTH(*buffer));
  if (json == NULL) {
    grpc_slice_unref(*buffer);
    gpr_log(GPR_ERROR, "JSON parsing error.");
  }
  return json;
}
Beispiel #27
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;
}
Beispiel #28
0
void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string,
                           size_t *out_length) {
  grpc_byte_buffer_reader reader;
  if (buffer == NULL || !grpc_byte_buffer_reader_init(&reader, buffer)) {
    /* TODO(dgq): distinguish between the error cases. */
    *out_string = NULL;
    *out_length = 0;
    return;
  }

  grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
  size_t length = GRPC_SLICE_LENGTH(slice);
  char *string = ecalloc(length + 1, sizeof(char));
  memcpy(string, GRPC_SLICE_START_PTR(slice), length);
  grpc_slice_unref(slice);

  *out_string = string;
  *out_length = length;
}
Beispiel #29
0
static void parse_query_parts(grpc_uri *uri) {
  static const char *QUERY_PARTS_SEPARATOR = "&";
  static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
  GPR_ASSERT(uri->query != NULL);
  if (uri->query[0] == '\0') {
    uri->query_parts = NULL;
    uri->query_parts_values = NULL;
    uri->num_query_parts = 0;
    return;
  }
  grpc_slice query_slice =
      grpc_slice_new(uri->query, strlen(uri->query), do_nothing);
  grpc_slice_buffer query_parts; /* the &-separated elements of the query */
  grpc_slice_buffer query_param_parts; /* the =-separated subelements */

  grpc_slice_buffer_init(&query_parts);
  grpc_slice_buffer_init(&query_param_parts);

  grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
  uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
  uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
  uri->num_query_parts = query_parts.count;
  for (size_t i = 0; i < query_parts.count; i++) {
    grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
                     &query_param_parts);
    GPR_ASSERT(query_param_parts.count > 0);
    uri->query_parts[i] =
        grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
    if (query_param_parts.count > 1) {
      /* TODO(dgq): only the first value after the separator is considered.
       * Perhaps all chars after the first separator for the query part should
       * be included, even if they include the separator. */
      uri->query_parts_values[i] =
          grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
    } else {
      uri->query_parts_values[i] = NULL;
    }
    grpc_slice_buffer_reset_and_unref(&query_param_parts);
  }
  grpc_slice_buffer_destroy(&query_parts);
  grpc_slice_buffer_destroy(&query_param_parts);
  grpc_slice_unref(query_slice);
}
Beispiel #30
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;
}