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 http://httpd.apache.org/docs/2.2/env.html 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