0

I understand proxies in concept (though have never set one up). I'm attempting to proxy Drupal, but I'm fairly sure that my problem is not related to Drupal. As I have been trying to determine the magic ingredient to get this working since this morning, I'll get right down to it:

Environment

I have two servers, as described below. Both are publicly accessible, but certain portions of the drupal site need to be accessible from the proxy server - specifically content that requires a login.

Proxy server (c5.domain.com)

  • c5.domain.com is a Concrete5 site, which means that there will be cookies associated with it. I'd like to avoid "crumb fallout" from cookie collisions if possible (not sure if this is an issue or not).
  • http://c5.domain.com/my-account/ should proxy to http://drupal.domain.com/proxy/
  • http://c5.domain.com/my-account/login is the url to the login page (http://drupal.domain.com/proxy/login on drupal)

Drupal Server (drupal.domain.com)

  • Pretty standard site with plenty of obnoxious redirects. The redirects seem to require a RewriteRule to get around.

What works (but isn't what I need)

While this allows full access to the drupal site, including the ability to log in, this has the obvious and unfortunate side effect of preventing access to the concrete5 site.

ProxyPass         /        http://drupal.domain.com/
ProxyPassReverse  /        http://drupal.domain.com/
ProxyPassReverseCookieDomain   c5.domain.com    drupal.domain.com

What I'm trying right now

With the following setup I am able to access drupal pages using the url http://c5.domain.com/my-account/..., but I am unable log in - attempting to do so reroutes me to http://c5.domain.com/proxy/ (which redirects to /my-account/)

Apache

<Location /my-account/>
    ProxyPass http://drupal.domain.com/proxy/
    ProxyPassReverse http://drupal.domain.com/proxy/
    ProxyPassReverseCookieDomain drupal.domain.com c5.domain.com
    # the cookie path seems important...
    ProxyPassReverseCookiePath / /my-account/
</Location>

# These rules seem necessary, since drupal's mod-alias seems to
# feed the browser a path like `https://c5.domain.com/proxy/...`
RewriteRule ^/proxy/(.*)$ /my-account/$1 [R,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R,L]

Drupal Config

Here I try to make Drupal play nice with the proxy server:

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) &&
    'drupal.domain.com' === $_SERVER['HTTP_X_FORWARDED_HOST']
) {
  $base_url = "$protocol://{$_SERVER['HTTP_X_FORWARDED_HOST']}/proxy";
  $cookie_domain = '.drupal.domain.com';
  $conf['reverse_proxy'] = TRUE;
  $conf['reverse_proxy_addresses'] = array('55.55.55.55',);
} else {
  $base_url = "$protocol://{$_SERVER['SERVER_NAME']}";
}
0

The problem:

The login form posts to the URL Drupal knows about: /proxy. That means that the proxy server receives a request for http://c5.domain.com/proxy, instead of http://c5.domain.com/my-account. I thought I could solve this with a redirect:

RewriteRule ^/proxy/(.*)$ /my-account/$1 [R,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R,L]

As it turns out, POST data is not forwarded with most redirects.

A Solution:

There is an exception to this rule: a 307 will forward POST data. Something like this works:

RewriteRule ^/proxy/(.*)$ /my-account/$1 [R=307,L]
RewriteRule ^/my-account/proxy/(.*)$ /my-account/$1 [R=307,L]

A caveat:

Naturally this solution is not without its pros and cons. Most browsers notify the user of the redirect (appropriately, since the POST data could be sent anywhere) and ask the user if they mean to send the data to the new URL. Since few users are likely to understand the notification, this option can lead to confusion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.