Drupal detects whether it's using HTTPS by looking at $_SERVER['HTTPS']. This variable is of course not set to "YES" if Drupal runs in HTTP. If your Drupal site is behind an reverse proxy or load balancer that serves HTTPS but communicates with the web server via HTTP (i.e. Internet --HTTPS--> ReverseProxy --HTTP--> Apache), Drupal sets an incorrect $base_root. This causes various things to break -- most visibly, file uploads and AJAX.
Pound (http://www.apsis.ch/pound) sends an HTTP header, X_FORWARDED_PROTO, which is either "http" or "https". Detecting it solves this problem.
I haven't been able to discover whether other HTTP reverse proxies use the same variable, but I've seen discussion by the Rails folks suggesting that people who use Apache as a proxy should add RequestHeader set X_FORWARDED_PROTO "https" to their Apache configuration.
I've attached a patch which fixes this for users of Pound or appropriately configured Apache.
I filed a similar bug report for Drupal 5.2: http://drupal.org/node/183398
.
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | bootstrap.inc_.185161_3.patch | 859 bytes | ghoti |
| #4 | bootstrap.inc_.185161_2.patch | 871 bytes | ghoti |
| #2 | bootstrap.inc_.185161.patch | 576 bytes | ghoti |
| bootstrap.inc__8.patch | 576 bytes | ghoti |
Comments
Comment #1
ghoti commentedSee also: http://drupal.org/node/183537
Comment #2
ghoti commentedAttaching again to change status.
Comment #3
dries commentedThanks for the research and detailed background information, ghoti. In order for this patch to be 'committable', we'll want to add some comments to the code (and rework the code so the flow is slightly more readable). Without some extra information in the code, I'm afraid we'd not be able to understand it one or two years down the road. Thanks.
Comment #4
ghoti commentedThanks for the feedback.
Updated patch is attached. I've split the inline "if" into a regular if-elseif series, and added comments to describe what's going on.
I don't know whether an in-line if performs better than the more readable variety, but there isn't much we can do about it either way.
I note that Drupal 6 now also includes a "Reverse proxy" setting under admin/settings/performance, which mentions an additional header. Is there any point in exploring automation of that proxy detection? It seems odd that we'd autodetect in bootstrap.inc, then have a static setting stored in the database to override logging. Is there any reason *not* to use the X_FORWARDED_FOR header if it's there?
p
Comment #5
ghoti commentedbootstrap.inc hasn't changed at this spot, so the patch applies to 6.x-dev too.
Comment #6
ghoti commentedComment #7
catchMinor code style issue - comments have to break at column 80, yours goes a little over.
Comment #8
ghoti commentedFixed minor code style issue, updated for 6.0. If that's all this is waiting for, it's ready to be committed. :-/
Comment #9
ghoti commentedupdated for 6.1... same patch
Comment #10
ghoti commentedFor the time being, the logic from this can be hacked into settings.php, since $base_root is never an issue if $base_url is already set.
Comment #11
silverhammerdotcc commentedAs it seems this is a hot topic, I recently tried to apply this patch to my Drupal 5.7 and Drupal 6.1 sites, with some interesting results:
I am using Apache 2.0 to serve drupal.silverhammer.cc (Drupal 5), drupal6.silverhammer.cc (Drupal 6), www.silverhammer.cc (Drupal 5), and some other sites. I am providing SSL support through Pound 2.4.1.
My pound.cfg:
... with the Header lines added per suggestion from http://mongrel.rubyforge.org/wiki/Pound .
Before applying patch line to $base_root:
http://www.silverhammer.cc/user => http://www.silverhammer.cc/user/1
BUT...
https://www.silverhammer.cc/user => https://www.silverhammer.ccuser/1 (Host not found)
Similarly with http://drupal6.silverhammer.cc
After applying patch line to $base_root:
https://drupal6.silverhammer.cc/user => https://drupal6.silverhammer.cc/user/1
BUT... with Drupal 5....
https://www.silverhammer.cc/user => https://www.silverhammer.ccuser/1 (Host not found)
still.
So, Drupal 5 should be recognizing this header just the same... is there a new rewrite functionality found in Drupal 6 that can be ported over to 5?
Repeatable results anyone?
Comment #12
ghoti commentedI wasn't sure how to repeat your results in 5.x; the patch works for me, and the problem it was fixing doesn't look like what you're seeing. But your pound configuration looks a little odd; normally, the "AddHeader" line and "Service...End" block would live inside the ListenHTTPS...End block. Here's a sample based on my pound.cfg:
Incidentally, there's now a patch for 7.x-dev:
#313145: Support X-Forwarded-* HTTP headers alternates
Comment #13
gmania commentedFor anyone running into this issue, here's what needs to be added to settings.php in Drupal 6 to avoid this problem (based on patch provided by Ghoti in #8)
Testing and working with AWS Elastic Load Balancer