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

Caddy proxy redirects to wrong localhost? #444

Closed
cboettig opened this issue Dec 18, 2015 · 20 comments
Closed

Caddy proxy redirects to wrong localhost? #444

cboettig opened this issue Dec 18, 2015 · 20 comments

Comments

@cboettig
Copy link

I'm trying to translate this simple nginx configuration (taken from the app documentation, see here) into a Caddyfile:

NGINX version:

http {

  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
    }

  server {
    listen 80;


    location /rstudio/ {
      rewrite ^/rstudio/(.*)$ /$1 break;
      proxy_pass http://localhost:8787;
      proxy_redirect http://localhost:8787/ $scheme://$host/rstudio/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_read_timeout 20d;
    }

My Caddyfile:

myserver.com

redir localhost:8787 {scheme}://{host}/rstudio 302
proxy /rstudio localhost:8787 {
  without /rstudio 
}

But this Caddyfile, rather than proxy-ing in to the application running on localhost of port 8787, literally redirects my browser to point to it's own localhost. Not sure where I've gone wrong; the nginx is a bit opaque to me (though it works just fine). Any suggestions?

@abiosoft
Copy link

Are you getting redirected to http://localhoslt/rstudio ?

@cboettig
Copy link
Author

I'm getting redirected to http://localhost:8787

@cboettig
Copy link
Author

If it helps to debug, the app is dockerized, so this behavior should be relatively straight-forward to reproduce if you have docker installed. e.g. just run: docker run -d -p 127.0.0.1:8787:8787 rocker/rstudio to get the app running on localhost, and then run the above Caddyfile (with appropriate hostname) and I think you should see what I see...

@abiosoft
Copy link

Alright. Got my hands tied right now but hopefully before end of the day (if someone else hasn't come around).

@mholt
Copy link
Member

mholt commented Dec 18, 2015

This line is what is causing your redirect:

redir localhost:8787 {scheme}://{host}/rstudio 302

But this line in nginx conf causes a rewrite:

rewrite ^/rstudio/(.*)$ /$1 break;

So, you want a rewrite, which changes the URL internally but doesn't issue a response. Basically this rewrite just strips rstudio from the URL.

@mholt
Copy link
Member

mholt commented Dec 18, 2015

Actually j/k, just get rid of the redir entirely in your Caddyfile, see if that works. (because you have the without line in your proxy directive)

@cboettig
Copy link
Author

@mholt thanks, I really appreciate your help in debugging this.

I tried dropping the redir but no luck, that still forwards me to the http://localhost:8787

Right, like you say, my reading was that the without was doing the same thing as rewrite. Interestingly, if I drop the without and the redir command, so I just have proxy /rstudio localhost:8787, then I get an "Input/output error" (which I do think comes from the app, as expected).

I also tried using the Caddy rewrite instead of without:

proxy /rstudio localhost:8787
rewrite {
regexp ^/rstudio/(.*)
to /
}

That doesn't go to http://localhost:8787, but throws the same error as it does with the proxy line alone.

I tried testing without the need for any rewrite to see if I could run it on root, using only the line:

proxy / localhost:8787

in the Caddyfile. And that sends me to http://localhost:8787....

So I'm stuck. In the nginx, I see the rewrite and redir clauses are placed within the location clause, but in caddy they are outside the proxy clause; guess that's not an issue since they declare the location explicitly. Were you able to give it a whirl with docker and a test server?

@mholt
Copy link
Member

mholt commented Dec 18, 2015

I'm not convinced Caddy is redirecting without that redir line. Check your app or your browser cache or at least the Network tab in the inspector tools to see what's really going on.

@cboettig
Copy link
Author

@mholt hmm, tried all that, still persists.

I've cleared the browser cache & all associated history, and have also tried switching to another domain name to avoid any caching that might exist between my computer and the server. I've reset the app. No luck.

It seems like the app itself is responsible for returning its localhost:8787 call instead of the server address, and I suppose the nginx code's "redirect" line is introduced to address that? For instance, if I curl -L https://example.com/rstudio, I get the expected error message from the app saying "your browser is not supported". Only in a real browser does the app end up directing to localhost...

@novaeye novaeye mentioned this issue Dec 19, 2015
@novaeye
Copy link

novaeye commented Dec 19, 2015

@cboettig maybe you need add proxy_header Host {host} in proxy section.

@mholt
Copy link
Member

mholt commented Dec 19, 2015

^ That's possible.

Strange that the app insists on forwarding like that. You can confirm this by looking at the Network tab of your browser's inspector tools - even a screenshot or two of the requests and the response headers might be useful. But try @novaeye's suggestion and see what happens.

@cboettig
Copy link
Author

@novaeye Thanks, that pretty much does it! With one problem. When hosting from root, all I need is this:

example.com
proxy / localhost:8787 {
  proxy_header Host {host}
}

Hosting from the /app sub-directory, I add without /app and append /app to Host:

  proxy /app localhost:8787 {
    without /app
    proxy_header Host {host}/app
  }

and it almost works, except that I need to go to https://example.com/app/ with the explicit trailing slash; https://example.com/app doesn't work.

This appears to be because the app loads a page looking for javascript at src="rstudio/rstudio.nochache.js". If the browser URL has the trailing slash, https://example.com/app/, then that relative URL corresponds to: https://example.com/app/rstudio/rstudio.nocache.js and all is well. But if the browser URL does not have the trailing slash, then the full URL of the javascript is missing the "app" part https://example.com/rstudio/rstudio.nocache.js and thus cannot be loaded. Not quite sure how to get around this. I tried proxy_header Host {host}/app/ but that doesn't make a difference.

@abiosoft
Copy link

This hack could work

redir /app /app/

@cboettig
Copy link
Author

@abiosoft Thanks, that works for me.

Incidentally, Caddy won't let me write a redir command without also giving a code (running v0.8), so I needed: redir /app /app/ 307 or I get the error Parse error: Invalid redirect code '/app/'

@cboettig
Copy link
Author

Thanks everyone for all the help, much appreciated and happy to have this all working nicely now!

@abiosoft
Copy link

Its my mistake. :)

Glad it worked in the end.

@ki9us
Copy link

ki9us commented Feb 27, 2017

I was having this same issue. novaeye's solutions didn't help, but using transparent did the trick.

Just in case someone else google's their way over here.

@uptad0112
Copy link

uptad0112 commented Mar 18, 2018

transparent doesn’t work for me in Caddy 0.10.11, has there been a regression?

My Caddyfile is:

https://forum.ac.upt.ro:443 {
	tls self_signed

	proxy / http://www.ac.upt.ro/forum/ {
		transparent
	}

	filter rule {
		content_type text/html.*
		search_pattern http://www.ac.upt.ro/forum
		replacement "https://forum.ac.upt.ro"
	}
	filter rule {
		content_type text/css.*
		search_pattern http://www.ac.upt.ro/forum
		replacement "https://forum.ac.upt.ro"
	}

	log ./access.log {
		rotate_size 100
		rotate_age  14
		rotate_keep 10
	}
	errors ./error.log
}

