Problem getting Rails to emit the correct (proxy) domain in route urls

Behind the scenes my app runs like this:

  http://myapp.mydomain.com/myapp and     and   https://myapp.mydomain.com/myapp     are Apache 2.2 virtual hosts proxy-balanced to a mongrel cluster on the same machine.

But I need to make these available here:

  https://www.mydomain.com/myapp     and   https://myapp.mydomain.com/myapp     are on a second server using ProxyPass and ProxyPassReverse to point to the first

Unfortunately the second server is running Apache 2.0 or I'd do the proxy balancing there. I assure you that getting the proxying, the subfolder, and various necessary transitions between HTTP and HTTPS working is collectively no fun at all. But I'm writing about a particular problem:

In my routes I have

    HTTPS_PROTOCOL = (Rails.env.production? || Rails.env.test?) ? "https" : "http"

    map.with_options :protocol => HTTPS_PROTOCOL do         map.resource :session, :requirements => {:protocol => HTTPS_PROTOCOL}         map.logout '/logout', :controller => 'sessions', :action => 'destroy'         map.login '/login', :controller => 'sessions', :action => 'new'     end

In my views I make reference to login_path and logout_path and these correctly form fully-qualified absolute URLs which include the https:// protocol directive. But **they point to the wrong server**. I am supposed to get https://www.mydomain.com/myapp/login but instead I get https://myapp.mydomain.com/myapp/login.

What do I have to do to get Rails to generate these route urls with the proxy domain instead of request.host?

Thanks,

Sven

Check out this plugin: http://github.com/shuber/proxy

I'm taking a look, Sean. It looks very promising, but I do have a couple of questions. First, we weren't using Rewrite, but rather ProxyPass to set up the front-end server. That is, we have:

  ProxyPass /neworders http://client.example.com   ProxyPassReverse /neworders http://client.example.com

but your app expects this approach:

  RewriteRule ^/neworders(.*) http://client.example.com/orders$1 [L,P,E=originalUri:%{REQUEST_URI}]   RequestHeader append X_FORWARDED_URI %{originalUri}e

In theory I ought to be able to add something like

  RequestHeader append X_FORWARDED_URI %{originalUri}e

to the ProxyPass code above, but I haven't yet figured out how to stuff the server variable REQUEST_URI into the originalUri directive without using Rewrite (unfortunately it doesn't look like there's a way to reference REQUEST_URI directly in RequestHeader). Any idea how to do this?

I'm trying it your way at the moment, but it's introduced two problems that I wasn't having before. First, my image links (e.g. http://my.domain.com/myapp/image_assets/0000/0001/_thumb.jpg) aren't resolving. Second, I'm getting a redirect loop on SSL requests that makes me think that the ssl_requirement plugin may not be entirely happy. I'll report back if I learn more, but I'd appreciate any suggestions you might have.

Thanks,

-Sven

I found this page Environment Variables in Apache - Apache HTTP Server Version 2.2 which states

"Conditional Per-Request Settings

For additional flexibility, the directives provided by mod_setenvif allow environment variables to be set on a per-request basis, conditional on characteristics of particular requests. For example, a variable could be set only when a specific browser (User-Agent) is making a request, or only when a specific Referer [sic] header is found. Even more flexibility is available through the mod_rewrite's RewriteRule which uses the [E=...] option to set environment variables."

So, as far as I can tell it looks like only RewriteRule allows setting of environment variables so you'd have to use that instead with the [P] option.

I'll look into the image links and ssl_requirement plugin issues.

Thanks, Sean

My assets seem to be resolving correctly. Looks like you're using attachment_fu. Are you using something like

image_tag(@image.public_filename) ?

Thanks, Sean

Yes, I am using attachment_fu, and I am using image_tag(image.public_filename). I have images working right now, but only by dropping the creation of the X_FORWARDED_URI request header. So obviously other stuff isn’t working …

-Sven