grpc json transcoder: Support response_body#10892
Conversation
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
| } else if (tag == 0) { | ||
| return true; | ||
| } else { | ||
| if (!Protobuf::internal::WireFormatLite::SkipField(input, tag)) { |
There was a problem hiding this comment.
Dependency on internal API worries me, but I didn't find a better way without actually copying the same logic.
There was a problem hiding this comment.
Sorry for the late response. Can we add more test coverage for this function? This part isn't covered.
| // TODO(elessar): Return error to client. | ||
| encoder_callbacks_->resetStream(); |
There was a problem hiding this comment.
Is there a way to actually return 500 http status code to client right here if first message is invalid and stop fetching bad body from the upstream?
There was a problem hiding this comment.
you can call encoder_callbackds_->sendLocalReply() to return 500.
There was a problem hiding this comment.
sendLocalReply is only available as part of decoder_callbacks_, at encoding phase it's too late to call it.
There was a problem hiding this comment.
Yes it is usually too late at encodeData, unless you returned StopIteration in encodeHeaders, then you can modify headers and Continue. (which is the case here)
There was a problem hiding this comment.
Is there a way to indicate envoy that there will be no more data (end_stream=true)?
There was a problem hiding this comment.
Yes, end_stream = true means not more data.
There was a problem hiding this comment.
seems no, we have StopIterationAndEndStream in FilterHeaderStatus but not in data. cc @mattklein123?
There was a problem hiding this comment.
Yeah I think this is a new use case we haven't hit before. You might be able to hack something up with injectEncodedDataToFilterChain (0 bytes + end_stream), but otherwise I think this would require HCM changes. cc @alyssawilk @snowp to see if I am forgetting about something.
There was a problem hiding this comment.
ooh error handling on the response path!
AFIK the only example we have of this is in the HCM responseDataTooLarge.
In theory once we've stared running responses through the filter chain, we can't run them again (i.e. if headers are blocked by some downstream filter and haven't been written to the client, we can send a 500 but e can't send headers through the filter chain a second time)
I think the same way that we have a sendLocalReply for decoder filter callbacks we could have a sendReplyOrResetStream() for encoder filter callbacks which factors out the HCM responseDataTooLarge logic and either ships headers + body directly to the codec, or resets the stream.
There was a problem hiding this comment.
I think the same way that we have a sendLocalReply for decoder filter callbacks we could have a sendReplyOrResetStream() for encoder filter callbacks which factors out the HCM responseDataTooLarge logic and either ships headers + body directly to the codec, or resets the stream.
Yeah +1. I would probably just submit this PR the way you have it now with a TODO and then circle back with an HCM change if you so desire.
| http_body.Clear(); | ||
| Buffer::ZeroCopyInputStreamImpl stream(std::move(frame.data_)); | ||
| http_body.ParseFromZeroCopyStream(&stream); | ||
| if (!HttpBodyUtils::parseMessageByFieldPath(&stream, method_->response_body_field_path, |
There was a problem hiding this comment.
Doing there is only supporting HttpBody response. What about normal JSON response?
You may have to implement it here
There was a problem hiding this comment.
I can submit a version of this change to grpc-httpjson-transcoding library instead & use it both here for HttpBody and there for JSON.
Protobuf spec allows inclusion of the same message field multiple times with an expectation that parser merges them. In order to support this generically I may need to provide ZeroCopyInputStream implementation built on top of the chain of sub-streams. It can be somehow less efficient though hopefully still the same amount of copies.
Thoughts?
There was a problem hiding this comment.
Alternatively we could decide to not support this edge case and treat it as an error until somebody complains.
There was a problem hiding this comment.
We can make supporting response_body in HttpBody and JSON as two different features. This PR can be just for HttpBody, and file another issue to track JSON feature.
Please log a proper warning or error code for not supported case.
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
Still working on it, will update the CL by end of the week |
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
@euroelessar the coverage fail is real due to lack of coverage. /wait |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
/retest |
|
🤷♀️ nothing to rebuild. |
|
/retest |
|
🤷♀️ nothing to rebuild. |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
@lizan Thanks for the patience, I've fixed the coverage for the pieces introduced by this pull request. |
|
ASAN failure looks weird though, all tests are passed but: |
|
@euroelessar a fix from @lizan is on its way: #12018. |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com>
|
Failed coverage test is |
Signed-off-by: Ruslan Nigmatullin <elessar@dropbox.com> Signed-off-by: scheler <santosh.cheler@appdynamics.com>
Description: Add support for
google.api.Http.response_bodyfield.Risk Level: medium (new parsing of potentially untrusted user data, but requires config change to be active)
Testing: added unit test
Docs Changes: n/a (
body/response_bodyare part of google api documentation and are not mentioned in envoy docs)Release Notes: added
Fixes #10870