diff --git a/src/nginx/grpc.cc b/src/nginx/grpc.cc index 113d55fee..b6f54d3a3 100644 --- a/src/nginx/grpc.cc +++ b/src/nginx/grpc.cc @@ -93,8 +93,14 @@ std::pair> GrpcGetStub( return std::make_pair(Status::OK, it->second); } - auto result = std::make_shared<::grpc::GenericStub>( - ::grpc::CreateChannel(address, ::grpc::InsecureChannelCredentials())); + ::grpc::ChannelArguments channel_arguments; + + channel_arguments.SetMaxReceiveMessageSize(INT_MAX); + channel_arguments.SetMaxSendMessageSize(INT_MAX); + + auto result = + std::make_shared<::grpc::GenericStub>(::grpc::CreateCustomChannel( + address, ::grpc::InsecureChannelCredentials(), channel_arguments)); if (result) { espcf->grpc_stubs.emplace(address, result); diff --git a/src/nginx/t/BUILD b/src/nginx/t/BUILD index f6fe32939..ddd6243cd 100644 --- a/src/nginx/t/BUILD +++ b/src/nginx/t/BUILD @@ -110,6 +110,7 @@ nginx_suite( "grpc_grpc_fallback.t", "grpc_grpc_override.t", "grpc_large_request.t", + "grpc_large_response.t", "grpc_large_streaming.t", "grpc_long_streaming.t", "grpc_metadata.t", diff --git a/src/nginx/t/grpc_large_response.t b/src/nginx/t/grpc_large_response.t new file mode 100644 index 000000000..31b512a7d --- /dev/null +++ b/src/nginx/t/grpc_large_response.t @@ -0,0 +1,120 @@ +# Copyright (C) Extensible Service Proxy Authors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +################################################################################ +# +use strict; +use warnings; + +################################################################################ + +use src::nginx::t::ApiManager; # Must be first (sets up import path to the Nginx test module) +use src::nginx::t::HttpServer; +use Test::Nginx; # Imports Nginx's test module +use Test::More; # And the test framework + +################################################################################ + +# Port assignments +my $Http2NginxPort = ApiManager::pick_port(); +my $ServiceControlPort = ApiManager::pick_port(); +my $GrpcBackendPort = ApiManager::pick_port(); + +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(4); + +$t->write_file('service.pb.txt', ApiManager::get_grpc_test_service_config($GrpcBackendPort) . <<"EOF"); +control { + environment: "http://127.0.0.1:${ServiceControlPort}" +} +EOF + +$t->write_file_expand('nginx.conf', <<"EOF"); +%%TEST_GLOBALS%% +daemon off; +events { + worker_connections 32; +} +http { + %%TEST_GLOBALS_HTTP%% + server { + listen 127.0.0.1:${Http2NginxPort} http2; + server_name localhost; + client_max_body_size 32m; + location / { + endpoints { + api service.pb.txt; + on; + } + grpc_pass 127.0.0.2:${GrpcBackendPort}; + } + } +} +EOF + +$t->run_daemon(\&service_control, $t, $ServiceControlPort, 'requests.log'); +$t->run_daemon(\&ApiManager::grpc_test_server, $t, "127.0.0.1:${GrpcBackendPort}"); +is($t->waitforsocket("127.0.0.1:${ServiceControlPort}"), 1, 'Service control socket ready.'); +is($t->waitforsocket("127.0.0.1:${GrpcBackendPort}"), 1, 'GRPC test server socket ready.'); +$t->run(); +is($t->waitforsocket("127.0.0.1:${Http2NginxPort}"), 1, 'Nginx socket ready.'); + +################################################################################ +my $test_results = &ApiManager::run_grpc_test($t, <<"EOF"); +server_addr: "127.0.0.1:${Http2NginxPort}" +plans { + echo { + call_config { + api_key: "this-is-an-api-key" + } + request { + space_payload_size: 30000000 + } + } +} +EOF + +$t->stop_daemons(); + +like($test_results, qr/echo \{/, "Test returned error"); + +################################################################################ + +sub service_control { + my ($t, $port, $file) = @_; + my $server = HttpServer->new($port, $t->testdir() . '/' . $file) + or die "Can't create test server socket: $!\n"; + + $server->on_sub('POST', '/v1/services/endpoints-grpc-test.cloudendpointsapis.com:check', sub { + my ($headers, $body, $client) = @_; + print $client <<'EOF'; +HTTP/1.1 200 OK +Connection: close + +EOF + }); + + $server->run(); +} + +################################################################################ diff --git a/test/grpc/client-test-lib.cc b/test/grpc/client-test-lib.cc index eb85ee204..1fbf87a6d 100644 --- a/test/grpc/client-test-lib.cc +++ b/test/grpc/client-test-lib.cc @@ -46,13 +46,14 @@ using ::google::api::servicecontrol::v1::ReportRequest; using ::google::protobuf::util::MessageDifferencer; using ::grpc::Alarm; using ::grpc::Channel; +using ::grpc::ChannelArguments; using ::grpc::ChannelCredentials; using ::grpc::ClientContext; using ::grpc::ClientAsyncReaderWriterInterface; using ::grpc::ClientAsyncResponseReaderInterface; using ::grpc::ClientReaderWriter; using ::grpc::CompletionQueue; -using ::grpc::CreateChannel; +using ::grpc::CreateCustomChannel; using ::grpc::InsecureChannelCredentials; using ::grpc::SslCredentials; using ::grpc::SslCredentialsOptions; @@ -92,7 +93,11 @@ std::shared_ptr GetCreds(const EchoStreamTest &desc) { template static std::unique_ptr GetStub(const std::string &addr, const T &desc) { - std::shared_ptr channel(CreateChannel(addr, GetCreds(desc))); + ChannelArguments args; + args.SetMaxReceiveMessageSize(INT_MAX); + args.SetMaxSendMessageSize(INT_MAX); + std::shared_ptr channel( + CreateCustomChannel(addr, GetCreds(desc), args)); return std::unique_ptr(Test::NewStub(channel)); } @@ -220,6 +225,10 @@ class Echo { desc_.mutable_request()->set_text( RandomString(desc_.request().random_payload_max_size())); } + if (desc_.request().space_payload_size() > 0) { + desc_.mutable_request()->set_text( + std::string(desc_.request().space_payload_size(), ' ')); + } } EchoTest desc_; diff --git a/test/grpc/grpc-test-server.cc b/test/grpc/grpc-test-server.cc index de96e198f..f020004d6 100644 --- a/test/grpc/grpc-test-server.cc +++ b/test/grpc/grpc-test-server.cc @@ -360,6 +360,8 @@ void TestServer::Run(const char *addr) { ServerBuilder builder; builder.AddListeningPort(addr, InsecureServerCredentials()); builder.RegisterService(this); + builder.SetMaxReceiveMessageSize(INT_MAX); + builder.SetMaxSendMessageSize(INT_MAX); cq_ = builder.AddCompletionQueue(); std::unique_ptr server(builder.BuildAndStart()); diff --git a/test/grpc/grpc-test.proto b/test/grpc/grpc-test.proto index 3db36e026..fd3d66acb 100644 --- a/test/grpc/grpc-test.proto +++ b/test/grpc/grpc-test.proto @@ -44,6 +44,10 @@ message EchoRequest { // The payload size is random between 0 and value of this field. int32 random_payload_max_size = 3; + // If non 0, the text payload is generated with space characters + // The payload size is specified by the value of this field. + int32 space_payload_size = 6; + // The metadata that server should return map return_initial_metadata = 4; map return_trailing_metadata = 5;