|
|
|
@ -37,8 +37,8 @@ |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
|
|
|
|
|
|
#include "src/core/ext/filters/workarounds/workaround_utils.h" |
|
|
|
|
#include "src/core/lib/surface/channel_init.h" |
|
|
|
|
#include "src/core/lib/channel/channel_stack_builder.h" |
|
|
|
|
#include "src/core/lib/surface/channel_init.h" |
|
|
|
|
#include "src/core/lib/transport/metadata.h" |
|
|
|
|
|
|
|
|
|
typedef struct call_data { |
|
|
|
@ -74,8 +74,8 @@ static bool get_user_agent_mdelem(const grpc_metadata_batch *batch, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Callback invoked when we receive an initial metadata.
|
|
|
|
|
static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, void* user_data, |
|
|
|
|
grpc_error* error) { |
|
|
|
|
static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, |
|
|
|
|
void* user_data, grpc_error* error) { |
|
|
|
|
grpc_call_element* elem = user_data; |
|
|
|
|
call_data* calld = elem->call_data; |
|
|
|
|
|
|
|
|
@ -83,7 +83,8 @@ static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, void* user_data |
|
|
|
|
grpc_mdelem md; |
|
|
|
|
if (get_user_agent_mdelem(calld->recv_initial_metadata, &md)) { |
|
|
|
|
grpc_user_agent_md* user_agent_md = grpc_parse_user_agent(md); |
|
|
|
|
if (user_agent_md->workaround_active[GRPC_WORKAROUND_ID_CRONET_COMPRESSION]) { |
|
|
|
|
if (user_agent_md |
|
|
|
|
->workaround_active[GRPC_WORKAROUND_ID_CRONET_COMPRESSION]) { |
|
|
|
|
calld->workaround_active = true; |
|
|
|
|
} |
|
|
|
|
// Remove with caching
|
|
|
|
@ -92,7 +93,8 @@ static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, void* user_data |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Invoke the next callback.
|
|
|
|
|
grpc_closure_run(exec_ctx, calld->next_recv_initial_metadata_ready, GRPC_ERROR_REF(error)); |
|
|
|
|
grpc_closure_run(exec_ctx, calld->next_recv_initial_metadata_ready, |
|
|
|
|
GRPC_ERROR_REF(error)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Start transport stream op.
|
|
|
|
@ -105,8 +107,17 @@ static void start_transport_stream_op_batch( |
|
|
|
|
if (op->recv_initial_metadata) { |
|
|
|
|
calld->next_recv_initial_metadata_ready = |
|
|
|
|
op->payload->recv_initial_metadata.recv_initial_metadata_ready; |
|
|
|
|
op->payload->recv_initial_metadata.recv_initial_metadata_ready = &calld->recv_initial_metadata_ready; |
|
|
|
|
calld->recv_initial_metadata = op->payload->recv_initial_metadata.recv_initial_metadata; |
|
|
|
|
op->payload->recv_initial_metadata.recv_initial_metadata_ready = |
|
|
|
|
&calld->recv_initial_metadata_ready; |
|
|
|
|
calld->recv_initial_metadata = |
|
|
|
|
op->payload->recv_initial_metadata.recv_initial_metadata; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (op->send_message) { |
|
|
|
|
/* Send message happens after client's user-agent (initial metadata) is received, so workaround_active must be set already */ |
|
|
|
|
if (calld->workaround_active) { |
|
|
|
|
op->payload->send_message.send_message->flags |= GRPC_WRITE_NO_COMPRESS; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Chain to the next filter.
|
|
|
|
@ -120,7 +131,8 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx, |
|
|
|
|
call_data* calld = elem->call_data; |
|
|
|
|
calld->next_recv_initial_metadata_ready = NULL; |
|
|
|
|
calld->workaround_active = false; |
|
|
|
|
grpc_closure_init(&calld->recv_initial_metadata_ready, recv_initial_metadata_ready, elem, |
|
|
|
|
grpc_closure_init(&calld->recv_initial_metadata_ready, |
|
|
|
|
recv_initial_metadata_ready, elem, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
return GRPC_ERROR_NONE; |
|
|
|
|
} |
|
|
|
@ -173,8 +185,7 @@ static bool parse_user_agent(grpc_mdelem md) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_free(user_agent_str); |
|
|
|
|
return (grpc_objc_specifier_seen && |
|
|
|
|
cronet_specifier_seen && |
|
|
|
|
return (grpc_objc_specifier_seen && cronet_specifier_seen && |
|
|
|
|
(atol(major_version) < 1 || |
|
|
|
|
(atol(major_version) == 1 && atol(minor_version) <= 3))); |
|
|
|
|
} |
|
|
|
@ -193,9 +204,8 @@ const grpc_channel_filter grpc_workaround_cronet_compression_filter = { |
|
|
|
|
grpc_channel_next_get_info, |
|
|
|
|
"workaround_cronet_compression"}; |
|
|
|
|
|
|
|
|
|
static bool register_workaround_cronet_compression(grpc_exec_ctx* exec_ctx, |
|
|
|
|
grpc_channel_stack_builder* builder, |
|
|
|
|
void* arg) { |
|
|
|
|
static bool register_workaround_cronet_compression( |
|
|
|
|
grpc_exec_ctx* exec_ctx, grpc_channel_stack_builder* builder, void* arg) { |
|
|
|
|
grpc_register_workaround(GRPC_WORKAROUND_ID_CRONET_COMPRESSION, |
|
|
|
|
parse_user_agent); |
|
|
|
|
return grpc_channel_stack_builder_prepend_filter( |
|
|
|
@ -203,8 +213,8 @@ static bool register_workaround_cronet_compression(grpc_exec_ctx* exec_ctx, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_workaround_cronet_compression_filter_init(void) { |
|
|
|
|
grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, |
|
|
|
|
GRPC_WORKAROUND_PRIORITY_HIGH, |
|
|
|
|
grpc_channel_init_register_stage( |
|
|
|
|
GRPC_SERVER_CHANNEL, GRPC_WORKAROUND_PRIORITY_HIGH, |
|
|
|
|
register_workaround_cronet_compression, NULL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|