stas 2004/07/04 01:37:49 Modified: src/docs/2.0 TODO Log: updates Revision Changes Path 1.9 +0 -242 modperl-docs/src/docs/2.0/TODO Index: TODO =================================================================== RCS file: /home/cvs/modperl-docs/src/docs/2.0/TODO,v retrieving revision 1.8 retrieving revision 1.9 diff -u -u -r1.8 -r1.9 --- TODO 10 May 2004 05:17:58 -0000 1.8 +++ TODO 4 Jul 2004 08:37:49 -0000 1.9 @@ -7,16 +7,6 @@ mp2doc - replacement for perldoc for modules that get installed into Apache2/ ---- - -*** Areas that would be nice to document first *** - -- Automatic API docs generator from .h files - Owner: Lyle Brooks? - -- Directive handlers (custom config handlers) - Owner: stas - *** General items *** --- @@ -88,238 +78,6 @@ --- - -Need to integrate the following example, removed from overview.pod, in -protocols.pod: - - -=head2 Apache::CommandServer - -Our first protocol handler example took advange of Apache's server -framework, but did not tap into any other modules. The next example -is based on the example in the "TCP Servers with IO::Socket" section -of the I<perlipc> manpage. Of course, we don't need C<IO::Socket> -since Apache takes care of those details for us. The rest of that -example can still be used to illustrate implementing a simple text -protocol. In this case, one where a command is sent by the client to -be executed on the server side, with results sent back to the client. - -The C<Apache::CommandServer> handler will support four commands: -C<motd>, C<date>, C<who> and C<quit>. These are probably not commands -which can be exploited, but should we add such commands, we'll want to -limit access based on ip address/hostname, authentication and -authorization. Protocol handlers need to take care of these tasks -themselves, since we bypass the HTTP protocol handler. - -As with all C<PerlProcessConnectionHandlers>, we are passed an -C<Apache::Connection> object as the first argument. Again, we will be -directly accessing the client socket via the I<client_socket> method. -The I<login> subroutine is called to check if access by this client -should be allowed. This routine makes up for what we lost with the -core HTTP protocol handler bypassed. First we call the -C<Apache::RequestRec> I<new> method, which returns a I<request_rec> -object, just like that which is passed at request time to -C<Perl*Handlers> and returned by the subrequest API methods, -I<lookup_uri> and I<lookup_file>. However, this "fake request" does -not run handlers for any of the phases, it simply returns an object -which we can use to do that ourselves. The C<location_merge> method -is passed the "location" for this request, it will look up the -C<E<lt>LocationE<gt>> section that matches the given name and merge it -with the default server configuration. For example, should we only -wish to allow access to this server from certain locations: - - <Location Apache::CommandServer> - deny from all - allow from 10.* - </Location> - -The I<location_merge> method only looks up and merges the -configuration, we still need to apply it. This is done in I<for> -loop, iterating over three methods: I<run_access_checker>, -I<run_check_user_id> and I<run_auth_checker>. These methods will call -directly into the Apache functions that invoke module handlers for -these phases and will return an integer status code, such as C<OK>, -C<DECLINED> or C<FORBIDDEN>. If I<run_access_check> returns something -other than C<OK> or C<DECLINED>, that status will be propagated up to -the handler routine and then back up to Apache. Otherwise, the access -check passed and the loop will break unless I<some_auth_required> -returns true. This would be false given the previous configuration -example, but would be true in the presense of a I<require> directive, -such as: - - <Location Apache::CommandServer> - deny from all - allow from 10.* - require user dougm - </Location> - -Given this configuration, I<some_auth_required> will return true. The -I<user> method is then called, which will return false if we have not -yet authenticated. A I<prompt> utility is called to read the username -and password, which are then injected into the I<headers_in> table -using the I<set_basic_credentials> method. The I<Authenticate> field -in this table is set to a base64 encoded value of the -username:password pair, exactly the same format a browser would send -for I<Basic authentication>. Next time through the loop -I<run_check_user_id> is called, which will in turn invoke any -authentication handlers, such as I<mod_auth>. When I<mod_auth> calls -the I<ap_get_basic_auth_pw()> API function (as all Basic auth modules -do), it will get back the username and password we injected. If we -fail authentication a B<401> status code is returned which we -propagate up. Otherwise, authorization handlers are run via -I<run_auth_checker>. Authorization handlers normally need the I<user> -field of the I<request_rec> for its checks and that field was filled -in when I<mod_auth> called I<ap_get_basic_auth_pw()>. - -Provided login is a success, a welcome message is printed and main -request loop entered. Inside the loop the I<getline> function returns -just one line of data, with newline characters stripped. If the -string sent by the client is in our command table, the command is then -invoked, otherwise a usage message is sent. If the command does not -return a true value, we break out of the loop. Let's give it a try -with this configuration: - - Listen 8085 - <VirtualHost _default_:8085> - PerlProcessConnectionHandler Apache::CommandServer - - <Location Apache::CommandServer> - allow from 127.0.0.1 - require user dougm - satisfy any - AuthUserFile /tmp/basic-auth - </Location> - </VirtualHost> - - % telnet localhost 8085 - Trying 127.0.0.1... - Connected to localhost (127.0.0.1). - Escape character is '^]'. - Login: dougm - Password: foo - Welcome to Apache::CommandServer - Available commands: motd date who quit - motd - Have a lot of fun... - date - Mon Mar 12 19:20:10 PST 2001 - who - dougm tty1 Mar 12 00:49 - dougm pts/0 Mar 12 11:23 - dougm pts/1 Mar 12 14:08 - dougm pts/2 Mar 12 17:09 - quit - Connection closed by foreign host. - -=head2 Apache::CommandServer Source - - package Apache::CommandServer; - - use strict; - use Apache::Connection (); - use APR::Socket (); - use Apache::HookRun (); - - use Apache::Const -compile => qw(OK DECLINED); - - my @cmds = qw(motd date who quit); - my %commands = map { $_, \&{$_} } @cmds; - - sub handler { - my Apache::Connection $c = shift; - my APR::Socket $socket = $c->client_socket; - - if ((my $rc = login($c)) != Apache::OK) { - $socket->send("Access Denied\n"); - return $rc; - } - - $socket->send("Welcome to " . __PACKAGE__ . - "\nAvailable commands: @cmds\n"); - - for (;;) { - my $cmd; - next unless $cmd = getline($socket); - - if (my $sub = $commands{$cmd}) { - last unless $sub->($socket) == APR::SUCCESS; - } - else { - $socket->send("Commands: @cmds\n"); - } - } - - return Apache::OK; - } - - sub login { - my $c = shift; - - my $r = Apache::RequestRec->new($c); - $r->location_merge(__PACKAGE__); - - for my $method (qw(run_access_checker run_check_user_id run_auth_checker)) { - my $rc = $r->$method(); - - if ($rc != Apache::OK and $rc != Apache::DECLINED) { - return $rc; - } - - last unless $r->some_auth_required; - - unless ($r->user) { - my $socket = $c->client_socket; - my $username = prompt($socket, "Login"); - my $password = prompt($socket, "Password"); - - $r->set_basic_credentials($username, $password); - } - } - - return Apache::OK; - } - - sub getline { - my $socket = shift; - my $line; - $socket->recv($line, 1024); - return unless $line; - $line =~ s/[\r\n]*$//; - return $line; - } - - sub prompt { - my($socket, $msg) = @_; - $socket->send("$msg: "); - getline($socket); - } - - sub motd { - my $socket = shift; - open my $fh, '/etc/motd' or return; - local $/; - my $status = $socket->send(scalar <$fh>); - close $fh; - return $status; - } - - sub date { - my $socket = shift; - $socket->send(scalar(localtime) . "\n"); - } - - sub who { - my $socket = shift; - $socket->send(scalar `who`); - } - - sub quit {1} - - 1; - __END__ - - - ---
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]