
Chapter 11: Recipes- P2
Making Use of Autoflush
Every once in a while you may have to output a very large component or file
to the client. Simply letting this accumulate in the buffer could use up a lot
of memory. Furthermore, the slow response time may make the user think
that the site has stalled.
Example 11-4 sends out the contents of a potentially large file without
sucking up lots of memory.
Example 11-4. send_file-autoflush.comp
<%args>
$filename
</%args>
<%init>
local *FILE;
open FILE, "< $filename" or die "Cannot open
$filename: $!";
$m->autoflush(1);
while (<FILE>) {
$m->print($_);
}
$m->autoflush(0);

</%init>
If each line wasn't too huge, you might just flush the buffer every once in a
while, as in Example 11-5.
Example 11-5. send_file-flush-every-10.comp
<%args>
$filename
</%args>
<%init>
local *FILE;
open FILE, "< $filename" or die "Cannot open
$filename: $!";
while (<FILE>) {
$m->print($_);
$m->flush_buffer unless $. % 10;
}
$m->flush_buffer;
</%init>
The unless $. % 10 bit makes use of the special Perl variable $., which
is the current line number of the file being read. If this number modulo 10 is
equal to zero, we flush the buffer. This means that we flush the buffer every
10 lines. Replace the number 10 with any desired value.
User Authentication and Authorization

One problem that web sites have to solve over and over is user
authentication and authorization. These two topics are related but not the
same, as some might think. Authentication is the process of figuring out if
someone is who he says he is, and usually involves checking passwords or
keys of some sort. Authorization comes after this, when we want to
determine whether or not a particular person is allowed to perform a certain
action.
There are a number of modules on CPAN intended to help do these things
under mod_perl. In fact, Apache has separate request-handling phases for
both authentication and authorization that mod_perl can handle. It is
certainly possible to use these modules with Mason.
You can also do authentication and authorization using Mason components
(as seen in Chapter 8). Authentication will usually involve some sort of
request for a login and password, after which you give the user some sort of
token (either in a cookie or a session) that indicates that he has been
authenticated. You can then check the validity of this token for each request.
If you have such a token, authorization simply consists of checking that the
user to whom the token belongs is allowed to perform a given action.
Using Apache::AuthCookie
The Apache::AuthCookie module, available from CPAN, handles both
authentication and authorization via mod_perl and can be easily hooked
into Mason. Let's just skip all the details of configuring
Apache::AuthCookie, which requires various settings in your server
config file, and show how to make the interface to Mason.

Apache::AuthCookie requires that you create a "login script" that will
be executed the first time a browser tries to access a protected area. Calling
this a script is actually somewhat misleading since it is really a page rather
than a script (though it could be a script that generates a page). Regardless,
using a Mason component for your login script merely requires that you
specify the path to your Mason component for the login script parameter.
We'll call this script AuthCookieLoginForm-login.comp,as shown in
Example 11-6.
Example 11-6. AuthCookieLoginForm-login.comp
<html>
<head>
<title>Mason Book AuthCookie Login Form</title>
</head>
<body>
<p>
Your attempt to access this document was denied
(<% $r->prev->subprocess_env("AuthCookieReason")
%>). Please enter
your username and password.
</p>
<form action="/AuthCookieLoginSubmit">

<input type="hidden" name="destination" value="<%
$r->prev->uri %>">
<table align="left">
<tr>
<td align="right"><b>Username:</b></td>
<td><input type="text" name="credential_0"
size="10" maxlength="10"></td>
</tr>
<tr>
<td align="right"><b>Password:</b></td>
<td><input type="password" name="credential_1"
size="8" maxlength="8"></td>
</tr>
<tr>
<td colspan="2" align="center"><input
type="submit" value="Continue"></td>
</tr>
</table>
</form>
</body>
</html>

