Skip to content

Conversation

@stevenzzzz
Copy link
Contributor

@stevenzzzz stevenzzzz commented Apr 5, 2025

Commit Message: Envoy Grpc-lib en/decode base64 on -bin init-metadata
Additional Description: Following https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md spec about "-bin" metadata.

Also fixed a use-after-move bug in the grpc async-client-impl.

Risk Level: LOW
Testing: unit tests, integration tests.
Docs Changes:
Release Notes:
Platform Specific Features:

lizan and others added 18 commits March 2, 2020 14:27
Signed-off-by: Lizan Zhou <lizan@tetrate.io>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
…oogle grpc "-bin" initial metadata

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
…ocessing

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
@stevenzzzz stevenzzzz marked this pull request as draft April 5, 2025 23:56
@stevenzzzz stevenzzzz changed the title Envoy Grpc-lib en/decode base64 on -bin init-metadata [grpc] Envoy Grpc-lib en/decode base64 on -bin init-metadata Apr 7, 2025
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
…ponse for Envoy-grpc (less test breakages)

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
@stevenzzzz stevenzzzz changed the title [grpc] Envoy Grpc-lib en/decode base64 on -bin init-metadata [grpc] Envoy/Googe-Grpc-lib en/decode base64 on -bin init-metadata Apr 9, 2025
@stevenzzzz stevenzzzz marked this pull request as ready for review April 9, 2025 02:47
@stevenzzzz
Copy link
Contributor Author

/assign @yanjunxiang-google

Hey Yanjun, could you give it a pass?

@stevenzzzz
Copy link
Contributor Author

@kyessenov FYI

@stevenzzzz
Copy link
Contributor Author

/assign @yanavlasov

@stevenzzzz
Copy link
Contributor Author

/retest

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Http::HeaderMap& header_map) {
// More painful copying, this time due to the mismatch in header
// representation data structures in Envoy and Google gRPC.
// Note that grpc-lib has handled the "-bin" metadata decoding.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it do it at send, or when set? I am worried about a case some module using gRPC SDK gets this header corrupted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's in the gprc hpack lib I think.
check out the integration test. I am pretty sure on the wire it should be based-encoded. at least, we should not encode it on the receiving path.
(I will show you an internal integration test as example).

@stevenzzzz
Copy link
Contributor Author

/assign @htuch

if (absl::EndsWith(header.key().getStringView(), "-bin")) {
bin_metadata.emplace(header.key().getStringView(),
absl::Base64Escape(header.value().getStringView()));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we directly remove the original header/value pair, and adds the new header/base-64-value pair here? That way, we can avoid the below for loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can not find a method from headermap to in-place replace the value of a key, let me know if you know one.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering can you use setCopy() to replace the value inline, like something as below:

headers.iterate([&bin_metadata](const Http::HeaderEntry& header) {
if (absl::EndsWith(header.key().getStringView(), "-bin")) {
headers.setCopy(header.key().getStringView(), absl::Base64Escape(header.value().getStringView()));
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

setCopy is basically remove + addCopy under the hood. this iterate() method is a "const" method, I don't fell like mutate the headermap inside it.
Let's use the somewhat ugly two loops to fix the issue.

std::string value;
absl::Base64Unescape(header.value().getStringView(), &value);
bin_metadata[header.key().getStringView()] = std::move(value);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pls see the other comment.

this method is removed in later commit.


// TODO(htuch): match Google gRPC base64 encoding behavior for *-bin headers, see
// https://github.com/envoyproxy/envoy/pull/2444#discussion_r163914459.
void AsyncStreamImpl::onHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we remove this TODO comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

per recent discussion, we want to drop the base64 decoding of server side -bin metadata until #39054 resolves.

}
// Normal response headers/Server initial metadata.
if (!waiting_to_delete_on_remote_close_) {
base64UnescapeBinHeaders(*headers);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just add this line base64UnescapeBinHeaders(*headers) at the original place, i.e, line 194, and keep other places in this function untouched? What's the benefit to move it to the end, and spread the logic before each return? Also, why not having if (!waiting_to_delete_on_remote_close_) check in other places? Is it a logic change?

@stevenzzzz
Copy link
Contributor Author

Per discussion, let's not decode on the receiving path for -bin headers. This means encoding the Google-gprc-client "-bin" headers. #39054

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Copy link
Contributor Author

@stevenzzzz stevenzzzz left a comment

Choose a reason for hiding this comment

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

Thanks.

Reverted the "decoding" on receiving path. adjusted tests, PTAL.


// TODO(htuch): match Google gRPC base64 encoding behavior for *-bin headers, see
// https://github.com/envoyproxy/envoy/pull/2444#discussion_r163914459.
void AsyncStreamImpl::onHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

per recent discussion, we want to drop the base64 decoding of server side -bin metadata until #39054 resolves.

@yanjunxiang-google
Copy link
Contributor

LGTM

@stevenzzzz
Copy link
Contributor Author

/retest

@stevenzzzz stevenzzzz changed the title [grpc] Envoy/Googe-Grpc-lib en/decode base64 on -bin init-metadata [grpc] Envoy/Googe-Grpc-lib base64 encode "-bin" client init-metadata Apr 11, 2025
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
@stevenzzzz
Copy link
Contributor Author

Hey @yanavlasov, could you pls give it a maintainer bless?

I'd hope someone could take care of #39054,

Right now wasm filter is the only consuming server metadatas, but I am not sure if there is any meaningful application, but still good to have.

@yanavlasov yanavlasov merged commit fcb83af into envoyproxy:main Apr 14, 2025
25 checks passed
oconnorkyle pushed a commit to oconnorkyle/envoy that referenced this pull request Apr 23, 2025
…envoyproxy#39026)

Envoy Grpc-lib  en/decode base64 on -bin init-metadata 

Following
https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md spec
about "-bin" metadata.

Also fixed a use-after-move bug in the grpc async-client-impl. 

Risk Level: LOW
Testing: unit tests, integration tests. 
Docs Changes:
Release Notes:
Platform Specific Features:

---------

Signed-off-by: Lizan Zhou <lizan@tetrate.io>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Co-authored-by: Lizan Zhou <lizan@tetrate.io>
Signed-off-by: Kyle O'Connor <oconnorkyle@google.com>
oconnorkyle pushed a commit to oconnorkyle/envoy that referenced this pull request Apr 23, 2025
…envoyproxy#39026)

Envoy Grpc-lib  en/decode base64 on -bin init-metadata 

Following
https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md spec
about "-bin" metadata.

Also fixed a use-after-move bug in the grpc async-client-impl. 

Risk Level: LOW
Testing: unit tests, integration tests. 
Docs Changes:
Release Notes:
Platform Specific Features:

---------

Signed-off-by: Lizan Zhou <lizan@tetrate.io>
Signed-off-by: Xin Zhuang <stevenzzz@google.com>
Co-authored-by: Lizan Zhou <lizan@tetrate.io>
Signed-off-by: Kyle O'Connor <oconnorkyle@google.com>
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.

6 participants