Here’s how I did it (got it working properly) but wonder if I can
clean it up a bit (especially about trailing slash and
/~blah/file.php)
the rewrites for user directory (not including php) are from this
server {
listen 80;
server_name domain.tld;
root /usr/local/www/data;
index index.php;
location /~ {
if ($request_uri ~ ^/~([^/])(/.[^/]|)(/)$) {
set $homedir $1;
set $filedir $2;
set $trailingslashes $3;
rewrite ^/~([^/])(/|$)(.*)$ f~/$3;
}
}
location f~/ {
alias /home/$homedir/public_html/;
if (-d /home/$homedir/public_html$filedir) {
rewrite ^f~/(.*) ~/$1;
}
}
location ~/ {
#autoindex on;
alias /home/$homedir/public_html/;
if ($trailingslashes = “”) {
rewrite .* /~$homedir$filedir/ redirect;
}
}
location ~ .php$ {
if ($request_uri ~ ^/~([^/])(/.)$) {
set $newroot /home/$1/public_html;
set $filedir $2;
}
if ($newroot = “”) {
set $newroot /usr/local/www/data;
set $filedir $fastcgi_script_name;
}
if (!-f $newroot$filedir) {
return 404;
break;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $newroot$filedir;
include fastcgi_params;
}
location ~ /.ht {
deny all;
}
}
On Sat, Mar 14, 2009 at 2:13 PM, Edho P Arief [email protected]
wrote:
    root /usr/local/www/data;
        if ($trailingslashes = “”) {
            set $newroot /usr/local/www/data;
    }
    location ~ /.ht {
    deny all;
    }
}
and apparently it doesn’t respect index 
…and 10 hours later I fixed it by myself. Tested with most common
cases, also ensured basic logic. Can be cleaned up better (or perhaps
squash more bugs, if any) but I’m too sleepy right now.
Also probably rather slow. My own connection is currently slow and I
only tried this on remote system.
server {
listen 80;
server_name genshiken.unit.itb.ac.id;
index index.php;
#change /usr/local/etc/nginx/ to default nginx root path
if ($request_filename ~
^/usr/local/etc/nginx//~([a-zA-Z0-9])(.[^/]|)(/)$) {
#$org_uri is old, unused variable but might have some
use for improvement (or deletion)
set $org_uri $request_uri;
set $is_userdir 1;
set $newroot /home/$1/public_html;
set $homedir $1;
set $filedir $2;
set $slashes $3;
rewrite ^/~. f~/;
}
if ($is_userdir != 1) {
set $newroot /usr/local/www/data;
#set to random string if not userdir (see above).
set $org_uri zxzz123;
}
root $newroot;
location f~/ {
#$is_ok: check wheter to apply rewrite or not at this
and next location
set $is_ok 1;
if (-d /home/$homedir/public_html$filedir) {
set $is_ok 2;
rewrite ^f~/$ d~/;
}
if ($is_ok = 1) {
rewrite ^f~/$ finaldest~/;
}
}
location d~/ {
#add slash for directory (if there's none yet - to
avoid unwanted rewrite by nginx)
if ($slashes = “”) {rewrite ^d~/$ /~$homedir$filedir/
redirect; set $is_ok 1; }
if ($is_ok = 2) {rewrite ^d~/$ finaldest~/; set $is_ok
1; }
}
location finaldest~/ {
#extra: user-specific rewrite
if ($homedir = sampleuser) {rewrite ^finaldest~/$
sampleuser~/;}
#final destination (if there’s no user-specific rewrite)
rewrite ^finaldest~/$ $filedir$slashes;
}
#user-specific rewrite block
location sampleuser~/ {
#or sampleuser~/$filedir$slashes; to get subfolder
location ruling
rewrite ^sampleuser~/$ $filedir$slashes;
#wordpress. haven’t able to make use of try_files or
other modern mechanics yet
if (!-e $request_filename) {
rewrite ^(.*)$ /blog/index.php?q=$1 last;
break;
}
}
#just a standard php block.
location ~ \.php$ {
if (!-f $document_root$fastcgi_script_name) { return
404; break; }
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
On Sat, Mar 14, 2009 at 11:25:10AM -0700, mike wrote:
location ^/~(.+) {
root /home/$1/public_html/;
}
Perhaps? Not sure. I should probably try it but I’m too lazy. Igor
would probably know how to hack it quick.
It should be:
location ^/~(.+?)(/.+)?$ {
alias /home/$1/public_html$2;
}
because
root /home/$1/public_html/;
will map /~mike/some/page.html to
/home/mike/public_html/~mike/some/page.html;
Is all you want the ability to have
foo.com/~username/ ?
If so I have it working a lot easier. Well, at least for ~mike. But
with the new regex location/etc. support it might be able to work
without that.
something like
location ^/~(.+) {
root /home/$1/public_html/;
}
Perhaps? Not sure. I should probably try it but I’m too lazy. Igor
would probably know how to hack it quick.
I assume .42 will be coming soon then with at least:
patch.captures.41
the patch for auth_basic_user_file capture support

On Sat, Mar 14, 2009 at 12:35:12PM -0700, mike wrote:
I assume .42 will be coming soon then with at least:
patch.captures.41
the patch for auth_basic_user_file capture support
Yes, I planned it for Monday.
On Sat, Mar 14, 2009 at 09:33:43PM +0300, Igor S. wrote:
something like
location ^/~(.+?)(/.+)?$ {
alias /home/$1/public_html$2;
}
The location should be
- location ^/~(.+?)(/.+)?$ {
- location ^/~(.+?)(/.*)?$ {
Also I have found two bugs in alias captures, the patch is attached.
2009/3/14 Igor S. [email protected]:
It should be:
 location ^/~(.+?)(/.+)?$ {
     alias  /home/$1/public_html$2;
 }
because
   root /home/$1/public_html/;
will map /~mike/some/page.html to /home/mike/public_html/~mike/some/page.html;
I thought about that. Thanks.
This should be put down on the wiki as a howto: mod_userdir equivalent
or whatever
On Sat, Mar 14, 2009 at 12:51:06PM -0700, mike wrote:
and maybe change those 500 errors to 403’s? 
The new patch that logs error and returns 403 if passwd file is not
found.
and maybe change those 500 errors to 403’s? 
2009/3/14 Igor S. [email protected]:
On Sun, Mar 15, 2009 at 2:28 AM, Igor S. [email protected] wrote:
without that.
It should be:
Also I have found two bugs in alias captures, the patch is attached.
–
Igor S.
Igor Sysoev
Doesn’t work, which, if iirc, I’ve tried before - or else I wouldn’t
resort to something like the one I mailed before
And yes, I’ve also applied that patch
I found this to be working. Should be faster than before but dunno.
shrugs
Or is there a better way doing this? I’m planning to replace my
lighttpd installation with nginx using this config.
server {
listen 80;
server mahleetserver.com;
index index.php;
client_max_body_size 3m;
if ($uri ~ ^/~edho/blog) {
set $err404 /~edho/blog/index.php;
set $is_custom404 1;
}
if ($is_custom404 != 1) {
set $err404 /404.html;
}
error_page 404 $err404;
#username should only contain these letters, right?
location ~ /\~([A-Za-z\d\-_\s]+)(.*)$ {
alias /export/home/$1/public_html$2;
location ~ \.php {
#it'll be rather broken if not done this way
location ~ /\~([A-Za-z\d\-_\s]+)(.*)$ {
set $ud_user $1; set $ud_file $2;
root /export/home/$ud_user/public_html;
try_files $ud_file @404;
fastcgi_pass php-cgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$ud_file;
include fastcgi_params;
}
}
}
location / {
root /var/www/data;
rewrite ^/wiki/([^?]*)(?:\?(.*))?
/w/index.php?title=$1&$2;
rewrite ^/wiki /w/index.php;
rewrite ^/edogawaconan/signature.jpg
/edogawaconan/signature.php;
}
location ~ .php$ {
root /var/www/data;
try_files $uri @404;
fastcgi_pass php-cgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.ht {
deny all;
}
location @404 {
return 404;
}