Skip to content

Instantly share code, notes, and snippets.

@stubbetje
Created March 7, 2012 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stubbetje/1992707 to your computer and use it in GitHub Desktop.
Save stubbetje/1992707 to your computer and use it in GitHub Desktop.
RewriteBase problem with usage in multiple different directories
RewriteEngine On
RewriteBase /
RewriteRule ^SESS.{13}/(.*)$ $1 [L,QSA]
# all others, check if exists and if not, redirect to index.php (front controller)
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

RewriteBase problem with usage in multiple different directories

Omschrijving

Door het gebruik van VirtualDocumentRoot zijn we verplicht om een RewriteBase toe te voegen aan onze .htacces. Anders worden de URL's niet op een correct manier herschreven door mod_rewrite.

Maar als je dit zelfde project in een andere directory structuur gebruikt, dan moet de RewriteBase ook aangepast worden, anders worden de URL's verkeerd herschreven. De .htaccess file zit echter steeds ook in het versie beheer, dus dezelfde code base gebruiken in verschillende directory structuren zorgt hierdoor voor problemen.

Een eenvoudige oplossing is het verwijderen van .htaccess uit het versie beheer, maar dit is niet werkbaar om bij te houden als er een nieuwe release moet gemaakt worden (.htaccess in alle verschillende directory structuren opsporen en wijzigingen aanbrengen waar nodig...)

Daarom zoeken we een alternatieve manier om dit op te lossen.

In de test case hebben we volgende directory structuur opgezet die een versimpelde versie is van het geen we mee werken:

/local/www/paashaas.dev
└── html
    ├── .htaccess
    └── index.php

/local/www/kerstman.dev
└── html
    └── paashaas -> /local/www/paashaas.dev/html

/local/www/users.dev
└── user13
    └── site
        └── project1
            └── html -> /local/www/paashaas.dev/html

De originele "codebase" staat onder /local/www/paashaas.dev/html en is bereikbaar via http://paashaas.dev/. Diezelfde code base wordt ook nog gebruikt in twee andere "sites":

Deze worden via symbolic links geshared in deze test case, maar dit hoeft daarvoor niet.

Voor het gemak gaan we de 3 test cases ook afkorten naar PAASHAAS, KERSTMAN en USER13.

Originele begin situatie

Werken WEL:

Werkt NIET:

Reden waarom dit niet werkt bij KERSTMAN, is doordat in de .htaccess een RewriteBase / staat, waardoor de url altijd wordt herschreven naar /index.php. Dit zou in dit geval /paashaas/index.php moeten zijn.

# vim: syn=apache:ts=4:sw=4:nu
ServerName dev
Listen 5211
NameVirtualHost *
LoadModule php5_module modules/libphp5.so
DirectoryIndex index.php
AddType application/x-httpd-php .php
AddType application/x-httpd-php .phtml
Options +Indexes
# enable mime
DefaultType text/plain
#<IfModule mime_module>
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
# AddType text/css .css
#</IfModule>
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog logs/access_log vcommon
<VirtualHost *:*>
ServerName paashaas.dev
DocumentRoot /local/www/paashaas.dev/html
<Directory "/local/www/paashaas.dev/html">
Options +Indexes
</Directory>
</VirtualHost>
<VirtualHost *:*>
ServerName kerstman.dev
DocumentRoot /local/www/kerstman.dev/html
<Directory "/local/www/kerstman.dev/html">
Options +Indexes
</Directory>
</VirtualHost>
UseCanonicalName Off
<VirtualHost *>
# mass virtualhost:
# project1.user13.dev
# => becomes: /local/www/users.dev/user13/site/project1/html
VirtualDocumentRoot /local/www/users.dev/%2/site/%1/html
<Directory "/local/www/users.dev/">
Options +ExecCGI +Indexes
</Directory>
</VirtualHost>
<?php
header( 'Content-Type: text/plain; charset=utf-8' );
define( 'SESSION_ID_PREFIX' , 'SESS' );
define( 'SESSION_ID_LENGTH' , 13 );
// redirect if no SESSxxxxxxxxx a first path part of the request url
$url = parse_url( $_SERVER[ 'REQUEST_URI' ] );
$path = explode( '/' , trim( $url[ 'path' ] , '/' ) );
if( empty( $path[0] )
|| strlen( trim( $path[0] ) ) != ( strlen( SESSION_ID_PREFIX ) + SESSION_ID_LENGTH )
|| substr( $path[0] , 0 , strlen( SESSION_ID_PREFIX ) ) !== SESSION_ID_PREFIX )
{
array_unshift( $path , generateFakeSessionId( SESSION_ID_LENGTH , SESSION_ID_PREFIX ) );
header( sprintf(
'Location: /%s?%s#%s'
, implode( '/' , $path )
, isset( $url[ 'query' ] ) ? $url[ 'query'] : null
, isset( $url[ 'fragment' ] ) ? $url[ 'fragment'] : null
) );
exit;
} else {
$session_id = substr( $path[0] , strlen( SESSION_ID_PREFIX ) , SESSION_ID_LENGTH );
echo 'Hello session ' , $session_id , PHP_EOL;
echo PHP_EOL , 'The url you requested: ' , implode( '/' , array_slice( $path , 1 ) ) , PHP_EOL;
}
echo PHP_EOL
, 'PHP version : ' , phpversion() , PHP_EOL
, 'Apache version : ' , apache_get_version() , PHP_EOL;
function generateFakeSessionId( $length , $prefix = null )
{
$id = $prefix;
for( $i = 0 ; $i < $length ; $i++ ) {
$id .= strtoupper( dechex( rand( 0 , 15 ) ) );
}
return $id;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment