![]() |
Practical mod_perl / HTML Book / | ![]() |
||
![]() |
||||
![]() |
![]() |
|||
![]() |
![]() |
|||
![]() |
||||
|
|
||||
![]() |
![]() |
|||
![]() |
25.2.2.2.1. Socket-based protocol module |
![]() |
||
![]() |
||||
![]() |
![]() |
![]() |
||
![]() |
||||
To demonstrate the workings of a protocol module, we'll take a look at the Book::Eliza module, which sends the data read from the client as input to Chatbot::Eliza, which in turn implements a mock Rogerian psychotherapist and forwards the response from the psychotherapist back to the client. In this module we will use the implementation that works directly with the connection socket and therefore bypasses any connection filters.
A protocol handler is configured using the PerlProcessConnectionHandler directive, and we will use the Listen and <VirtualHost> directives to bind to the nonstandard port 8084:
Listen 8084
<VirtualHost _default_:8084>
PerlModule Book::Eliza
PerlProcessConnectionHandler Book::Eliza
</VirtualHost>
Book::Eliza is then enabled when starting Apache:
panic% httpd
And we give it a whirl:
panic% telnet localhost 8084 Trying 127.0.0.1... Connected to localhost (127.0.0.1). Escape character is '^]'. Hello Eliza How do you do. Please state your problem. How are you? Oh, I? Why do I have core dumped? You say Why do you have core dumped? I feel like writing some tests today, you? I'm not sure I understand you fully. Good bye, Eliza Does talking about this bother you? Connection closed by foreign host.
The code is shown in Example 25-3.
package Book::Eliza;
use strict;
use warnings FATAL => 'all';
use Apache::Connection ( );
use APR::Socket ( );
require Chatbot::Eliza;
use Apache::Const -compile => 'OK';
use constant BUFF_LEN => 1024;
my $eliza = new Chatbot::Eliza;
sub handler {
my $c = shift;
my $socket = $c->client_socket;
my $buff;
my $last = 0;
while (1) {
my($rlen, $wlen);
$rlen = BUFF_LEN;
$socket->recv($buff, $rlen);
last if $rlen <= 0;
# \r is sent instead of \n if the client is talking over telnet
$buff =~ s/[\r\n]*$//;
$last++ if $buff =~ /good bye/i;
$buff = $eliza->transform( $buff ) . "\n\n";
$socket->send($buff, length $buff);
last if $last;
}
Apache::OK;
}
1;
The example handler starts with the standard package declaration and, of course, use strict;. As with all Perl*Handlers, the subroutine name defaults to handler. However, in the case of a protocol handler, the first argument is not a request_rec, but a conn_rec blessed into the Apache::Connection class. We have direct access to the client socket via Apache::Connection's client_socket( ) method, which returns an object blessed into the APR::Socket class.
Inside the read/send loop, the handler attempts to read BUFF_LEN bytes from the client socket into the $buff buffer. The $rlen parameter will be set to the number of bytes actually read. The APR::Socket::recv( ) method returns an APR status value, but we need only check the read length to break out of the loop if it is less than or equal to 0 bytes. The handler also breaks the loop after processing an input including the "good bye" string.
Otherwise, if the handler receives some data, it sends this data to the $eliza object (which represents the psychotherapist), whose returned text is then sent back to the client with the APR::Socket::send( ) method. When the read/print loop is finished the handler returns Apache::OK, telling Apache to terminate the connection. As mentioned earlier, since this handler is working directly with the connection socket, no filters can be applied.
 
Continue to:
mod_perl, modperl, Apache, perl, cgi, html, mod_perl, e-commerce, scalability, free, open source, OSS, apache, squid, high availability, modperl, linux, unix, Web, www, mod_perl, webserver, admin, apache, book, webmaster, tools, modperl, guide, docs, documentation, help, mod_perl, perl, information, apache, script, errata, eric cholet, perl, apache, mod-perl, stas bekman, mod_perl, cool, perl, Apache, performance, speed, choice
![]() |
Other projects to check out: meta-religion.com is for those interested in Religious, Spiritual and Esoteric Phenomena. i-want-a-better.com is a community of people discussing what they would like to be improved in their lives and things they use and interact with. You may also want to find a healer in your area or read articles on variety of topics.