Skip to content

Conversation

@mbaynton
Copy link
Contributor

This builds on #13133 to make it possible to adjust settings on the *httputil.ReverseProxy that queue-proxy uses, or to replace it entirely with any http.Handler, using the out-of-tree extension pattern introduced by that PR.

In general this allows additions to the queue-proxy main server's request handler chain, which greatly expands what can be done via the out-of-tree extension model started in 13133. Many potential use cases for this form of out-of-tree extending exist, most probably not as involved as the below. For example someone might want to do their own customization to the httputil.ReverseProxy, or add handlers that perform custom header rewrites. In case you are curious, I fully explain my specific use case that motivated the change at the bottom.

Proposed Changes

  • Adds an http.Handler to the Defaults struct that queue proxy Option functions can manipulate

Release Note

Made it possible to configure the `httputil.ReverseProxy` or add `http.Handler`s to queue-proxy in out-of-tree builds.

My specific use case

We operate a service that allows users to publish and run their web application code. Because it leads to much better publishing performance than image building/pushing/pulling, our architecture allows the end user applications to be built (and updated, during dev/test cycles) in the same container that serves the application. As a result, we can experience states such as:

  • container has started, but needs to install a brand new application before it can serve it, so has an abnormally long startup time
  • container was serving a healthy app, but breaking changes to the code were applied and now the app cannot produce an http listener

We have been handling this by running our own small http server behind queue-proxy to serve things like loading splash pages and error pages when the user's application is unavailable. To reduce total number of proxy hops, this server and the user application take turns listening on the main container port, rather than having our server be another reverse proxy. But we obviously do mishandle some requests with this method as there are transition states where no server is listening.

With these changes, I am able to keep the number of proxy hops the same by inheriting all the functionality that the rest of knative requires from queue-proxy, but also customize it a little bit to do the loading splash page and error page serving when I know based on external state that attempting proxying will not work.

This builds on knative#13133 to make it possible to adjust settings on the
*httputil.ReverseProxy that queue-proxy uses, or to replace it entirely
with any http.Handler, using the out-of-tree extension pattern.
@knative-prow knative-prow bot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Sep 26, 2025
@knative-prow
Copy link

knative-prow bot commented Sep 26, 2025

Hi @mbaynton. Thanks for your PR.

I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@dprotaso
Copy link
Member

/ok-to-test

@knative-prow knative-prow bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Sep 28, 2025
Copy link
Member

@dprotaso dprotaso left a comment

Choose a reason for hiding this comment

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

Interesting use of the extension point - left a comment on order of operations

Comment on lines 219 to 222
d.ProxyHandler = buildProxyHandler(logger, env, d.Transport)

// allow extensions to read d and return modified context, transport, and proxy handler.
for _, opts := range opts {
Copy link
Member

Choose a reason for hiding this comment

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

There's one subtle regression. Prior if the integrator set d.Transport it would be used when building the proxy. This isn't the case anymore.

I think what you want is to set d.ProxyHandler to buildProxyHandler after iterating through the options - but only if ProxyHandler remains nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, good catch.

I think it's nicer if Options functions receive an incoming non-nil ProxyHandler -- this allows both fine-tuning options of the httputil.ReverseProxy and taking whatever handler knative wants to provide and wrapping it. But this does create an ordering problem since we configure a Transport onto the httputil.ReverseProxy that we provide to Options, and also Options can override the Transport.

What do you think about the new commit, which always resets the httputil.ReverseProxy's transport to the one set by the Options functions after iterating them?

Copy link
Member

Choose a reason for hiding this comment

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

What do you think about the new commit, which always resets the httputil.ReverseProxy's transport to the one set by the Options functions after iterating them?

I think that works. Thanks for the change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Awesome. Very helpful for us to have this in, thank you for checking it out!

Copy link
Member

Choose a reason for hiding this comment

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

No worries - consider adding yourself as an adopter here - https://github.com/knative/community/issues/new?template=ADOPTERS.yaml

@codecov
Copy link

codecov bot commented Sep 28, 2025

Codecov Report

❌ Patch coverage is 38.09524% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.05%. Comparing base (4f02005) to head (b363ef1).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
pkg/queue/sharedmain/main.go 40.00% 12 Missing ⚠️
pkg/queue/sharedmain/handlers.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #16097      +/-   ##
==========================================
- Coverage   80.15%   80.05%   -0.11%     
==========================================
  Files         214      214              
  Lines       16877    16916      +39     
==========================================
+ Hits        13528    13542      +14     
- Misses       2987     3017      +30     
+ Partials      362      357       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

If an integrator customizes the Transport in an Options function, we want to
apply the provided Transport to our default httputil.ReverseProxy
regardless of which Option sets the Transport and regardless of whether
or not other Option functions replace our default http.Handler.

Add some tests for this since the interactions beteween
Options.Transport and Options.ProxyHandler can be subtle.
@knative-prow knative-prow bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Oct 3, 2025
@dprotaso
Copy link
Member

dprotaso commented Oct 6, 2025

/lgtm
/approve

@knative-prow knative-prow bot added the lgtm Indicates that a PR is ready to be merged. label Oct 6, 2025
@knative-prow
Copy link

knative-prow bot commented Oct 6, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dprotaso, mbaynton

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 6, 2025
@knative-prow knative-prow bot merged commit 1c8d21b into knative:main Oct 6, 2025
71 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants