caddy: Incorrect Location header when proxy upstream responds with a redirect

1. What version of Caddy are you running (caddy -version)?

Caddy 0.9.0

2. What are you trying to do?

Proxy a redirect.

3. What is your entire Caddyfile?

example.com
proxy / unix:/var/run/example.sock
example.com
proxy / localhost:5000

4. How did you run Caddy (give the full command and describe the execution environment)?

sudo caddy

5. What did you expect to see?

Location header should be set correctly.

6. What did you see instead (give full error messages and/or log)?

$ curl -v https://example.com/number/random/
*   Trying 0.0.0.0...
* Connected to example.com (0.0.0.0) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: example.com
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> GET /number/random/ HTTP/1.1
> Host: example.com
> User-Agent: curl/7.49.1
> Accept: */*
> 
< HTTP/1.1 302 Found
< Content-Length: 235
< Content-Type: text/html; charset=utf-8
< Date: Sun, 07 Aug 2016 18:19:27 GMT
< Location: http://socket/number/42/
< Server: Caddy
< Server: gunicorn/17.5
< 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
* Connection #0 to host example.com left intact
<p>You should be redirected automatically to target URL: <a href="/number/42/">/number/42/</a>.  If not click the link.
$ curl -v https://example.com/number/random/
*   Trying 0.0.0.0...
* Connected to example.com (0.0.0.0) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: example.com
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> GET /number/random/ HTTP/1.1
> Host: example.com
> User-Agent: curl/7.49.1
> Accept: */*
> 
< HTTP/1.1 302 Found
< Content-Length: 235
< Content-Type: text/html; charset=utf-8
< Date: Sun, 07 Aug 2016 18:19:27 GMT
< Location: http://localhost:5000/number/42/
< Server: Caddy
< Server: gunicorn/17.5
< 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
* Connection #0 to host example.com left intact
<p>You should be redirected automatically to target URL: <a href="/number/42/">/number/42/</a>.  If not click the link.

7. How can someone who is starting from scratch reproduce this behavior as minimally as possible?

Use the above Caddyfile, and set up a simple redirect application.

from flask import Flask, redirect, url_for


app = Flask(__name__)


@app.route('/number/random/')
def random():
    return redirect(url_for('number', number=42))


@app.route('/number/<number>/')
def number(number):
    return number

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 21 (10 by maintainers)

Most upvoted comments

Hello,

I have an issue that might be the same, with a different scenario that might be easier to reproduce. If it’s indeed the same root cause, maybe it will help clarify the issue at hand 😃

In my Caddyfile:

https://mycaddy.com {
  ...
  proxy /foo http://1.2.3.4:8181 {
    without /foo
  }

So my Caddy front-end redirects /foo/* to http://1.2.3.4:8181/*. It works… except that if upstream sends a 301 redirection, then the Location header contains the upstream address. It seems to me that Caddy should substitute this.

Example:

$ curl -I https://mycaddy.com/foo/bar
HTTP/1.1 301 Moved Permanently
Date: Mon, 08 Aug 2016 22:29:45 GMT
Location: http://1.2.3.4:8181/bar/
Server: Caddy
Server: Upstream
X-Frame-Options: DENY
Content-Type: text/plain; charset=utf-8

Then my browser happily goes directly to http://1.2.3.4:8181/bar/ 😦 I think the upstream server should not be exposed (whether it is public or not), and Caddy should substitute this with the corresponding “downstream” URL.

To reproduce, you need any downstream “flat files” http server that redirects /xxx to /xxx/ when /xxx is a directory (which I believe many http servers do, Caddy included, except maybe at server root).

So the general problem seems to be that Caddy leaves the original “incorrect” Location: header, whereas the “correct” header should be the “proxied” location.

So, does it help, or is it a completely different issue and have I missed something obvious in the options ?

Edit: using Caddy 0.9.0