It should reverse-proxy an upstream http://www.ac.upt.ro/forum/ to a new Caddy-served downstream https://forum.ac.upt.ro/

I’ve setup a minimal index.php in http://www.ac.upt.ro/forum/:

<?php

if (isset($_GET['getnews']))
{
  header("HTTP/1.1 302 Moved Temporarily");
  header("Location: http://www.ac.upt.ro/forum/index.php?showtopic=2711&pid=149620&st=0&#entry149620");
  exit;
}

if (isset($_GET['showtopic']))
{
  exit("here's what's new..");
}

exit("try <a href='./?getnews'>?getnews</a> or <a href='./?showtopic'>?showtopic</a>");

?>

https://forum.ac.upt.ro/?showtopic works as expected.

But https://forum.ac.upt.ro/?getnews just serves directly the upstream reply from http://www.ac.upt.ro/forum/?getnews which has a hostnamed 302-redirect to http://www.ac.upt.ro/forum/index.php?showtopic=2711&pid=149620&st=0&#entry149620

I’d have expected the reply to be a transparent https://forum.ac.upt.ro/index.php?showtopic=2711&pid=149620&st=0&#entry149620

I can’t even find a workaround, something like a non-existing header_downstream Location {<Location{query}}{<Location{fragment}}.

@mholt
Copy link
Member

mholt commented Mar 18, 2018

@uptad0112 Caddy doesn't rewrite Location headers, if that's what you're asking for -- the application needs to redirect properly, i.e. it has to know it's behind a reverse proxy (this is true of most applications).

For further discussion, try asking on our forum, rather than 3-year-old closed issue: https://caddy.community

@uptad0112
Copy link

Apologies, I misunderstood from last year’s entry that the problem had been fixed by transparent.

Since my application is not proxy-aware, I’ve subscribed to the #1639 rewrite, and await for proxy_redirect #606

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

No branches or pull requests

6 participants