Tomas Doran wrote on 7/28/09 7:25 PM:
On 28 Jul 2009, at 14:55, Ash Berlin wrote:
On 28 Jul 2009, at 14:42, John SJ Anderson wrote:
$WORK-mate is working on a Cat app that (among other things) allows
authenticated users to download from a set of static files. He's
wondering what the best way is to set things up so that the Cat app
can handle the authentication/authorization parts of things but then
hand the static file serving part off to Apache.
Thanks for any help/hints.
john.
Largely depends on what webserver you are using. Lighttpd has
X-LIGHTTPD-Sendfile (or something similarly named) nginx has something
like X-Accel-Redirect which does the same (and can do more.) Both of
these tell the webserver to serve static content from a file. Hit
google for these env vars to find out how they work
There's an apache module which will do the same as the lighttpd one
http://tn123.ath.cx/mod_xsendfile/ Never used it mind.
Whilst this is all sage advice, remember - DO THE SIMPLEST THING WHICH
COULD POSSIBLY WORK.
Ergo, $c-serve_static_file($c-path_to(qw/ sekrit_files file1.avi /));
is probably a good bet (From Catalyst::Plugin::Static::Simple).
Unless you have dozens of concurrent users, all downloading large files
(where large is 10s of Mbs), then just do that - it's easy, it works,
you don't have to think about production vs development, etc.
This is also sage advice. It will work well in development, and can also work in
production if your cat app proves to scale to your demand.
With a little more code you can scale far more than C::P::S::S will allow. I
like to use mod_auth_tkt with Apache for general authn/authz tasks, and it works
just as well for one-time authn for serving static files.
Something like this (in MyApp.pm):
use Apache::AuthTkt;
__PACKAGE__-config(
auth_tkt_conf = '/etc/httpd/conf.d/auth_tkt.conf',
static_uri= 'http://mystatic.domain/authn/',
static_user = 'mystaticuser',
static_tokens = 'catalyst',
env = 'prod', # or 'dev' or 'test' or ...
);
sub serve_my_static_file {
my ($c, $file) = @_;
my $conf = $c-config;
my $env = $conf-{env} || 'dev';
if ($env eq 'dev') {
# do as t0m suggests
$c-serve_static_file($c-path_to('sekrit', $file));
}
else {
# if it doesn't exist (assuming same filesystem as MyApp)
# then return 404
if (! -s $c-path_to('sekrit', $file)) {
$c-res-status(404);
$c-res-body('not found');
}
else {
# let apache serve it
my $at = Apache::AuthTkt-new(
conf = $conf-{auth_tkt_conf}, # or hardcode secret
ignore_ip = 1, # in case req is proxied
);
my $ticket = $at-ticket(
uid = $conf-{static_user},
tokens = $conf-{static_tokens},
) or die $at-errstr;
my $uri = join('',
$conf-{static_uri},
$file,
'?auth_tkt=',
$ticket
);
$c-res-redirect($uri);
}
}
}
and then a mod_auth_tkt.conf something like:
TKTAuthSecret foobarbing123
TKTAuthDigestType MD5
Location /authn
# TKTAuthLoginURL must be present
# but in this case we assume all requests
# are pre-authenticated. Send someplace that
# returns a custom 401 or whatever.
TKTAuthLoginURL http://nosuchurl/
# really short. i.e., as long as it takes for
# the browser to receive the 302 and request the
# new uri. 2 seconds should be *ample*
TKTAuthTimeout 2
# *IMPORTANT* lest requests use the same token over
# and over again, negating its temporary intent.
TKTAuthTimeoutRefresh 0
# optional, really. just for example.
TKTAuthToken catalyst
# must match config in $at call above in perl
TKTAuthIgnoreIP on
# turn on to debug
TKTAuthDebug 3
# tell apache to protect this space
AuthType None
require valid-user mystaticuser
/Location
Many variations on the theme are possible of course, including putting the
auth_tkt value in the uri path instead of as a param and then using mod_rewrite
in apache to untangle it.
--
Peter Karman . http://peknet.com/ . pe...@peknet.com
gpg key: 37D2 DAA6 3A13 D415 4295 3A69 448F E556 374A 34D9
___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/