mirror of https://github.com/grpc/grpc.git
parent
1213682122
commit
c7c0d69d8b
30 changed files with 331 additions and 350 deletions
@ -0,0 +1,117 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2017 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <assert.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/channel/client_authority_filter.h" |
||||
#include "src/core/lib/gpr/string.h" |
||||
#include "src/core/lib/slice/slice_internal.h" |
||||
#include "src/core/lib/slice/slice_string_helpers.h" |
||||
#include "src/core/lib/surface/call.h" |
||||
#include "src/core/lib/surface/channel_init.h" |
||||
#include "src/core/lib/surface/channel_stack_type.h" |
||||
#include "src/core/lib/transport/static_metadata.h" |
||||
|
||||
namespace { |
||||
|
||||
struct call_data { |
||||
grpc_linked_mdelem authority_storage; |
||||
grpc_call_combiner* call_combiner; |
||||
}; |
||||
|
||||
struct channel_data { |
||||
grpc_slice default_authority; |
||||
}; |
||||
|
||||
void authority_start_transport_stream_op_batch( |
||||
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { |
||||
channel_data* chand = static_cast<channel_data*>(elem->channel_data); |
||||
call_data* calld = static_cast<call_data*>(elem->call_data); |
||||
// Handle send_initial_metadata.
|
||||
auto* initial_metadata = |
||||
batch->payload->send_initial_metadata.send_initial_metadata; |
||||
// If the initial metadata doesn't already contain :authority, add it.
|
||||
if (batch->send_initial_metadata && |
||||
initial_metadata->idx.named.authority == nullptr) { |
||||
grpc_error* error = grpc_metadata_batch_add_head( |
||||
initial_metadata, &calld->authority_storage, |
||||
grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY, |
||||
grpc_slice_ref(chand->default_authority))); |
||||
if (error != GRPC_ERROR_NONE) { |
||||
grpc_transport_stream_op_batch_finish_with_failure(batch, error, |
||||
calld->call_combiner); |
||||
return; |
||||
} |
||||
} |
||||
// Pass control down the stack.
|
||||
grpc_call_next_op(elem, batch); |
||||
} |
||||
|
||||
/* Constructor for call_data */ |
||||
grpc_error* init_call_elem(grpc_call_element* elem, |
||||
const grpc_call_element_args* args) { |
||||
call_data* calld = static_cast<call_data*>(elem->call_data); |
||||
calld->call_combiner = args->call_combiner; |
||||
return GRPC_ERROR_NONE; |
||||
} |
||||
|
||||
/* Destructor for call_data */ |
||||
void destroy_call_elem(grpc_call_element* elem, |
||||
const grpc_call_final_info* final_info, |
||||
grpc_closure* ignored) {} |
||||
|
||||
/* Constructor for channel_data */ |
||||
grpc_error* init_channel_elem(grpc_channel_element* elem, |
||||
grpc_channel_element_args* args) { |
||||
channel_data* chand = static_cast<channel_data*>(elem->channel_data); |
||||
const grpc_arg* default_authority_arg = |
||||
grpc_channel_args_find(args->channel_args, GRPC_ARG_DEFAULT_AUTHORITY); |
||||
GPR_ASSERT(default_authority_arg != nullptr); |
||||
chand->default_authority = grpc_slice_from_copied_string( |
||||
grpc_channel_arg_get_string(default_authority_arg)); |
||||
GPR_ASSERT(!args->is_last); |
||||
return GRPC_ERROR_NONE; |
||||
} |
||||
|
||||
/* Destructor for channel data */ |
||||
void destroy_channel_elem(grpc_channel_element* elem) { |
||||
channel_data* chand = static_cast<channel_data*>(elem->channel_data); |
||||
grpc_slice_unref(chand->default_authority); |
||||
} |
||||
} // namespace
|
||||
|
||||
const grpc_channel_filter grpc_client_authority_filter = { |
||||
authority_start_transport_stream_op_batch, |
||||
grpc_channel_next_op, |
||||
sizeof(call_data), |
||||
init_call_elem, |
||||
grpc_call_stack_ignore_set_pollset_or_pollset_set, |
||||
destroy_call_elem, |
||||
sizeof(channel_data), |
||||
init_channel_elem, |
||||
destroy_channel_elem, |
||||
grpc_channel_next_get_info, |
||||
"authority"}; |
@ -0,0 +1,34 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2017 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_CHANNEL_CLIENT_AUTHORITY_FILTER_H |
||||
#define GRPC_CORE_LIB_CHANNEL_CLIENT_AUTHORITY_FILTER_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/impl/codegen/compression_types.h> |
||||
|
||||
#include "src/core/lib/channel/channel_stack.h" |
||||
|
||||
/// Filter responsible for setting the authority header, if not already set. It
|
||||
/// uses the value of the GRPC_ARG_DEFAULT_AUTHORITY channel arg if the initial
|
||||
/// metadata doesn't already contain an authority value.
|
||||
|
||||
extern const grpc_channel_filter grpc_client_authority_filter; |
||||
|
||||
#endif /* GRPC_CORE_LIB_CHANNEL_CLIENT_AUTHORITY_FILTER_H */ |
@ -1,137 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
static char* g_last_log_error_message = nullptr; |
||||
static const char* g_file_name = "channel.cc"; |
||||
|
||||
static int ends_with(const char* src, const char* suffix) { |
||||
size_t src_len = strlen(src); |
||||
size_t suffix_len = strlen(suffix); |
||||
if (src_len < suffix_len) { |
||||
return 0; |
||||
} |
||||
return strcmp(src + src_len - suffix_len, suffix) == 0; |
||||
} |
||||
|
||||
static void log_error_sink(gpr_log_func_args* args) { |
||||
if (args->severity == GPR_LOG_SEVERITY_ERROR && |
||||
ends_with(args->file, g_file_name)) { |
||||
g_last_log_error_message = gpr_strdup(args->message); |
||||
} |
||||
} |
||||
|
||||
static void verify_last_error(const char* message) { |
||||
if (message == nullptr) { |
||||
GPR_ASSERT(g_last_log_error_message == nullptr); |
||||
return; |
||||
} |
||||
GPR_ASSERT(strcmp(message, g_last_log_error_message) == 0); |
||||
gpr_free(g_last_log_error_message); |
||||
g_last_log_error_message = nullptr; |
||||
} |
||||
|
||||
static char* compose_error_string(const char* key, const char* message) { |
||||
char* ret; |
||||
gpr_asprintf(&ret, "%s%s", key, message); |
||||
return ret; |
||||
} |
||||
|
||||
static void one_test(grpc_channel_args* args, char* expected_error_message) { |
||||
grpc_channel* chan = |
||||
grpc_insecure_channel_create("nonexistant:54321", args, nullptr); |
||||
verify_last_error(expected_error_message); |
||||
gpr_free(expected_error_message); |
||||
grpc_channel_destroy(chan); |
||||
} |
||||
|
||||
static void test_no_error_message(void) { one_test(nullptr, nullptr); } |
||||
|
||||
static void test_default_authority_type(void) { |
||||
grpc_arg client_arg; |
||||
grpc_channel_args client_args; |
||||
char* expected_error_message; |
||||
|
||||
client_arg.type = GRPC_ARG_INTEGER; |
||||
client_arg.key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY); |
||||
client_arg.value.integer = 0; |
||||
|
||||
client_args.num_args = 1; |
||||
client_args.args = &client_arg; |
||||
expected_error_message = compose_error_string( |
||||
GRPC_ARG_DEFAULT_AUTHORITY, " ignored: it must be a string"); |
||||
one_test(&client_args, expected_error_message); |
||||
} |
||||
|
||||
static void test_ssl_name_override_type(void) { |
||||
grpc_arg client_arg; |
||||
grpc_channel_args client_args; |
||||
char* expected_error_message; |
||||
|
||||
client_arg.type = GRPC_ARG_INTEGER; |
||||
client_arg.key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); |
||||
client_arg.value.integer = 0; |
||||
|
||||
client_args.num_args = 1; |
||||
client_args.args = &client_arg; |
||||
expected_error_message = compose_error_string( |
||||
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, " ignored: it must be a string"); |
||||
one_test(&client_args, expected_error_message); |
||||
} |
||||
|
||||
static void test_ssl_name_override_failed(void) { |
||||
grpc_arg client_arg[2]; |
||||
grpc_channel_args client_args; |
||||
char* expected_error_message; |
||||
|
||||
client_arg[0].type = GRPC_ARG_STRING; |
||||
client_arg[0].key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY); |
||||
client_arg[0].value.string = const_cast<char*>("default"); |
||||
client_arg[1].type = GRPC_ARG_STRING; |
||||
client_arg[1].key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); |
||||
client_arg[1].value.string = const_cast<char*>("ssl"); |
||||
|
||||
client_args.num_args = 2; |
||||
client_args.args = client_arg; |
||||
expected_error_message = |
||||
compose_error_string(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, |
||||
" ignored: default host already set some other way"); |
||||
one_test(&client_args, expected_error_message); |
||||
} |
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc_test_init(argc, argv); |
||||
grpc_init(); |
||||
gpr_set_log_function(log_error_sink); |
||||
|
||||
test_no_error_message(); |
||||
test_default_authority_type(); |
||||
test_ssl_name_override_type(); |
||||
test_ssl_name_override_failed(); |
||||
|
||||
grpc_shutdown(); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue