-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Title: Enovy as forward proxy doesn't pass query parameters from request
Description:
I found a problem with envoy as forward proxy for egress traffic. When I am doing request to another service through envoy, query parameters are missing.
Example:
On my localhost I have envoy running with 2 listeners ingress and egress.
So when I am doing request with curl through envoy to cluster my-service:
curl -x localhost:6002 "http://my-service/test?username=test" -v
in logs I can see that my request failed because there is missing query parameter username
envoy_wrapper_1 | [envoy][2019-04-02 08:32:44.022][33][debug][http] [source/common/http/conn_manager_impl.cc:576] [C11][S4906893650903990186] request headers complete (end_stream=true):
envoy_wrapper_1 | ':authority', 'my-service'
envoy_wrapper_1 | ':path', '/test'
envoy_wrapper_1 | ':method', 'GET'
envoy_wrapper_1 | 'user-agent', 'curl/7.54.0'
envoy_wrapper_1 | 'accept', '*/*'
envoy_wrapper_1 | 'proxy-connection', 'Keep-Alive'
envoy_wrapper_1 |
envoy_wrapper_1 | [envoy][2019-04-02 08:32:44.022][33][debug][http] [source/common/http/conn_manager_impl.cc:1021] [C11][S4906893650903990186] request end stream
envoy_wrapper_1 | [envoy][2019-04-02 08:32:44.022][33][debug][router] [source/common/router/router.cc:320] [C11][S4906893650903990186] cluster 'my-service' match for URL '/test'
envoy_wrapper_1 | [envoy][2019-04-02 08:32:44.022][33][debug][router] [source/common/router/router.cc:381] [C11][S4906893650903990186] router decoding headers:
envoy_wrapper_1 | ':authority', 'myservice'
envoy_wrapper_1 | ':path', '/test'
envoy_wrapper_1 | ':method', 'GET'
envoy_wrapper_1 | ':scheme', 'http'
envoy_wrapper_1 | 'user-agent', 'curl/7.54.0'
envoy_wrapper_1 | 'accept', '*/*'
envoy_wrapper_1 | 'x-forwarded-proto', 'http'
envoy_wrapper_1 | 'x-request-id', 'bf18935a-bdb2-4cf4-9825-7cb127bd7285'
envoy_wrapper_1 | 'x-envoy-expected-rq-timeout-ms', '15000'
envoy_wrapper_1 | [envoy][2019-04-02 08:32:44.067][33][debug][http] [source/common/http/conn_manager_impl.cc:1256] [C11][S4906893650903990186] encoding headers via codec (end_stream=false):
envoy_wrapper_1 | ':status', '400'
envoy_wrapper_1 | 'access-control-allow-origin', '*'
envoy_wrapper_1 | 'access-control-allow-headers', 'origin, Content-Type, Accept, Authorization'
envoy_wrapper_1 | 'content-type', 'application/json;charset=UTF-8'
envoy_wrapper_1 | 'access-control-allow-methods', 'POST, PUT, GET, OPTIONS, DELETE'
envoy_wrapper_1 | 'access-control-max-age', '3600'
envoy_wrapper_1 | 'date', 'Tue, 02 Apr 2019 08:32:43 GMT'
envoy_wrapper_1 | 'x-envoy-upstream-service-time', '44'
envoy_wrapper_1 | 'server', 'envoy'
But if I make request:
curl -H "host: my-service" "http://localhost:6002/test?username=test" -v
everything works fine.
envoy_wrapper_1 | ':authority', 'my-service'
envoy_wrapper_1 | ':path', '/test?username=test'
envoy_wrapper_1 | ':method', 'GET'
envoy_wrapper_1 | 'user-agent', 'curl/7.54.0'
envoy_wrapper_1 | 'accept', '*/*'
envoy_wrapper_1 | 'accept-language', 'pl'
envoy_wrapper_1 |
envoy_wrapper_1 | [envoy][2019-04-02 08:37:11.909][35][debug][http] [source/common/http/conn_manager_impl.cc:1021] [C15][S14347542195339788614] request end stream
envoy_wrapper_1 | [envoy][2019-04-02 08:37:11.909][35][debug][router] [source/common/router/router.cc:320] [C15][S14347542195339788614] cluster 'my-service' match for URL '/test?username=test'
envoy_wrapper_1 | [envoy][2019-04-02 08:37:11.909][35][debug][router] [source/common/router/router.cc:381] [C15][S14347542195339788614] router decoding headers:
envoy_wrapper_1 | ':authority', 'my-service'
envoy_wrapper_1 | ':path', '/test?username=test'
envoy_wrapper_1 | ':method', 'GET'
envoy_wrapper_1 | ':scheme', 'http'
envoy_wrapper_1 | 'user-agent', 'curl/7.54.0'
envoy_wrapper_1 | 'accept', '*/*'
envoy_wrapper_1 | 'accept-language', 'pl'
envoy_wrapper_1 | 'x-forwarded-proto', 'http'
envoy_wrapper_1 | 'x-request-id', '65c9abab-ba2d-494e-ad60-c79e286181cb'
envoy_wrapper_1 | 'x-envoy-expected-rq-timeout-ms', '15000'
envoy_wrapper_1 | ':status', '200'
envoy_wrapper_1 | 'access-control-allow-origin', '*'
envoy_wrapper_1 | 'access-control-allow-headers', 'origin, Content-Type, Accept, Authorization'
envoy_wrapper_1 | 'content-type', 'application/json;charset=UTF-8'
envoy_wrapper_1 | 'access-control-allow-methods', 'POST, PUT, GET, OPTIONS, DELETE'
envoy_wrapper_1 | 'access-control-max-age', '3600'
envoy_wrapper_1 | 'date', 'Tue, 02 Apr 2019 08:37:11 GMT'
envoy_wrapper_1 | 'x-envoy-upstream-service-time', '146'
envoy_wrapper_1 | 'server', 'envoy'
Config
This is my route config
"name": "default_routes",
"virtual_hosts": [
{
"name": "my-service",
"domains": [
"my-service"
],
"routes": [
{
"match": {
"prefix": "/"
},
"route": {
"cluster": "my-service"
}
}
]
}]
}
Egress listener config
{
"listener": {
"name": "egress_listener",
"address": {
"socket_address": {
"address": "0.0.0.0",
"port_value": 6002
}
},
"filter_chains": [
{
"filters": [
{
"name": "envoy.http_connection_manager",
"config": {
"access_log": [],
"http_filters": [
{
"name": "envoy.router"
}
],
"http_protocol_options": {
"allow_absolute_url": true
},
"rds": {
"route_config_name": "default_routes",
"config_source": {
"ads": {},
"initial_fetch_timeout": "20s"
}
},
"stat_prefix": "egress_http"
}
}
]
}
If you need same more information I am ready to help.
Also edited test in envoy which fails bazel test //test/common/http/http1:codec_impl_test(when I changed expected_headers : {":path", "/foo/bar"} test passed ) :
TEST_F(Http1ServerConnectionImplTest, Http11AbsolutePathWithPort) {
TestHeaderMapImpl expected_headers{
{":authority", "www.somewhere.com:4532"}, {":path", "/foo/bar?test=test"}, {":method", "GET"}};
Buffer::OwnedImpl buffer(
"GET http://www.somewhere.com:4532/foo/bar?test=test HTTP/1.1\r\nHost: bah\r\n\r\n");
expectHeadersTest(Protocol::Http11, true, buffer, expected_headers);
}
[ RUN ] Http1ServerConnectionImplTest.Http11AbsolutePathWithPort
unknown file: Failure
Unexpected mock function call - returning directly.
Function call: decodeHeaders_(@0x7fd2df00c5f0 0x7fd2df00d140, true)
Google Mock tried the following 1 expectation, but it didn't match:
test/common/http/http1/codec_impl_test.cc:86: EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_headers), true))...
Expected arg #0: header map equal 0x7ffee47b3d40
Actual: 0x7fd2df00d140
Expected: to be called once
Actual: never called - unsatisfied and active
test/common/http/http1/codec_impl_test.cc:86: Failure
Actual function call count doesn't match EXPECT_CALL(decoder, decodeHeaders_(HeaderMapEqual(&expected_headers), true))...
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] Http1ServerConnectionImplTest.Http11AbsolutePathWithPort