URL Rewrite + PHP LSAPI hate the $_SERVER array

Discussion in 'Bug Reports' started by SaltwaterC, May 24, 2010.

  1. SaltwaterC

    SaltwaterC New Member

    Long story short I installed LiteSpeed Web Server on one of my boxes for testing, evaluation, and benchmarking purposes. Some of my tests use a Drupal installation installed here: $DOC_ROOT/drupal.

    The used rewrite rule is pretty straightforward:

    At least this is what I though, but for 15 minutes I felt like a complete moron that isn't able to write a simple rewrite rule. Wait, actually the rewrite rule is fine, as the server log says: drupal/node/1 goes to drupal/index.php?q=node/1. Placing a small debug script that replaces Drupal's front controller confirms that $_GET['q']/$_REQUEST['q'] is indeed node/1. However, all the static content throws 404 errors. All the paths to the static content are brokenly generated by Drupal.

    Instead of:
    I got:
    Since none of my previous setups have this issue, the reason was pretty obvious: the web server isn't setting properly some parameters that PHP receives. Educated guess: $_SERVER.

    Instead of $_SERVER['SCRIPT_NAME'] = '/drupal/index.php' and $_SERVER['PHP_SELF'] = '/drupal/index.php', LSWS + Rewrite + PHP LSAPI insist on $_SERVER['SCRIPT_NAME'] = '/drupal/node/1'; and $_SERVER['PHP_SELF'] = '/drupal/node/1';. Actually the SCRIPT_NAME is the piece that actually breaks Drupal.

    I could "fix" it with some ini settings wizardry (auto_prepend_file) which executes this script for every PHP request:

    Ubuntu Server 10.04 LTS amd64
    LiteSpeed Web Server 4.0.14 Standard (x86 + Ubuntu's ia32-libs)
    PHP 5.3.2/Zend Server 5.0.1 + PHP LSAPI 5.3.1

    Just to be clear (if you actually "try this at home"): Zend Server/Zend Server CE includes a source package that contains PHP patches not available into the upstream PHP 5.3.2 as Zend says. Creating a binary compatible SAPI (including LSAPI) is a trivial task (if you manually pick all the dependencies, not too many), but the Zend extensions (Data Cache, Optimizer+) may or may not work. Data Cache works only with mod_php (software switch, had some rough discussions with the Zend guys about the lack of support for FastCGI), while Optimizer+ doesn't work beyond mod_php, FastCGI. This obviously shouldn't break LSAPI in any way as the $_SERVER superglobal is set by the web server.

    Later edit: the other PHP hog, besides Drupal (great for benchmarking), called Joomla also suffers because of this specific behavior of the web server.
    Last edited: May 24, 2010
  2. mistwang

    mistwang LiteSpeed Staff

    In order to exactly match Apache's behavior, those variables are set differently depends on how your rewrite rule was configured, at vhost level? or at context/directory/.htaccess level?

    I think you set the rewrite rule at vhost level, you can try configuring the rules another way.
  3. SaltwaterC

    SaltwaterC New Member

    The rewrite is configured at virtual host level. Indeed, the .htaccess and the virtual host configuration produces different results under Apache. As I am not into the .htaccess, since it adds server overhead plus the lack of using shared hosting at my company, I tried to use the virtual host configuration for this particular setup. Maybe LiteSpeed does a better job when using .htaccess, so far this is untested.

    However, a plain old <Location> directive works as expected under Apache if I have to use a different rewrite set for a particular subdirectory, while the "RewriteCond %{REQUEST_URI} ^/something" hack for LiteSpeed produces this kind of dumb behavior. I understand that this comes from Apache, thus the resolution most probably is "won't fix". And yes, I already tried to use the configuration lines for rewrite from the Apache's virtual host file, but the <Location> isn't doing anything. Obviously, I could replicate the same issue under LiteSpeed Enterprise. Also, placing the above rewrite rule (with minor changes) within a <Directory> block, fixes the issue under Apache. Obviously, the <Directory> configuration isn't supported by LiteSpeed rewrite support.

    FastCGI instead of LSAPI also works as expected. I tried with both a standard php-cgi spawned by LiteSpeed and the external daemon, php-fpm. I'll make an educated guess and say that spawn-fcgi+daemontools would work as expected as well.

    Long story short: mod_rewrite / LSWS rewrite + mod_php / PHP LSAPI are affected by this bug. Apache's bug, but still a bug as SCRIPT_NAME and PHP_SELF should always point to a real php file, not to the location previous to the URL rewrite process. FastCGI works as expected, always, under both Apache+mod_fcgid and LiteSpeed + php-cgi / php-fpm. I guess I should bug the Apache guys to fix it in order to have a fix in LiteSpeed.
  4. NiteWave

    NiteWave Administrator

    you can define a context under a vhost.

    in this drupal case, define a static context:
    URI: /drupal/
    Location: drupal
    Rewrite Rules:
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
    my simple test on a drupal 6.16 new installation, looks working.

    in above testing .htaccess is disabled.

    when enable .htaccess, the default drupal .htaccess under $docroot/drupal looks working well without any change.

Share This Page