Skip to content

http: Internal redirects with request body#15634

Merged
snowp merged 34 commits intoenvoyproxy:mainfrom
derekargueta:internal-redirects-with-request-body
Apr 8, 2021
Merged

http: Internal redirects with request body#15634
snowp merged 34 commits intoenvoyproxy:mainfrom
derekargueta:internal-redirects-with-request-body

Conversation

@derekargueta
Copy link
Member

@derekargueta derekargueta commented Mar 23, 2021

Commit Message: http: Internal redirects with request body
Additional Description: Adds support for handling internal redirects for requests that have a body.
Risk Level: medium - HCM/FM stream recreation
Testing: Added unit and integration tests
Docs Changes: Done
Release Notes: Added
Runtime guard: envoy.reloadable_features.internal_redirects_with_body
Fixes: #14736

Signed-off-by: Derek Argueta darguetap@gmail.com

Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
@derekargueta
Copy link
Member Author

derekargueta commented Mar 23, 2021

all existing tests pass. I assume this needs a runtime guard since it modifies behavior without a configuration change (hmm, should it be a config option? exclude_requests_with_body or something?) and users may need to adjust buffer limits since any route that has this enabled will need to buffer the request body - don't think there's a way around that since you can't know if it needs a redirect ahead of time.

Still some cleanup to do as well, but wanted to see if I can start getting feedback on the direction cc @alyssawilk @mattklein123

Also thinking that trailers should probably be handled as well?

@alyssawilk alyssawilk self-assigned this Mar 24, 2021
Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall - thanks for tackling this one! I know we'll be wanting to use it for small bodied requests as well.


default_request_headers_.setHost("handle.internal.redirect");
IntegrationStreamDecoderPtr response =
codec_client_->makeRequestWithBody(default_request_headers_, "foobarbizbaz");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also make sure we have a test where we encode headers and partial body, do an early redirect, and downstream sends the rest of the body (or make sure we don't redirect given partial body if you don't want to deal with that yet)

Copy link
Member Author

@derekargueta derekargueta Mar 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I want to tackle partial bodies quite yet (happy to do further iterations, but hoping to get the complete-request-body functionality in very soon 🙂).

We still have the condition The request must have been fully processed by Envoy., which is gated by checking that downstream_end_stream_ is true in order to do an internal redirect.

Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Here's a few more thoughts.

Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
@derekargueta derekargueta marked this pull request as ready for review March 31, 2021 01:10
Signed-off-by: Derek Argueta <darguetap@gmail.com>
@alyssawilk
Copy link
Contributor

Hm, looks like that asan failure may be real. Want to check it out?

https://dev.azure.com/cncf/4684fb3d-0389-4e0b-8251-221942316e06/_apis/build/builds/70794/logs/169

Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall! Only minor nits left so @snowp up for second pass?

Also cc @penguingao in case he wants to check it out.

// the stream is complete may differ, re-check bytesReceived() to make sure
// there was no body from the HCM's point of view.
if (!complete() || parent_.stream_info_.bytesReceived() != 0) {
if (!parent_.enableInternalRedirectsWithBody() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want
if (!complete() || (!parent_.enableInternalRedirectsWithBody() parent_.stream_info_.bytesReceived() != 0)
no?

Copy link
Member Author

@derekargueta derekargueta Mar 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right - the integration test still passed since the router has its own end-of-stream/request-body-present checks that generally prevent us from reaching this point but (as the above comment mentions) this seems to be an extra protection layer against incomplete requests.

I don't see any existing tests for this branch but I can try to put one together - this could occur when the router's downstream_end_stream_ is true but the FM's state_.local_complete_ is false, and if the router's bufferedBody() is false (router doesn't think there's a body) but FM's receivedBytes() is non-zero. Hmmm, tricky cases to test.

@derekargueta
Copy link
Member Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15634 (comment) was created by @derekargueta.

see: more, trace.

@derekargueta
Copy link
Member Author

hmm, //test/integration:protocol_integration_test failed coverage twice in a row, seemingly for this error

FAIL: //test/integration:protocol_integration_test (shard 2 of 5) (see /build/tmp/_bazel_envoybuild/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/bazel-out/k8-fastbuild/testlogs/test/integration/protocol_integration_test/shard_2_of_5/test.log)
INFO: From Testing //test/integration:protocol_integration_test (shard 2 of 5):
stdout (/build/tmp/_bazel_envoybuild/b570b5ccd0454dc9af9f65ab1833764d/execroot/envoy/bazel-out/_tmp/actions/stdout-13151) exceeds maximum size of --experimental_ui_max_stdouterr_bytes=1048576 bytes; skipping

https://dev.azure.com/cncf/envoy/_build/results?buildId=71238&view=logs&j=5035ce29-be3c-5fcf-dc50-abb6a265f8b1&t=548c3e59-0417-5971-4f1b-f8545005c291&l=10704

gonna give it one more kick while I try to repro locally

@derekargueta
Copy link
Member Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15634 (comment) was created by @derekargueta.

see: more, trace.

@derekargueta derekargueta requested a review from snowp April 5, 2021 23:25
@alyssawilk
Copy link
Contributor

@snowp any other requests as second pass reviewer (once you're back tomorrow)?

Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks this looks good in general, just a few questions

Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
Signed-off-by: Derek Argueta <darguetap@gmail.com>
…er_.bufferedRequestData() a second time

Signed-off-by: Derek Argueta <darguetap@gmail.com>
@derekargueta
Copy link
Member Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15634 (comment) was created by @derekargueta.

see: more, trace.

@derekargueta
Copy link
Member Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15634 (comment) was created by @derekargueta.

see: more, trace.

@alyssawilk
Copy link
Contributor

verify examples got broken last night by a g-c-p change - main merge should now fix!

Signed-off-by: Derek Argueta <darguetap@gmail.com>
@derekargueta
Copy link
Member Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #15634 (comment) was created by @derekargueta.

see: more, trace.

Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support internal redirects with body to support the semantics of 307 redirects

4 participants