diff --git a/src/api_manager/config_test.cc b/src/api_manager/config_test.cc index 68bc420df..9053193da 100644 --- a/src/api_manager/config_test.cc +++ b/src/api_manager/config_test.cc @@ -479,15 +479,23 @@ static const char backends_config[] = "name: \"backends-config\"\n" "backend {\n" " rules {\n" - " selector: \"test.api.MethodWithBackend\"\n" + " selector: \"test.api.MethodWithBackendConstant\"\n" " address: \"TestBackend:TestPort\"\n" " path_translation: CONSTANT_ADDRESS\n" " }\n" + " rules {\n" + " selector: \"test.api.MethodWithBackendAppend\"\n" + " address: \"TestBackend:TestPort\"\n" + " path_translation: APPEND_PATH_TO_ADDRESS\n" + " }\n" "}\n" "apis {\n" " name: \"test.api\"\n" " methods {\n" - " name: \"MethodWithBackend\"\n" + " name: \"MethodWithBackendConstant\"\n" + " }\n" + " methods {\n" + " name: \"MethodWithBackendAppend\"\n" " }\n" " methods {\n" " name: \"MethodWithoutBackend\"\n" @@ -501,11 +509,19 @@ TEST(Config, LoadBackends) { ASSERT_TRUE(config); const MethodInfo *method_with_backend = - config->GetMethodInfo("POST", "/test.api/MethodWithBackend"); + config->GetMethodInfo("POST", "/test.api/MethodWithBackendConstant"); ASSERT_NE(nullptr, method_with_backend); EXPECT_EQ("TestBackend:TestPort", method_with_backend->backend_address()); + EXPECT_EQ("/", method_with_backend->backend_path()); EXPECT_EQ(1, method_with_backend->backend_path_translation()); + method_with_backend = + config->GetMethodInfo("POST", "/test.api/MethodWithBackendAppend"); + ASSERT_NE(nullptr, method_with_backend); + EXPECT_EQ("TestBackend:TestPort", method_with_backend->backend_address()); + EXPECT_EQ("", method_with_backend->backend_path()); + EXPECT_EQ(2, method_with_backend->backend_path_translation()); + const MethodInfo *method_without_backend = config->GetMethodInfo("POST", "/test.api/MethodWithoutBackend"); ASSERT_NE(nullptr, method_without_backend); diff --git a/src/api_manager/method_impl.cc b/src/api_manager/method_impl.cc index 8cc4b87b9..bfb7dd1a8 100644 --- a/src/api_manager/method_impl.cc +++ b/src/api_manager/method_impl.cc @@ -134,6 +134,14 @@ void MethodInfoImpl::process_backend_rule( backend_path_ = backend_address_.substr(i); backend_address_ = backend_address_.substr(0, i); } + + // For constant_address, backend_path should not be empty. + // An empty backend_path should be treated as "/". + if (backend_path_.empty() && + backend_path_translation_ == + ::google::api::BackendRule_PathTranslation_CONSTANT_ADDRESS) { + backend_path_ = "/"; + } } void MethodInfoImpl::process_system_parameters() { diff --git a/src/api_manager/method_test.cc b/src/api_manager/method_test.cc index 7ea6a3454..5f5452d44 100644 --- a/src/api_manager/method_test.cc +++ b/src/api_manager/method_test.cc @@ -156,7 +156,7 @@ TEST(MethodInfo, PreservesBackendAddress_Constant2) { method_info->process_backend_rule(rule); ASSERT_EQ(method_info->backend_address(), "http://example.cloudfunctions.net"); - ASSERT_EQ(method_info->backend_path(), ""); + ASSERT_EQ(method_info->backend_path(), "/"); ASSERT_EQ(method_info->backend_jwt_audience(), ""); } @@ -168,7 +168,7 @@ TEST(MethodInfo, PreservesBackendAddress_Constant3) { ::google::api::BackendRule_PathTranslation_CONSTANT_ADDRESS); method_info->process_backend_rule(rule); ASSERT_EQ(method_info->backend_address(), "backend"); - ASSERT_EQ(method_info->backend_path(), ""); + ASSERT_EQ(method_info->backend_path(), "/"); } TEST(MethodInfo, PreservesBackendAddress_Append) { diff --git a/src/nginx/t/backend_routing_constant_address.t b/src/nginx/t/backend_routing_constant_address.t index eaf1d1c55..2b6f78313 100644 --- a/src/nginx/t/backend_routing_constant_address.t +++ b/src/nginx/t/backend_routing_constant_address.t @@ -42,7 +42,7 @@ my $BackendPort = ApiManager::pick_port(); my $ServiceControlPort = ApiManager::pick_port(); my $MetadataPort = ApiManager::pick_port(); -my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(18); +my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(20); # Save service name in the service configuration protocol buffer file. @@ -77,6 +77,12 @@ backend { path_translation: CONSTANT_ADDRESS jwt_audience: "test-audience" } + rules { + selector: "ListAllBooks" + address: "http://127.0.0.1:$BackendPort" + path_translation: CONSTANT_ADDRESS + jwt_audience: "test-audience" + } } types { fields { @@ -156,6 +162,9 @@ my $response4 = ApiManager::http_get($NginxPort,'/shelves/123/books/info/1234?ke # also, {foo.bar} style path is supported. my $response5 = ApiManager::http_get($NginxPort,'/shelves/123/books/id/1234?key=this-is-an-api-key'); +# Test address only has host name. +my $response6 = ApiManager::http_get($NginxPort,'/allbooks'); + $t->stop_daemons(); my ($response_headers1, $response_body1) = split /\r\n\r\n/, $response1, 2; @@ -195,9 +204,15 @@ is($response_body5, <<'EOF', 'Book Info returned in the response body.'); { "id": "1234" } EOF +my ($response_headers6, $response_body6) = split /\r\n\r\n/, $response6, 2; +like($response_headers6, qr/HTTP\/1\.1 200 OK/, 'Returned HTTP 200.'); +is($response_body6, <<'EOF', 'ListAllBooks returned in the response body.'); +{ "allbooks" } +EOF + # Check Authorization header is added into requests. my @bookstore_requests = ApiManager::read_http_stream($t, 'bookstore.log'); -is(scalar @bookstore_requests, 5, 'Bookstore received 5 requests.'); +is(scalar @bookstore_requests, 6, 'Bookstore received 6 requests.'); my $request = shift @bookstore_requests; is($request->{headers}->{'authorization'}, 'Bearer test_audience_override', @@ -263,6 +278,13 @@ HTTP/1.1 200 OK Connection: close { "id": "1234" } +EOF + + $server->on('GET', '/', <<'EOF'); +HTTP/1.1 200 OK +Connection: close + +{ "allbooks" } EOF $server->run(); diff --git a/src/nginx/t/testdata/bookstore_allow_all_http_requests.pb.txt b/src/nginx/t/testdata/bookstore_allow_all_http_requests.pb.txt index dc4159f0b..bbe7260bc 100644 --- a/src/nginx/t/testdata/bookstore_allow_all_http_requests.pb.txt +++ b/src/nginx/t/testdata/bookstore_allow_all_http_requests.pb.txt @@ -4,6 +4,10 @@ http { selector: "ListShelves" get: "/shelves" } + rules { + selector: "ListAllBooks" + get: "/allbooks" + } rules { selector: "CorsShelves" custom: { @@ -64,6 +68,10 @@ usage { selector: "GetShelf" allow_unregistered_calls: true } + rules { + selector: "ListAllBooks" + allow_unregistered_calls: true + } rules { selector: "ListBooks" allow_unregistered_calls: false