Search code examples
phpdrupaldrupal-7

$base_url problems in forms after upgrading Drupal


I believe I followed the instructions when upgrading Drupal (7.33 -> 7.39), but managed to break it.

The setup: The Drupal site is behind a reverse proxy:

<Location /app>
  ProxyPass http://back.example.com/drupal
  ProxyPassReverse http://back.example.com/drupal
  ProxyPassReverseCookiePath /drupal /app
</Location>

And in the sites/default/settings.php, there's this bit:

$conf['reverse_proxy_header'] = 'HTTP_X_FORWARDED_FOR';
if (!empty($_SERVER[$conf['reverse_proxy_header']])) {
  $base_url = 'http://front.example.com/app';
}

The problem: While some forms seem to work, generating a correct action attribute (<form action="/app/..." ...>), most (notably, everything in Admin area) are ignoring the $base_url, generating <form action="/drupal/..." ...>, so submit obviously fails.

I took a look at the source, but I can't figure out how it worked in the first place, because, as far as I can see, action is generated from drupal_build_form, which reads the action data from element_info('form'), which is populated by system_element_info, which, in turn, calls request_uri() - and there is nothing in request_uri() about $base_url.

I tried to clear caches with drush just in case I was missing something in the database, and it did not help.

EDIT: It seems most of the links are calling the url($path) function, which does the right thing. But it is not being called for the form's action attribute, except for a form that is being rendered from a plugin (and which doesn't seem to use element_info, but calls url to construct its action).

EDIT2: If it was not clear, $base_url has the correct value; it is just not getting applied (and I can't see where it would be applied).


Solution

  • The problem is indeed in system_element_info calling request_uri which is not taking care of $base_url...

    But as always in drupal you can alter things:

    function yourmodule_element_info_alter(&$type) {
      global $base_url;
    
      // Use $base_url for form action
      $type['form']['#action'] = $base_url . request_path();
    }