static void plugin_md_request_metadata_ready(void *request,
                                             const grpc_metadata *md,
                                             size_t num_md,
                                             grpc_status_code status,
                                             const char *error_details) {
  /* called from application code */
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request;
  if (status != GRPC_STATUS_OK) {
    if (error_details != NULL) {
      gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s",
              error_details);
    }
    r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
          error_details);
  } else {
    size_t i;
    bool seen_illegal_header = false;
    grpc_credentials_md *md_array = NULL;
    for (i = 0; i < num_md; i++) {
      if (!grpc_header_key_is_legal(md[i].key, strlen(md[i].key))) {
        gpr_log(GPR_ERROR, "Plugin added invalid metadata key: %s", md[i].key);
        seen_illegal_header = true;
        break;
      } else if (!grpc_is_binary_header(md[i].key, strlen(md[i].key)) &&
                 !grpc_header_nonbin_value_is_legal(md[i].value,
                                                    md[i].value_length)) {
        gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
        seen_illegal_header = true;
        break;
      }
    }
    if (seen_illegal_header) {
      r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR,
            "Illegal metadata");
    } else if (num_md > 0) {
      md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md));
      for (i = 0; i < num_md; i++) {
        md_array[i].key = gpr_slice_from_copied_string(md[i].key);
        md_array[i].value =
            gpr_slice_from_copied_buffer(md[i].value, md[i].value_length);
      }
      r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK,
            NULL);
      for (i = 0; i < num_md; i++) {
        gpr_slice_unref(md_array[i].key);
        gpr_slice_unref(md_array[i].value);
      }
      gpr_free(md_array);
    }
  }
  gpr_free(r);
  grpc_exec_ctx_finish(&exec_ctx);
}
Exemple #2
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;
}
Exemple #3
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;
  char *key_str;
  size_t key_len;
  char *value_str;
  size_t value_len;

  if (TYPE(key) == T_SYMBOL) {
    key_str = (char *)rb_id2name(SYM2ID(key));
    key_len = strlen(key_str);
  } else { /* StringValueCStr does all other type exclusions for us */
    key_str = StringValueCStr(key);
    key_len = RSTRING_LEN(key);
  }

  if (!grpc_header_key_is_legal(key_str, key_len)) {
    rb_raise(rb_eArgError,
             "'%s' is an invalid header key, must match [a-z0-9-_.]+",
             key_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_str = RSTRING_PTR(rb_ary_entry(val, i));
      value_len = RSTRING_LEN(rb_ary_entry(val, i));
      if (!grpc_is_binary_header(key_str, key_len) &&
          !grpc_header_nonbin_value_is_legal(value_str, value_len)) {
        // The value has invalid characters
        rb_raise(rb_eArgError,
                 "Header value '%s' has invalid characters", value_str);
        return ST_STOP;
      }
      md_ary->metadata[md_ary->count].key = key_str;
      md_ary->metadata[md_ary->count].value = value_str;
      md_ary->metadata[md_ary->count].value_length = value_len;
      md_ary->count += 1;
    }
  } else {
    value_str = RSTRING_PTR(val);
    value_len = RSTRING_LEN(val);
    if (!grpc_is_binary_header(key_str, key_len) &&
        !grpc_header_nonbin_value_is_legal(value_str, value_len)) {
      // The value has invalid characters
      rb_raise(rb_eArgError,
               "Header value '%s' has invalid characters", value_str);
      return ST_STOP;
    }
    md_ary->metadata[md_ary->count].key = key_str;
    md_ary->metadata[md_ary->count].value = value_str;
    md_ary->metadata[md_ary->count].value_length = value_len;
    md_ary->count += 1;
  }

  return ST_CONTINUE;
}