Skip to content

router: add direct response with body format#41821

Merged
ravenblackx merged 27 commits intoenvoyproxy:mainfrom
6ixfalls:feat/direct_body
Nov 12, 2025
Merged

router: add direct response with body format#41821
ravenblackx merged 27 commits intoenvoyproxy:mainfrom
6ixfalls:feat/direct_body

Conversation

@6ixfalls
Copy link
Copy Markdown
Contributor

@6ixfalls 6ixfalls commented Nov 3, 2025

Adds support for passing a body_format to a route's direct response. Fixes #39463

Commit Message: Allows a body_format to be passed for a route's direct_response. The body_format follows the same convention as the local_response_policy body. If a body is present & body_format is not, continue prior behavior with no formatting. If both are present, return the formatted content, and if neither is specified, no body is returned.
Additional Description: Not sure if I covered all places where this could be used (libraries)?
Risk Level: Medium
Testing: Unit & integration
Docs Changes: In line with API protos
Release Notes: New feature - Added support for substitution formatting in direct response bodies via the new :ref:body_format <envoy_v3_api_field_config.route.v3.DirectResponseAction.body_format> field
in :ref:DirectResponseAction <envoy_v3_api_msg_config.route.v3.DirectResponseAction>.
Platform Specific Features: N/A
Optional Runtime guard: Unsure if required
Optional Fixes #39463
Optional API Considerations: Should be satisfied

Adds support for passing a body_format to a route's direct response. Fixes envoyproxy#39463

Signed-off-by: Six <23470032+6ixfalls@users.noreply.github.com>
Signed-off-by: Six <23470032+6ixfalls@users.noreply.github.com>
@repokitteh-read-only
Copy link
Copy Markdown

Hi @6ixfalls, welcome and thank you for your contribution.

We will try to review your Pull Request as quickly as possible.

In the meantime, please take a look at the contribution guidelines if you have not done so already.

🐱

Caused by: #41821 was opened by 6ixfalls.

see: more, trace.

@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to (api/envoy/|docs/root/api-docs/).
envoyproxy/api-shepherds assignee is @adisuissa
CC @envoyproxy/api-watchers: FYI only for changes made to (api/envoy/|docs/root/api-docs/).

🐱

Caused by: #41821 was opened by 6ixfalls.

see: more, trace.

@6ixfalls 6ixfalls marked this pull request as draft November 4, 2025 04:51
@6ixfalls
Copy link
Copy Markdown
Contributor Author

6ixfalls commented Nov 4, 2025

Existing tests need to be rewritten to pass - not sure if this was the right way to implement it.

@ravenblackx ravenblackx self-assigned this Nov 6, 2025
New mock, updated bodyFormat to return a string instead of modifying an argument

Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
@6ixfalls
Copy link
Copy Markdown
Contributor Author

6ixfalls commented Nov 7, 2025

It seems like there are no more references to responseBody() outside tests - would it be best to remove it outright and update all the mocks to point to formatBody(...)?

@ravenblackx
Copy link
Copy Markdown
Contributor

It seems like there are no more references to responseBody() outside tests - would it be best to remove it outright and update all the mocks to point to formatBody(...)?

Yes, I think that's the cleanest solution here. A little unfortunate that formatBody requires more arguments, but there's not that many of them so I think it's not a big cost.

@ravenblackx
Copy link
Copy Markdown
Contributor

/coverage

@repokitteh-read-only
Copy link
Copy Markdown

Coverage for this Pull Request will be rendered here:

https://storage.googleapis.com/envoy-cncf-pr/41821/coverage/index.html

For comparison, current coverage on main branch is here:

https://storage.googleapis.com/envoy-cncf-postsubmit/main/coverage/index.html

The coverage results are (re-)rendered each time the CI Envoy/Checks (coverage) job completes.

🐱

Caused by: a #41821 (comment) was created by @ravenblackx.

see: more, trace.

Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
…rmatting

Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
@ravenblackx
Copy link
Copy Markdown
Contributor

/retest

Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
@6ixfalls 6ixfalls marked this pull request as ready for review November 11, 2025 02:37
@6ixfalls 6ixfalls requested a review from ravenblackx November 11, 2025 02:38
ravenblackx
ravenblackx previously approved these changes Nov 11, 2025
Copy link
Copy Markdown
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

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

