Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add generic response interceptors #6232

Merged
merged 8 commits into from May 13, 2024

Conversation

dunglas
Copy link
Collaborator

@dunglas dunglas commented Apr 10, 2024

In proxy mode, Caddy allows intercepting and modifying responses coming from upstream servers.
This is especially useful for implementing X-Sendfile/X-Accel-Redirect-like features.

However, the current implementation of this feature is only available in proxy mode and doesn't allow to intercept and modify responses created by modules.

This makes it impossible to use features like X-Sendfile with FrankenPHP, https://github.com/mliezun/caddy-snake, and other similar potential modules (LUA module, etc).

This patch implements a generic implementation of response interceptors that behaves similarly to the reverse_proxy handle_response.

It currently does not support the copy_response and copy_response_headers subdirectives, but it should be easy to add support for these features in future Pull Requests.
It should also be possible, in the future, to replace the current reverse_proxy specific implementation with this new more generic one, but it is out of scope for this PR.

Closes dunglas/frankenphp#365. Closes dunglas/frankenphp#396.

@elghailani
Copy link

elghailani commented Apr 10, 2024

Nice feature! Thanks @dunglas !
I posted asking for help configuring similar capability in this post on caddy forum few days ago.

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

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

This is a cool change. I haven't thoroughly reviewed it yet but my first pass is liking where this is going. Just a couple nit picky thoughts for starters.

modules/caddyhttp/interceptresponse/interceptresponse.go Outdated Show resolved Hide resolved
modules/caddyhttp/interceptresponse/interceptresponse.go Outdated Show resolved Hide resolved
modules/caddyhttp/interceptresponse/interceptresponse.go Outdated Show resolved Hide resolved
@mholt mholt added the feature ⚙️ New feature or request label Apr 11, 2024
@mholt mholt added this to the v2.8.0 milestone Apr 11, 2024
@dunglas dunglas force-pushed the feat/response-interceptors branch 2 times, most recently from 7cce44a to 8aa881f Compare April 12, 2024 06:39
@mholt
Copy link
Member

mholt commented Apr 12, 2024

Looking good here. @francislavoie any thoughts on the Caddyfile implementation?

Comment on lines +200 to +215
// delegate the parsing of handle_response to the caller,
// since we need the httpcaddyfile.Helper to parse subroutes.
// See h.FinalizeUnmarshalCaddyfile
i.handleResponseSegments = append(i.handleResponseSegments, d.NewFromNextSegment())
Copy link
Member

Choose a reason for hiding this comment

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

Since this isn't embedded within another directive, I think we don't need the finalize thing here. I think we can immediately parse the current segment as a handler and add that to the config. Then we can delete handleResponseSegments

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do you have an idea of how we can do that @francislavoie? We need a httpcaddyfile.Helper to call ParseSegmentAsSubroute().

Copy link
Member

Choose a reason for hiding this comment

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

Oooh right. I'll think about it.

@mholt
Copy link
Member

mholt commented Apr 23, 2024

@dunglas I'll probably tag 2.8 beta 1 this week; it'd be nice to get this in 2.8 beta 1, but if not, maybe we can get it in beta 2 or the RC.

@mholt
Copy link
Member

mholt commented May 13, 2024

@dunglas Before we merge this, can we mark the exported types/methods as "EXPERIMENTAL: Subject to change or removal" (or something like that)? It sounds like there are still decisions to be made to finalize APIs to accommodate expanded functionality later, and by marking it as experimental we can at least merge it in sooner and then change it, as opposed to making painful changes later on.

@dunglas
Copy link
Collaborator Author

dunglas commented May 13, 2024

Sounds good to me to mark the public API as experimental. Should I update the code?

@mholt
Copy link
Member

mholt commented May 13, 2024

Yeah, if you have a chance to do that could you push a commit? I'm wrapping up a few things here.

@dunglas dunglas force-pushed the feat/response-interceptors branch from c7aedf3 to 184654a Compare May 13, 2024 17:29
@dunglas
Copy link
Collaborator Author

dunglas commented May 13, 2024

@mholt done (the public type was already marked as experimental).

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

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

Ah, okay thanks. I was mobile this weekend so thanks for double-checking.

@mholt mholt enabled auto-merge (squash) May 13, 2024 17:32
@mholt mholt disabled auto-merge May 13, 2024 17:32
@mholt mholt enabled auto-merge (squash) May 13, 2024 17:32
@mholt mholt merged commit fb63e2e into caddyserver:master May 13, 2024
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature ⚙️ New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Intercept responses for nginx-like X-Accel-Redirect handling
4 participants