WS7+PHPPack: PHP Path Info for URL Rewrites
I've got WS7.0u1 running with PHPPack 5.2.0. Before cutting over our production servers running a PHP application, I thought I'd give it a spin on a personal server running Gallery2. One of the feature you want to enable with Gallery is URL rewriting, which can be done via Apache mod_rewrite, IIS ISAPI_Rewrite, or PHP Path Info. Clearly only the last is a viable option for me, however when I tried to run the test to verify it would work, it would fail with "No input file specified."
After much searching, I found this is a common problem with PHP when enabled as FastCGI, and some folks claimed adding this to php.ini would clear it up:
cgi.force_redirect = 1
However the only thing that worked for me was to define doc_root in php.ini as well. Once I set that, the Gallery "PHP Path Info" test passed. Thats progress, but I do plan on running virtual hosts within a single WS7 instance, each with its own doc_root. Is there a way to accomplish this?
thanks-
Rama
[1007 byte] By [
rama-ra] at [2007-11-27 10:24:40]

# 2
I haven't tried this directly, so I'm not positive this will work. I think this would do the trick for you though:
Basically you want a different set of preferences for the PHP engine for each VS (a different doc root, etc).
#Sun FastCGI config
Service fn=responder-fastcgi
app-path="/export/SOWS/third-party/php/php_fcgi"
bind-path="$(lc($urlhost))"
req-retry=5
type="*magnus-internal/fastcgi*"
app-env="PHPRC=/export/SOWS/third-party/php/$(lc($urlhost))_config"
app-env="PHP_FCGI_CHILDREN=10"
app-env="PHP_FCGI_MAX_REQUEST=200"
min-procs=1
restart-interval=10
rlimit_cpu=60
This would use a different PHP process and php.ini for each host name (extracting the Host: header from the request). The php.ini file would live in an appropriately named sub directory of /export/SOWS/third-party/php/ (e.g. /export/SOWS/third-party/php/www.foobar.com_config).
It might be possible to directly set the document root in the obj.conf instead of the php.ini though:
#Sun FastCGI config
Service fn=responder-fastcgi
app-path="/export/SOWS/third-party/php/php_fcgi"
bind-path="$(lc($urlhost))"
req-retry=5
type="*magnus-internal/fastcgi*"
app-env="PHPRC=/export/SOWS/third-party/php/config"
app-env="PHP_FCGI_CHILDREN=10"
app-env="PHP_FCGI_MAX_REQUEST=200"
app-env="DOCUMENT_ROOT=/home/$(lc($urlhost))/"
min-procs=1
restart-interval=10
rlimit_cpu=60
This would use the same php.ini for all PHP processes (and would still use a separate PHP runtime for each VS), and would set the DOCUMENT_ROOT environment variable for PHP to /home/whatever/ (where whatever is the extracted lower case value of the HTTP Host: request header).
Experiment a little. Let me know what you come up with. I've been wanting to use the URL Rewrite option of Gallery2 for a little while and have been considering re-writing the mod_rewrite expressions into WS7 syntax.
# 8
I've been putting off rewriting the Gallery2 mod_rewrite rules for a while. This discussion finally got me to stop being complacent and do it.
I've enable the Gallery2 URL Rewrite module with these options:
Show Item
Download Item
Add Comment
View Comments
Slideshow
RSS
Simple RSS Feed
Updates Album
Popular Album
Random Album
My Gallery2 has its own vanity domain, so it's deployed as the root of the URI space.
Gallery2 helpfully generated an htaccess file with these rules (I've annotated for my own understanding - Please point out errors for me):
RewriteBase /
# Stop processing is the requested file actually exists, or the request is
# for main.php or gallery_remote2.php
# I'm opting to skip this in my translation. It seems a bit unneeded to me.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} gallery\_remote2\.php
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule .-[L]
# If the request is for /popular, and the URI is _not) for /main.php, grab
# Restart the request with the URI changes to the canonical album syntax, and
# append the query string to the end of the new URL (used for paging to pages past
# the front page of the album).
# I notice that all the rules specifically call out main.php in their check. This seems
# overkill to me, so I'll just check once at the beginning of my translation
RewriteCond %{THE_REQUEST} /popular(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=dynamicalbum.PopularAlbum[QSA,L]
# Same, but for Updates
RewriteCond %{THE_REQUEST} /updates(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=dynamicalbum.UpdatesAlbum[QSA,L]
# Same, but for Random
RewriteCond %{THE_REQUEST} /random(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=dynamicalbum.RandomAlbum[QSA,L]
# URI space for downloading items (e.g. "Save Image")
RewriteCond %{THE_REQUEST} /d/([0-9]+)-([0-9]+)/([^/?]+)(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=core.DownloadItem&g2_itemId=%1&g2_serialNumber=%2&g2_fileName=%3[QSA,L]
# More of the same, but for the slideshow
RewriteCond %{THE_REQUEST} /v/([^?]+)/slideshow\.html(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=slideshow.Slideshow&g2_path=%1[QSA,L]
# Comment viewing
RewriteCond %{THE_REQUEST} /c/view/([0-9]+)\.html(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=comment.ShowAllComments&g2_itemId=%1[QSA,L]
# Comment adding
RewriteCond %{THE_REQUEST} /c/add/([0-9]+)\.html(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=comment.AddComment&g2_itemId=%1[QSA,L]
# RSS and Simple RSS rules
RewriteCond %{THE_REQUEST} /rss/([^\/\?]+)(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=rss.Render&g2_name=%1[QSA,L]
RewriteCond %{THE_REQUEST} /srss/([0-9]+)(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_view=rss.SimpleRender&g2_itemId=%1[QSA,L]
# The main URL cruft for viewing most items. I should probably make this my first
# "Real" rule
RewriteCond %{THE_REQUEST} /v/([^?]+)(\?.|\ .)
RewriteCond %{REQUEST_URI} !/main\.php$
RewriteRule ./main.php?g2_path=%1[QSA,L]
My translated rewrite rules for Web Server 7 are:
# At the top of my default block
# Only enter this stanza if this request is for my vanity VS for photos, and the URI isn't
# for /main.php
<If $urlhost = "photos.foo.com"
and $uri !~ '/main\.php'>
# If the request is for /popular
<If $url =~ '/popular(\?(.*)|())'>
# Restart the request with the canonical URI (and query string, represented here
# by "&$2" - Watch for it below too, but notice that the backreference ID changes
# based on where the parens are in the expression)
AuthTrans fn="restart" uri="/main.php?g2_view=dynamicalbum.PopularAlbum&$2"
</If>
# If the request is for /updates
<ElseIf $url =~ '/updates(\?(.*)|())'>
# Restart with canonical URI and query string
AuthTrans fn="restart" uri="/main.php?g2_view=dynamicalbum.UpdatesAlbum&$2"
</ElseIf>
# etc
<ElseIf $url =~ '/random(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=dynamicalbum.RandomAlbum&$2"
</ElseIf>
# etc
<ElseIf $url =~ '/d/([0-9]+)-([0-9]+)/([^/?]+)(\?(.*)|())'>
# Restart with the canonical URI and query string, but notice that the backreference
# for the query match is now $5 rather than $2 above
AuthTrans fn="restart" uri="/main.php?g2_view=core.DownloadItem&g2_itemId=$1&g2_serialNumber=$2&g2_fileName=$3&$5"
</ElseIf>
# etc
<ElseIf $url =~ '/v/([^?]+)/slideshow\.html(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=slideshow.Slideshow&g2_path=$1&$3"
</ElseIf>
# etc
<ElseIf $url =~ '/c/view/([0-9]+)\.html(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=comment.ShowAllComments&g2_itemId=$1&$3"
</ElseIf>
# etc
<ElseIf $url =~ '/c/add/([0-9]+)\.html(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=comment.AddComment&g2_itemId=$1&$3"
</ElseIf>
# etc
<ElseIf $url =~ '/rss/([^\/\?]+)(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=rss.Render&g2_itemId=$1&$3"
</ElseIf>
# etc
<ElseIf $url =~ '/srss/([0-9]+)(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_view=rss.SimpleRender&g2_itemId=$1&$3"
</ElseIf>
# etc
<ElseIf $url =~ '/v/([^?]+)(\?(.*)|())'>
AuthTrans fn="restart" uri="/main.php?g2_path=$1&$3"
</ElseIf>
</If>
I'm pretty happy with the results so far.
Also remember that this set of rules only restarts requests coming into the server; it does nothing to make Gallery2 write the URLs in a shorter, friendlier way. You still have to turn on the Gallery2 URL Rewrite module, etc. This tickles the Gallery2 code that generates the links, etc.