Thanks for you contribution and making the happy-path less costly.

Comment on lines +1947 to +1948
// Specifies a format string for the response body. If ``body_format`` is not provided,
// and ``body`` is, the contents of ``body`` will be used to populate the body of the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the !body_format && body is pretty clear. What should probably be clarified is:

  • body_format && body, and in this case I assume body_format will take precedence (please also update the comment of body - see example). (after briefly looking at the code changes, it is not clear to me if this requires the body to be present, and works on top of that or not - this should be clarified).
  • !body_format && !body, no body will be in the generated response.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I copied the definition from the custom_response_filter - but I can definitely make this clearer. This should be updated within that as well, but that's out of scope for this PR.

}

TEST_P(DirectResponseIntegrationTest, DirectResponseWithBodyFormatAndNoBody) {
testDirectResponseWithBodyFormatAndNoBody();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OOC what's the benefit of having a function call here?
If the code is not reused, IMHO it should just be here.
(same applies to the test below)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I thought that too, but this is how it's already structured elsewhere in this file, and I try not to ask for cleaning up other people's mess, or being inconsistent with it.
(I was thinking I might clean it up afterwards.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I thought that the testDirectResponseBodySize() method is being reused in some tests, and that's why it was made a function. Granted, there may be a better approach here.
Specifically the new functions don't seem to be reused, so IMHO the additional dereference just makes it a bit more complex to understand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The whole subfunction thing is part of my pet testing peeve, that if you do a subfunction like that and the test fails, the output you get is frequently much less helpful than it would be if you did the helper functions differently.
e.g. instead of

testDirectResponseBodySize(1);

you could structure it

auto body = getDirectResponseBody();
EXPECT_THAT(body, HasLength(1));

which is very slightly longer but significantly clearer and makes any test failure occur in the test function, and also can log more useful information on failure (e.g. that the body is "banana" rather than just that the body's length was not 1.)

Anyway, for the purposes of this PR my point is just that I'm recommending not fixing this in this PR, because there were bad precedents, and I'll clean it up better afterwards. :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

testDirectResponseFile() is also not being reused anywhere else, but was also made into a function.

Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Copy link
Copy Markdown
Contributor

@adisuissa adisuissa left a comment

Choose a reason for hiding this comment

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

/lgtm api

@adisuissa
Copy link
Copy Markdown
Contributor

/assign-from @envoyproxy/senior-maintainers

@repokitteh-read-only
Copy link
Copy Markdown

@envoyproxy/senior-maintainers assignee is @RyanTheOptimist

🐱

Caused by: a #41821 (comment) was created by @adisuissa.

see: more, trace.

@adisuissa
Copy link
Copy Markdown
Contributor

/retest

1 similar comment
@ravenblackx
Copy link
Copy Markdown
Contributor

/retest

@ravenblackx ravenblackx merged commit d524156 into envoyproxy:main Nov 12, 2025
25 of 26 checks passed
grnmeira pushed a commit to grnmeira/envoy that referenced this pull request Mar 20, 2026
Adds support for passing a body_format to a route's direct response.
Fixes envoyproxy#39463

Commit Message: Allows a body_format to be passed for a route's
direct_response. The body_format follows the same convention as the
local_response_policy body. If a body is present & body_format is not,
continue prior behavior with no formatting. If both are present, return
the formatted content, and if neither is specified, no body is returned.
Additional Description: Not sure if I covered all places where this
could be used (libraries)?
Risk Level: Medium
Testing: Unit & integration
Docs Changes: In line with API protos
Release Notes: New feature - Added support for substitution formatting
in direct response bodies via the new :ref:`body_format
<envoy_v3_api_field_config.route.v3.DirectResponseAction.body_format>`
field
in :ref:`DirectResponseAction
<envoy_v3_api_msg_config.route.v3.DirectResponseAction>`.
Platform Specific Features: N/A
Optional Runtime guard: Unsure if required
Optional Fixes envoyproxy#39463
Optional [API
Considerations](https://github.com/envoyproxy/envoy/blob/main/api/review_checklist.md):
Should be satisfied

---------

Signed-off-by: Six <23470032+6ixfalls@users.noreply.github.com>
Signed-off-by: Bryan Lee <me@bryanl.ee>
Signed-off-by: Gustavo <grnmeira@gmail.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.

Allow to use body_format in direct_response

4 participants