Search code examples
ruby-on-railspathnginxroutesproduction-environment

rails route path not shown in browser (sometimes)


After deploying my rails 3 app in production I noticed that paths are not always shown in the browser window. For example going to login or my_profile links would still only show http://my_app.com instead of expected http://my_app.com/login or http://my_app.com/my_profile. The views did change and were functional. I could also see the database being hit and views being rendered from the logs (which led me to believe it was not a simple browser cache issue). Going directly to http://my_app.com/login worked, however, using the links in the app would take me to the expected place while leaving the login url displayed. I tried it in several browsers (firefox, opera and chrome) and got the same behavior. The app was deployed under nginx + passenger and later nginx + thin cluster. My question is, whats going on? Could it be nginx settings or my production environment settings? I am not sure where to start.

Running curl -v my_app.com shows

* About to connect() to my_app.com port 80 (#0)
* Trying xx.xx.xx.xx... connected
* Connected to my_app.com (xx.xx.xx.xx) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.21.1 (x86_64-apple-darwin10.4.0) libcurl/7.21.1 OpenSSL/1.0.0a zlib/1.2.5 libidn/1.19
> Host: my_app.com
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Set-Cookie: ARPT=PKKIKIS10.0.81.64CKILJ; path=/
< Content-Type: text/html; charset=utf-8
< Status: 200
< X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.5
< ETag: "fce6dec3543058bec16175466020a906"
< X-Runtime: 7
< Content-Length: 787
< Cache-Control: private, max-age=0, must-revalidate
< Server: nginx/0.7.62 + Phusion Passenger 2.2.4 (mod_rails/mod_rack)
< P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
< X-Cache: MISS from server.com
< Via: 1.0 server.com:8080
< Connection: close
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>http://my_app.com/</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta name="generator" content="Hover Redirect Service">
</head>
<frameset framespacing="0" rows="100%,*" cols="100%" frameborder="no" border="0">
<frame name="DDIRECTXYZZY2" scrolling="auto" src="http://xxx.xx.xxx.xxx" noresize>
<frame name="DDIRECTXYZZY" scrolling="no" noresize>
<noframes>
<h1><a href="http://xxx.xx.xxx.xxx">http://my_app.com/</a></h1>
<p>Please <a href="http://xxx.xx.xxx.xxx">click here</a> to view the non-framed versi on.</p>
</noframes>
</frameset>
</html>

So that is clearly a problem. The whole thing gets framed by the DNS redirect? The setup is not Phusion Passenger + nginx. It was originally, but now its thin + nginx. Also, when going directly to ip address of the app, things are just fine. When going to the domain name, I get the framed version. curl -v response of just the ip address also looks normal (like its loading the entire page).


Solution

  • The problem is almost certainly your frames. The inner frame is loading the correct content but because you're (presumably) not targeting 'top' in your links (or whatever it is), the browser is still showing the URL of the outermost frame.

    Targeting frames: http://www.w3.org/TR/html4/present/frames.html#h-16.3

    If you were not expecting to see frames in your response at all then it's likely they're the responsibility of a shoddy "DNS" service. Get a real DNS address pointed to your server and you'll be singing.