| NetServerPOP3Skeleton documentation | view source | Contained in the NetServerPOP3Skeleton distribution. |
Net::Server::POP3::Skeleton - A simple skeleton POP3 server
package MyServer;
use base 'Net::Server::POP3::Skeleton';
sub user {
my $self = shift;
my $name = shift;
unless(defined $name) {
$client->senderr("missing argument");
return;
}
$self->set('username', $name);
$self->sendok("username accepted, send password");
}
sub pass {
my $self = shift;
my $pass = shift;
my $name = $self->get('username');
# PASS not allowed before USER
return $self->unknown() unless defined $name;
return $self->senderr('invalid username or password')
unless $Auth{$name} eq $pass;
$self->state('TRANS');
$self->sendok();
}
package main;
$server = MyServer->new(
greeting => "POP3 My server ready",
);
$server->run();
This module implements a bare-bones skeleton POP3 server. It is intended as a base class. You should inherit from this class (which, in turn, inherits from Net::Server::Fork). The only POP3 command implemented by this module is the QUIT command. All others should be implemented by your code as methods.
The purpose of this module is for easily creating non-standard POP3 servers in Perl. If you want a normal POP3 server (ie, one that simply serves emails from an MBOX or MailDirs file), you would probably be better off using one of the pre-built, faster C-based servers. If, on the other hand, you want to create a specialized POP3 server that, for instance, generates the content of the messages dynamically based on data from a website, this module is what you want.
When useing this module, you can specify an import option of
nonFork. This will cause the module to inherit from
Net::Server instead of
Net::Server::Fork. See CAVEATS for more
information
Creates a new instance of the server. This method can be inherited.
The following options are recognized:
Port to listen on. Defaults to 110.
Greeting to send clients when they connect. Defaults to "POP3 Net::Server::POP3::Skeleton ready"
Message sent to clients when they sign off. Defaults to "goodbye"
Server debug flag. Set to enable logging of extra information, and printing of some debug data to STDERR. Defaults to 0.
Number of seconds to wait after receiving data from the
client before terminating the connection. This option
is especially important when using the nonfork option,
since a client who leaves the connection open prohibits
others from connecting. Set to a false value to disable
timeout. This uses alarm.
Defaults to 60.
Transmit uncaught error messages to the client. If this option is set, uncaught, fatal error messages in the command handlers are passed along to the client. Otherwise, a generic message is sent. Defaults to 0.
Note that setting this option could present a security risk, as debugging info might be given to a potential attacker. It is recommended to leave this option disabled.
Capture otherwise fatal errors in command handlers. If this option is set, fatal errors in the command handlers are caught so that they don't bring down the server. Otherwise, the program halts on an uncaught error. Defaults to 1.
Handles connections accepted by Net::Server.
Commands are read from the client and dispatched
appropriately (see "COMMANDS") until either the
client disconnects, or $obj->{hasquit} becomes
true (usually set by the QUIT command).
This method should be considered internal and should not be called (it will be called automatically by Net::Server). You probably will not ever need to overload this method.
Set or return the current server state.
To change the server's state, pass the new state to this method. States can be upper, lower, or mixed case, and the AUTHORIZATION and TRANSACTION states may be abbreviated as AUTH and TRANS, respectively.
The new (or current if no new state is passed) is returned. The returned state is always the full state name, and is always upper case.
See "STATES" for more information.
Example: $server->add_command(state => 'auth', command => 'hello');
Add a new command to the server's list of allowed commands.
You must used named-argument notation (see example above), and specify at least one state, and one command. The command will then be allowed in all of the states given.
Neither the state nor command name are case-sensitive.
Note that all the standard POP3 commands are already in the allowed commands list, so this method should only be called to add new, non-standard commands.
Send to the client a positive response including the message passed to this method. The response will be of the form:
+OK MSG
Where MSG is the message passed. The response
will automatically have the end-of-line added. Do not
add any end-of-line characters.
Send to the client a negative response including the message passed to this method. The response will be of the form:
-ERR MSG
Where MSG is the message passed. The response
will automatically have the end-of-line added. Do not
add any end-of-line characters.
Send to the client a positive response and some lines of data (eg, a message list, or message body).
For example:
chomp(@lines = <$msgfh>);
$server->senddata('message follows', @lines);
Note that end-of-line characters will be added to each line as it is sent, so they should be chomped.
Send a raw message to the client. You should almost always use one of the other send- methods mentioned above. EOL's will be added to the end of each argument.
Note that, since STDIN and STDOUT are opened to the client socket, you could just write directly to them instead.
Flags the client connection to be closed. This should be called from your QUIT handler (assuming you don't use the one provided).
Stores some arbitrary data in the server object. The data can be accessed calling the get()|"get NAME" method with NAME later.
DATA should be a single scalar value (though it can be a reference).
Returns DATA.
Retrieves data stored earlier via set()|"set NAME DATA".
The server has four possible states: CONNECT, AUTHORIZATION, TRANSACTION, UPDATE, and DISCONNECT.
When a client connects to the server, it begins in the CONNECT
state. $obj->connect()> is called, if implemented, and
the state is then switched to AUTHENTICATION. When the user is
authenticated, the state should then move into the TRANSACTION
state.
If the user enters the QUIT command, the server will move into
the UPDATE state and call $obj->commit(), which you should
implement (see "COMMANDS"). In this state, any changes (such
as deleting a message) should be committed. Note that this state
can be skipped if the client disconnects without entering the
QUIT command, in which case any changes should be rolled back
during the DISCONNECT state.
After the client has disconnected, the server moves into the
DISCONNECT state and calls $obj->disconnect(), which you
may implement. This state can be entered either from the
UPDATE state, or directly from the AUTHENTICATION or TRANSACTION
states. In this state, any changes that were not previously
committed should be rolled back.
Each line read from the user is split into two parts at the first group of whitespace encountered. The first part is the command name, and the possible second part is the parameter to the command. Any case is accepted in the command names, though the parameters to the commands may be case sensitive.
Before a command is dispatched, it is checked against a list of allowed commands. If the command is not in this list, an error is returned to the client and the command is not dispatched. This is for security reasons, as the command supplied by the user is used directly to dispatch the command.
A command is dispatched by looking for the similarly named
(but lower case) method of the object. For example, when
dispatching the USER command, the method called is
$obj->user().
The QUIT command is already implemented by this package. It
changes the state to UPDATE, calls $obj->commit(@_),
and then flags the client's connection to be closed by
calling $obj->close_client(). In almost all cases,
this implementation of QUIT should be sufficient.
nonFork import
option to use the non-forking personality of
Net::Server, this module requires perl 5.8. This
is because of a bug in the fork emulation of perl 5.6.1 that
causes perl to crash when forking is used in conjunction with
sockets. fork is emulated on
Win32 using threads, but I have not looked into it exhaustively.
L<Net::Server>, L<IO::Select>, L<Carp>
Copyright (C) 2004, Cory Johns. All rights reserved.
This module is free software; you can redistribute and/or modify it under the same terms as Perl itself.
Address bug reports and comments to: Cory Johns <johnsca@cpan.org>
| NetServerPOP3Skeleton documentation | view source | Contained in the NetServerPOP3Skeleton distribution. |