prep work for enabling caching
Added new header grpc-payload-bin
Added new channel arg for setting max payload size
Ability to create a GET request in client filter
Ability to parse the payload from header in server filter.
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index a7a775c..8725618 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -50,6 +50,7 @@
grpc_linked_mdelem te_trailers;
grpc_linked_mdelem content_type;
grpc_linked_mdelem user_agent;
+ grpc_linked_mdelem payload_bin;
grpc_metadata_batch *recv_initial_metadata;
@@ -64,6 +65,7 @@
typedef struct channel_data {
grpc_mdelem *static_scheme;
grpc_mdelem *user_agent;
+ size_t max_payload_size_for_get;
} channel_data;
typedef struct {
@@ -134,17 +136,43 @@
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
+
+ /* Decide which HTTP VERB to use */
+ grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
+ if ((op->send_initial_metadata_flags &
+ GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
+ op->send_message != NULL &&
+ op->send_message->length < channeld->max_payload_size_for_get) {
+ method = GRPC_MDELEM_METHOD_GET;
+ } else if (op->send_initial_metadata_flags &
+ GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
+ method = GRPC_MDELEM_METHOD_PUT;
+ }
+
+ if (method == GRPC_MDELEM_METHOD_GET) {
+ gpr_slice slice;
+ /* TODO (makdharma): extend code for messages with multiple slices */
+ if (grpc_byte_stream_next(NULL, op->send_message, &slice,
+ op->send_message->length, NULL)) {
+ grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
+ GRPC_MDSTR_GRPC_PAYLOAD_BIN,
+ grpc_mdstr_from_buffer(GPR_SLICE_START_PTR(slice),
+ GPR_SLICE_LENGTH(slice)));
+ grpc_metadata_batch_add_tail(op->send_initial_metadata,
+ &calld->payload_bin, payload_bin);
+ } else {
+ gpr_log(GPR_ERROR, "send_message could not be read");
+ }
+ op->send_message = NULL;
+ }
+
if (op->send_initial_metadata != NULL) {
grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
elem);
/* Send : prefixed headers, which have to be before any application
layer headers. */
- grpc_metadata_batch_add_head(
- op->send_initial_metadata, &calld->method,
- op->send_initial_metadata_flags &
- GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
- ? GRPC_MDELEM_METHOD_PUT
- : GRPC_MDELEM_METHOD_POST);
+ grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
+ method);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
channeld->static_scheme);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
@@ -210,6 +238,22 @@
return GRPC_MDELEM_SCHEME_HTTP;
}
+static size_t max_payload_size_from_args(const grpc_channel_args *args) {
+ if (args != NULL) {
+ for (size_t i = 0; i < args->num_args; ++i) {
+ if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET)) {
+ if (args->args[i].type != GRPC_ARG_INTEGER) {
+ gpr_log(GPR_ERROR, "%s: must be an integer",
+ GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET);
+ } else {
+ return args->args[i].value.integer;
+ }
+ }
+ }
+ }
+ return kMaxPayloadSizeForGet;
+}
+
static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
const char *transport_name) {
gpr_strvec v;
@@ -267,6 +311,8 @@
GPR_ASSERT(!args->is_last);
GPR_ASSERT(args->optional_transport != NULL);
chand->static_scheme = scheme_from_args(args->channel_args);
+ chand->max_payload_size_for_get =
+ max_payload_size_from_args(args->channel_args);
chand->user_agent = grpc_mdelem_from_metadata_strings(
GRPC_MDSTR_USER_AGENT,
user_agent_from_args(args->channel_args,