nginxでDigest認証したかったけど対応して無かったよ。

nginx で autoindex + Digest認証したかったけど、この人Digest認証出来ない!

というわけでそれPla

/etc/nginx/nginx.conf

server {
    listen       80;
    server_name  private.example.com;

    access_log  logs/private.example.com.access.log  main;
    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:5000;
        # for Plack::Middleware::XSendfile
        proxy_set_header X-Accel-Mapping /srv/private/=/
    }
    location /data/ {
        internal;
        root /srv/private;
    }
}

/srv/private/private.psgi

use Plack::App::Directory;
use Plack::Builder;

my $users = {
    'dankogai' => 'kogaidan',
};

my $realm  = 'Private area';
my $secret = 's3cr3t';

my $app = Plack::App::Directory->new({ root => './data' })->to_app;

$app = builder {
    enable_if { $_[0]->{REMOTE_ADDR} eq '127.0.0.1' }
        'Plack::Middleware::ReverseProxy';
    enable 'Plack::Middleware::Auth::Digest', realm => $realm, secret => $secret,
        authenticator => sub {
            my ($username, $env) = @_;
            return $users->{$username};
        };
    enable 'Plack::Middleware::XSendfile', 'variation' => 'X-Accel-Redirect';
    $app;
};

autoindex を自分で書くのがめんどかったので、P::A::Directory にまかせて、
実際のファイルの配信は P::M::XSendfile を使い X-Accel-Redirect で nginx にまかせる。


こんな感じで、あとは /srv/private/data にいろいろ置けばよい。

あとがき

これぐらいなら Embedded Perl でやっても良かったのかなとか思った。