|
|
|
@ -45,6 +45,44 @@ |
|
|
|
|
// The protobuf library will (by default) start warning at 100 megs.
|
|
|
|
|
#define DEFAULT_MAX_RECV_MESSAGE_LENGTH (4 * 1024 * 1024) |
|
|
|
|
|
|
|
|
|
typedef struct message_size_limits { |
|
|
|
|
int max_send_size; |
|
|
|
|
int max_recv_size; |
|
|
|
|
} message_size_limits; |
|
|
|
|
|
|
|
|
|
static void* message_size_limits_copy(void* value) { |
|
|
|
|
void* new_value = gpr_malloc(sizeof(message_size_limits)); |
|
|
|
|
memcpy(new_value, value, sizeof(message_size_limits)); |
|
|
|
|
return new_value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int message_size_limits_cmp(void* value1, void* value2) { |
|
|
|
|
const message_size_limits* v1 = value1; |
|
|
|
|
const message_size_limits* v2 = value2; |
|
|
|
|
if (v1->max_send_size > v2->max_send_size) return 1; |
|
|
|
|
if (v1->max_send_size < v2->max_send_size) return -1; |
|
|
|
|
if (v1->max_recv_size > v2->max_recv_size) return 1; |
|
|
|
|
if (v1->max_recv_size < v2->max_recv_size) return -1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = { |
|
|
|
|
gpr_free, message_size_limits_copy, message_size_limits_cmp}; |
|
|
|
|
|
|
|
|
|
static void* method_config_convert_value( |
|
|
|
|
const grpc_method_config* method_config) { |
|
|
|
|
message_size_limits* value = gpr_malloc(sizeof(message_size_limits)); |
|
|
|
|
const int32_t* max_request_message_bytes = |
|
|
|
|
grpc_method_config_get_max_request_message_bytes(method_config); |
|
|
|
|
value->max_send_size = |
|
|
|
|
max_request_message_bytes != NULL ? *max_request_message_bytes : -1; |
|
|
|
|
const int32_t* max_response_message_bytes = |
|
|
|
|
grpc_method_config_get_max_response_message_bytes(method_config); |
|
|
|
|
value->max_recv_size = |
|
|
|
|
max_response_message_bytes != NULL ? *max_response_message_bytes : -1; |
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct call_data { |
|
|
|
|
int max_send_size; |
|
|
|
|
int max_recv_size; |
|
|
|
@ -61,8 +99,8 @@ typedef struct call_data { |
|
|
|
|
typedef struct channel_data { |
|
|
|
|
int max_send_size; |
|
|
|
|
int max_recv_size; |
|
|
|
|
// Method config table.
|
|
|
|
|
grpc_method_config_table* method_config_table; |
|
|
|
|
// Maps path names to message_size_limits structs.
|
|
|
|
|
grpc_mdstr_hash_table* method_limit_table; |
|
|
|
|
} channel_data; |
|
|
|
|
|
|
|
|
|
// Callback invoked when we receive a message. Here we check the max
|
|
|
|
@ -132,24 +170,19 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx, |
|
|
|
|
// size to the receive limit.
|
|
|
|
|
calld->max_send_size = chand->max_send_size; |
|
|
|
|
calld->max_recv_size = chand->max_recv_size; |
|
|
|
|
if (chand->method_config_table != NULL) { |
|
|
|
|
grpc_method_config* method_config = |
|
|
|
|
grpc_method_config_table_get_method_config(chand->method_config_table, |
|
|
|
|
args->path); |
|
|
|
|
if (method_config != NULL) { |
|
|
|
|
const int32_t* max_request_message_bytes = |
|
|
|
|
grpc_method_config_get_max_request_message_bytes(method_config); |
|
|
|
|
if (max_request_message_bytes != NULL && |
|
|
|
|
(*max_request_message_bytes < calld->max_send_size || |
|
|
|
|
if (chand->method_limit_table != NULL) { |
|
|
|
|
message_size_limits* limits = |
|
|
|
|
grpc_method_config_table_get(chand->method_limit_table, args->path); |
|
|
|
|
if (limits != NULL) { |
|
|
|
|
if (limits->max_send_size >= 0 && |
|
|
|
|
(limits->max_send_size < calld->max_send_size || |
|
|
|
|
calld->max_send_size < 0)) { |
|
|
|
|
calld->max_send_size = *max_request_message_bytes; |
|
|
|
|
calld->max_send_size = limits->max_send_size; |
|
|
|
|
} |
|
|
|
|
const int32_t* max_response_message_bytes = |
|
|
|
|
grpc_method_config_get_max_response_message_bytes(method_config); |
|
|
|
|
if (max_response_message_bytes != NULL && |
|
|
|
|
(*max_response_message_bytes < calld->max_recv_size || |
|
|
|
|
if (limits->max_recv_size >= 0 && |
|
|
|
|
(limits->max_recv_size < calld->max_recv_size || |
|
|
|
|
calld->max_recv_size < 0)) { |
|
|
|
|
calld->max_recv_size = *max_response_message_bytes; |
|
|
|
|
calld->max_recv_size = limits->max_recv_size; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -191,8 +224,9 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx, |
|
|
|
|
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); |
|
|
|
|
if (channel_arg != NULL) { |
|
|
|
|
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); |
|
|
|
|
chand->method_config_table = grpc_method_config_table_ref( |
|
|
|
|
(grpc_method_config_table*)channel_arg->value.pointer.p); |
|
|
|
|
chand->method_limit_table = grpc_method_config_table_convert( |
|
|
|
|
(grpc_method_config_table*)channel_arg->value.pointer.p, |
|
|
|
|
method_config_convert_value, &message_size_limits_vtable); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -200,7 +234,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx, |
|
|
|
|
static void destroy_channel_elem(grpc_exec_ctx* exec_ctx, |
|
|
|
|
grpc_channel_element* elem) { |
|
|
|
|
channel_data* chand = elem->channel_data; |
|
|
|
|
grpc_method_config_table_unref(chand->method_config_table); |
|
|
|
|
grpc_mdstr_hash_table_unref(chand->method_limit_table); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const grpc_channel_filter grpc_message_size_filter = { |
|
|
|
|