router: send response_headers_to_add with direct responses#2458
router: send response_headers_to_add with direct responses#2458mattklein123 merged 9 commits intoenvoyproxy:masterfrom brian-pane:direct-response-headers/2315
Conversation
*Description*: Send any configured `response_headers_to_add` with direct responses. *Risk Level*: Medium *Testing*: New integration test included *Docs Changes*: TODO *Release Notes*: Included in this PR *Fixes*: #2315 *API Changes*: envoyproxy/data-plane-api#393 Signed-off-by: Brian Pane <bpane@pinterest.com>
|
I still need to write the documentation for this feature. I'll make a doc PR and link to it here. |
source/common/router/router.cc
Outdated
| config_.stats_.rq_redirect_.inc(); | ||
| Http::Utility::sendRedirect(*callbacks_, route_->directResponseEntry()->newPath(headers), | ||
| response_code); | ||
| Http::Utility::sendRedirect(*callbacks_, direct_response->newPath(headers), response_code); |
There was a problem hiding this comment.
Is there a reason why 3xx responses don't get extra headers and response body?
There was a problem hiding this comment.
That's for backward compatibility. The implementations of the new direct-response feature and the existing redirect feature were merged in PR2335, at the request of the reviewers. Thus, if we were to send the extra headers with 3xx responses, it could change the behavior of users' existing Envoy configurations.
There was a problem hiding this comment.
Suggestion here (without full review): I still think we could probably pull the trigger and just do it in all cases and no one would notice, but if we feel that we shouldn't do that, I would put the fact that we are deprecating the old behavior in DEPRECATED.md and put a comment here. We can remove the guard in the next release.
There was a problem hiding this comment.
Hmm, sending the headers and response body in all cases would definitely yield a more consistent feature. I'll update this PR to make 3xx work the same way as all other response statuses.
…mit to both file and inline response bodies Signed-off-by: Brian Pane <bpane@pinterest.com>
mattklein123
left a comment
There was a problem hiding this comment.
Generally looks great to me. A few minor comments. Thank you!
| virtual ~ResponseEntry() {} | ||
|
|
||
| /** | ||
| * Do potentially destructive header transforms on response headers prior to forwarding. For |
source/common/router/router.cc
Outdated
| return Http::FilterHeadersStatus::StopIteration; | ||
| } | ||
| const auto* direct_response = route_->directResponseEntry(); | ||
| const auto& request_headers = headers; |
There was a problem hiding this comment.
why do you need this variable? Is this just for the capture? can you just capture the headers reference directly?
There was a problem hiding this comment.
The lambda has its own function parameter named headers, so this is just an alias to prevent a name collision.
There was a problem hiding this comment.
ah OK. FYI you can use C++14 lambda capture expression to define this variable inline in the capture which is a bit cleaner.
source/common/router/router.cc
Outdated
| bool end_stream) -> void { | ||
| const auto new_path = direct_response->newPath(request_headers); | ||
| if (!new_path.empty()) { | ||
| headers->addCopy(Http::LowerCaseString("location"), new_path); |
There was a problem hiding this comment.
You can do this using O(1) headers by doing a variant of headers->insertLocation()...
There was a problem hiding this comment.
It looks like Location isn't configured as one of the O(1) headers in header_map.h. I suppose I could add it, but it looks like each new header configured for O(1) access adds another pointer field to the HeaderMapImpl ... is it okay to increase the size of that structure?
There was a problem hiding this comment.
Ah OK, sorry. It's not a big deal either way. But you can use the constant that is already in Http::Headers and then addReferenceKey
| EXPECT_EQ(Http::Code::OK, direct_response->responseCode()); | ||
| EXPECT_STREQ("content", direct_response->responseBody().c_str()); | ||
|
|
||
| std::string response_body(4097, 'A'); |
There was a problem hiding this comment.
nit: I might split this into a separate test with a more obvious name.
| } | ||
| } | ||
|
|
||
| TEST(RouteConfigurationV2, DirectResponse) { |
There was a problem hiding this comment.
For new tests please add a // comment with a brief description of what the test does.
Signed-off-by: Brian Pane <bpane@pinterest.com>
Signed-off-by: Brian Pane <bpane@pinterest.com>
alyssawilk
left a comment
There was a problem hiding this comment.
Looks good - only two questions on my end.
| auto response_code = route_->directResponseEntry()->responseCode(); | ||
| if (response_code >= Http::Code::MultipleChoices && response_code < Http::Code::BadRequest) { | ||
| config_.stats_.rq_redirect_.inc(); | ||
| Http::Utility::sendRedirect(*callbacks_, route_->directResponseEntry()->newPath(headers), |
There was a problem hiding this comment.
can we remove sendRedirect with this PR?
source/common/router/router.cc
Outdated
| sendLocalReply(route_->directResponseEntry()->responseCode(), | ||
| route_->directResponseEntry()->responseBody(), false); | ||
| // TODO(brian-pane) support sending response_headers_to_add. | ||
| Http::Utility::sendLocalReply( |
There was a problem hiding this comment.
This is very similar to the existing Filter::sendLocalReply. Could we extend that instead?
There was a problem hiding this comment.
Yes, I think I have a way to make that work. Update coming soon.
There was a problem hiding this comment.
I removed the overloaded parameter from Http::Filter::sendLocalReply and replaced it with a more general callback hook to modify the headers. That made the couple of existing calls to that method more verbose, but I think it's a net improvement.
Signed-off-by: Brian Pane <bpane@pinterest.com>
Signed-off-by: Brian Pane <bpane@pinterest.com>
|
Did you miss one user of the function? It looks like some of the builds are unhappy. |
Signed-off-by: Brian Pane <bpane@pinterest.com>
source/common/router/router.cc
Outdated
| ->void { | ||
| const auto new_path = direct_response->newPath(request_headers); | ||
| if (!new_path.empty()) { | ||
| response_headers.addCopy(Http::LowerCaseString("location"), new_path); |
There was a problem hiding this comment.
My previous comment on this still needs action just in case it got lost (switch to addReferenceKey and use the constant in the headers class).
There was a problem hiding this comment.
There isn't a constant for location in the headers class:
$ egrep -ir location include/envoy/http
$ echo $?
1
$
There was a problem hiding this comment.
Oh, wait you mean the other headers class, the one in source/common/http.
There was a problem hiding this comment.
Yes, sorry, was going to provide you link. Basically just look at how it's being used in the other redirect code.
…eaders/2315 Conflicts: RAW_RELEASE_NOTES.md source/common/router/config_utility.cc Signed-off-by: Brian Pane <bpane@pinterest.com>
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for the refactor and adding comments! LGTM modulo one final nit.
source/common/router/router.h
Outdated
| * @param code supplies the HTTP status code. | ||
| * @param body supplies the response body (empty string if no body is needed). | ||
| * @param add_headers supplies an optional callback function that can add additional | ||
| * headers to the response. |
There was a problem hiding this comment.
that can alter the headers in the response
since it could also theoretically remove or just change, yeah?
Signed-off-by: Brian Pane <bpane@pinterest.com>
* add usage of stackdriver logger and test * add stat prefix * add metrics and only export at server * remove timeseries.go * fix test due to merge conflict
Signed-off-by: JP Simard <jp@jpsim.com>
Signed-off-by: JP Simard <jp@jpsim.com>
Description:
Send any configured
response_headers_to_addwith direct responses.Risk Level: Medium
Testing: New integration test included
Docs Changes: envoyproxy/data-plane-api#436
Release Notes: Included in this PR
Fixes: #2315
API Changes: envoyproxy/data-plane-api#393
Signed-off-by: Brian Pane bpane@pinterest.com