Exemplo n.º 1
0
grpc_call *grpc_channel_create_registered_call(
    grpc_channel *channel, grpc_completion_queue *completion_queue,
    void *registered_call_handle, gpr_timespec deadline) {
  registered_call *rc = registered_call_handle;
  return grpc_channel_create_call_internal(
      channel, completion_queue, grpc_mdelem_ref(rc->path),
      grpc_mdelem_ref(rc->authority), deadline);
}
Exemplo n.º 2
0
static void jwt_get_request_metadata(grpc_credentials *creds,
                                     const char *service_url,
                                     grpc_credentials_metadata_cb cb,
                                     void *user_data) {
  grpc_jwt_credentials *c = (grpc_jwt_credentials *)creds;
  gpr_timespec refresh_threshold = {GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS,
                                    0};

  /* See if we can return a cached jwt. */
  grpc_mdelem *jwt_md = NULL;
  {
    gpr_mu_lock(&c->cache_mu);
    if (c->cached.service_url != NULL &&
        strcmp(c->cached.service_url, service_url) == 0 &&
        c->cached.jwt_md != NULL &&
        (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now()),
                      refresh_threshold) > 0)) {
      jwt_md = grpc_mdelem_ref(c->cached.jwt_md);
    }
    gpr_mu_unlock(&c->cache_mu);
  }

  if (jwt_md == NULL) {
    char *jwt = NULL;
    /* Generate a new jwt. */
    gpr_mu_lock(&c->cache_mu);
    jwt_reset_cache(c);
    jwt = grpc_jwt_encode_and_sign(&c->key, service_url, c->jwt_lifetime, NULL);
    if (jwt != NULL) {
      char *md_value;
      gpr_asprintf(&md_value, "Bearer %s", jwt);
      gpr_free(jwt);
      c->cached.jwt_expiration = gpr_time_add(gpr_now(), c->jwt_lifetime);
      c->cached.service_url = gpr_strdup(service_url);
      c->cached.jwt_md = grpc_mdelem_from_strings(
          c->md_ctx, GRPC_AUTHORIZATION_METADATA_KEY, md_value);
      gpr_free(md_value);
      jwt_md = grpc_mdelem_ref(c->cached.jwt_md);
    }
    gpr_mu_unlock(&c->cache_mu);
  }

  if (jwt_md != NULL) {
    cb(user_data, &jwt_md, 1, GRPC_CREDENTIALS_OK);
    grpc_mdelem_unref(jwt_md);
  } else {
    cb(user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
  }
}
Exemplo n.º 3
0
static void hs_mutate_op(grpc_call_element *elem, grpc_transport_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *channeld = elem->channel_data;
  size_t i;

  if (op->send_ops && !calld->sent_status) {
    size_t nops = op->send_ops->nops;
    grpc_stream_op *ops = op->send_ops->ops;
    for (i = 0; i < nops; i++) {
      grpc_stream_op *op = &ops[i];
      if (op->type != GRPC_OP_METADATA) continue;
      calld->sent_status = 1;
      grpc_metadata_batch_add_head(&op->data.metadata, &calld->status,
                                   grpc_mdelem_ref(channeld->status_ok));
      break;
    }
  }

  if (op->recv_ops && !calld->got_initial_metadata) {
    /* substitute our callback for the higher callback */
    calld->recv_ops = op->recv_ops;
    calld->on_done_recv = op->on_done_recv;
    calld->recv_user_data = op->recv_user_data;
    op->on_done_recv = hs_on_recv;
    op->recv_user_data = elem;
  }
}
Exemplo n.º 4
0
static void oauth2_token_fetcher_get_request_metadata(
    grpc_credentials *creds, const char *service_url,
    grpc_credentials_metadata_cb cb, void *user_data) {
  grpc_oauth2_token_fetcher_credentials *c =
      (grpc_oauth2_token_fetcher_credentials *)creds;
  gpr_timespec refresh_threshold = {GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS,
                                    0};
  grpc_mdelem *cached_access_token_md = NULL;
  {
    gpr_mu_lock(&c->mu);
    if (c->access_token_md != NULL &&
        (gpr_time_cmp(gpr_time_sub(c->token_expiration, gpr_now()),
                      refresh_threshold) > 0)) {
      cached_access_token_md = grpc_mdelem_ref(c->access_token_md);
    }
    gpr_mu_unlock(&c->mu);
  }
  if (cached_access_token_md != NULL) {
    cb(user_data, &cached_access_token_md, 1, GRPC_CREDENTIALS_OK);
    grpc_mdelem_unref(cached_access_token_md);
  } else {
    c->fetch_func(
        grpc_credentials_metadata_request_create(creds, cb, user_data),
        on_oauth2_token_fetcher_http_response,
        gpr_time_add(gpr_now(), refresh_threshold));
  }
}
Exemplo n.º 5
0
/* Called either:
     - in response to an API call (or similar) from above, to send something
     - a network event (or similar) from below, to receive something
   op contains type and call direction information, in addition to the data
   that is being sent or received. */
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
                    grpc_call_op *op) {
  /* grab pointers to our data from the call element */
  call_data *calld = elem->call_data;
  channel_data *channeld = elem->channel_data;
  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);

  switch (op->type) {
    case GRPC_RECV_METADATA:
      grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
      if (!calld->got_initial_metadata) {
        calld->got_initial_metadata = 1;
        /* Have we seen the required http2 transport headers?
           (:method, :scheme, content-type, with :path and :authority covered
           at the channel level right now) */
        if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers &&
            calld->seen_path) {
          grpc_call_next_op(elem, op);
        } else {
          if (!calld->seen_path) {
            gpr_log(GPR_ERROR, "Missing :path header");
          }
          if (!calld->seen_post) {
            gpr_log(GPR_ERROR, "Missing :method header");
          }
          if (!calld->seen_scheme) {
            gpr_log(GPR_ERROR, "Missing :scheme header");
          }
          if (!calld->seen_te_trailers) {
            gpr_log(GPR_ERROR, "Missing te trailers header");
          }
          /* Error this call out */
          grpc_metadata_batch_destroy(&op->data.metadata);
          op->done_cb(op->user_data, GRPC_OP_OK);
          grpc_call_element_send_cancel(elem);
        }
      } else {
        grpc_call_next_op(elem, op);
      }
      break;
    case GRPC_SEND_METADATA:
      /* If we haven't sent status 200 yet, we need to so so because it needs to
         come before any non : prefixed metadata. */
      if (!calld->sent_status) {
        calld->sent_status = 1;
        grpc_metadata_batch_add_head(&op->data.metadata, &calld->status,
                                     grpc_mdelem_ref(channeld->status_ok));
      }
      grpc_call_next_op(elem, op);
      break;
    default:
      /* pass control up or down the stack depending on op->dir */
      grpc_call_next_op(elem, op);
      break;
  }
}
Exemplo n.º 6
0
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
                    grpc_call_op *op) {
  channel_data *channeld = elem->channel_data;
  GRPC_CALL_LOG_OP(GPR_INFO, elem, op);

  switch (op->type) {
    case GRPC_SEND_START:
      grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->status));
      grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->message));
      grpc_call_stream_closed(elem);
      break;
    case GRPC_SEND_METADATA:
      grpc_mdelem_unref(op->data.metadata);
      break;
    default:
      break;
  }

  op->done_cb(op->user_data, GRPC_OP_ERROR);
}
Exemplo n.º 7
0
grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
  if (i >= 0 && i < NUM_CACHED_STATUS_ELEMS) {
    return grpc_mdelem_ref(channel->grpc_status_elem[i]);
  } else {
    char tmp[GPR_LTOA_MIN_BUFSIZE];
    gpr_ltoa(i, tmp);
    return grpc_mdelem_from_metadata_strings(
        channel->metadata_context, grpc_mdstr_ref(channel->grpc_status_string),
        grpc_mdstr_from_string(channel->metadata_context, tmp));
  }
}
Exemplo n.º 8
0
static void send_up_cancelled_ops(grpc_call_element *elem) {
  grpc_call_op finish_op;
  channel_data *chand = elem->channel_data;
  /* send up a synthesized status */
  finish_op.type = GRPC_RECV_METADATA;
  finish_op.dir = GRPC_CALL_UP;
  finish_op.flags = 0;
  finish_op.data.metadata = grpc_mdelem_ref(chand->cancel_status);
  finish_op.done_cb = do_nothing;
  finish_op.user_data = NULL;
  grpc_call_next_op(elem, &finish_op);
  /* send up a finish */
  finish_op.type = GRPC_RECV_FINISH;
  finish_op.dir = GRPC_CALL_UP;
  finish_op.flags = 0;
  finish_op.done_cb = do_nothing;
  finish_op.user_data = NULL;
  grpc_call_next_op(elem, &finish_op);
}
Exemplo n.º 9
0
static void composite_metadata_cb(void *user_data, grpc_mdelem **md_elems,
                                  size_t num_md,
                                  grpc_credentials_status status) {
  grpc_composite_credentials_metadata_context *ctx =
      (grpc_composite_credentials_metadata_context *)user_data;
  size_t i;
  if (status != GRPC_CREDENTIALS_OK) {
    ctx->cb(ctx->user_data, NULL, 0, status);
    return;
  }

  /* Copy the metadata in the context. */
  if (num_md > 0) {
    ctx->md_elems = gpr_realloc(ctx->md_elems,
                                (ctx->num_md + num_md) * sizeof(grpc_mdelem *));
    for (i = 0; i < num_md; i++) {
      ctx->md_elems[i + ctx->num_md] = grpc_mdelem_ref(md_elems[i]);
    }
    ctx->num_md += num_md;
  }

  /* See if we need to get some more metadata. */
  while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
    grpc_credentials *inner_creds =
        ctx->composite_creds->inner.creds_array[ctx->creds_index++];
    if (grpc_credentials_has_request_metadata(inner_creds)) {
      grpc_credentials_get_request_metadata(inner_creds, ctx->service_url,
                                            composite_metadata_cb, ctx);
      return;
    }
  }

  /* We're done!. */
  ctx->cb(ctx->user_data, ctx->md_elems, ctx->num_md, GRPC_CREDENTIALS_OK);
  composite_md_context_destroy(ctx);
}