[Caddy 2] X-Sendfile/X-Accel support?

Is there support for X-Accel/X-Sendfile in Caddy 2 and if so how would I enable this in the Caddyfile, in Caddy 1 there’s internal without any arguments but I can’t find the equivalent for Caddy 2.

1 Like

Caddy doesn’t specifically handle that header.

What exactly are you trying to achieve? It’s likely possible regardless. Please be as specific as possible so that we have a clear idea of what you need.

1 Like

My understanding is that X-Accel is an nginx-specific behavior. So I second Francis’ question: what are you actually trying to achieve? I almost guarantee that Caddy 2 can do it (and if not already, then soon). Just need to know what it is.

X-Accel/X-Sendfile headers are intercepted by the webserver and serve whatever file is specified in the header, without redirecting the user.

1 Like

Yeah, you can probably just do that with rewrite and a header matcher. I feel that the header is probably unnecessary and you could do this more simply anyways.

Could you give us a specific example of a request and the expected response?

1 Like

See one of the many blogposts on the subject, there needs to be a match on a response header from the backend for which there doesn’t seem to be an available matcher?

Oh, I see. This is to rewrite a response to serve a static file.

Hmm. I’m not sure that’s currently possible, but I think it would be pretty easy to write a plugin that acts as response middleware to do this! See the docs on extending Caddy

The module would have to be designed to be added to an existing configuration using the core reverse_proxy implementation, wrap the response, and inspect it for an X-Accel-Redirect header.

Then it’s just an if statement - either discard the reverse proxy response and serve the file, or preserve the reverse proxy response if there’s no header and pass it up untouched.

I expect it would be extremely lightweight.

1 Like

It’s on my TODO list to write a handler that can wrap the response and execute an arbitrary route, either after the headers are written or the whole body… that should be able to implement the functionality then, right?

3 Likes

Yes, assuming we can inspect details of the response as part of that route, theoretically we could just use that handler and have it execute a route that rewrites to exactly the file we want (based on the response header) and serves it via the core file_server.

Might look something like this in the Caddyfile?

example.com {
  response_route {
    @accelRedirect {
      response_header X-Accel-Redirect *
    }
    rewrite @accelRedirect {http.response.header.X-Accel-Redirect}
    file_server @accelRedirect
  }
}

Hmm, that syntax is mostly for request matchers, not response matchers. Response matchers aren’t really a thing outside of handlers that are designed to capture the responses.

I don’t know what the Caddyfile would like yet, I seldom think of that before the underlying JSON (since Caddy doesn’t actually understand Caddyfile, I can’t design a new feature via Caddyfile). Maybe something like this:

{
    "handler": "capture_response",
    "routes": [...]
}

In other words, once the response has been captured, it evaluates those routes. Still lots of design work to do here though.

/shrug

You can only design what you can envision, and starting with an idea of what you want the end result to look like for a certain use case helps guide that process. Hopefully spitballing psuedo config here isn’t useless.

Yeah, that syntax would have to change too. Maybe it would have helped for me to explicitly outline all the parts of that Caddyfile that were psuedo config?

Anyway, yeah, it definitely seems complicated to handle arbitrary routes after the response. Orders of magnitude more complex than simply writing a sendfile specific handler.

Not to diminish your idea, I think it was very interesting – but it’s hard to implement from the Caddyfile. Still, if it helps you visualize it, then that’s great! Might as well start somewhere. But before any work gets done, it usually has to be figured out in the JSON first.

I wouldn’t say orders of magnitude :slight_smile: It’s just that the handler would not (need to) be specific to x-accel.

Hah, no worries. Mostly I say orders of magnitude because of just how incredibly simple I expected the sendfile handler would be.

One could always write a sendfile/accel-specific directive that wraps up the capture_response handler, like the php_fastcgi directive does for the reverse proxy.

The goal of the JSON is flexibility and clarity, while the Caddyfile can have some magic and convenience layered on top.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.