NAME
Protocol::IMAP::Client - client support for the Internet Message Access Protocol.
VERSION
version 0.004
SYNOPSIS
package Some::IMAP::Client;
use parent 'Protocol::IMAP::Client';
sub on_message { warn "new message!" }
package main;
my $client = Some::IMAP::Client->new;
$client->login('user', 'pass');
$client->idle;
DESCRIPTION
There are two standard modes of operation:
One-shot - connect to a server, process some messages, then disconnect
Long-term connection - connect to a server, update status, then sit in idle mode waiting for events
For one-shot operation against a server that doesn't keep you waiting, other more mature IMAP implementations are suggested ("see also" section).
IMPLEMENTATION DETAILS
All requests from the client have a tag, which is a 'unique' alphanumeric identifier - it is the client's responsibility to ensure these are unique for the session, see the next_id method for the implementation used here.
Server responses are always one of three possible states:
OK - Command was successful
NO - The server's having none of it
BAD - You sent something invalid
with additional 'untagged' responses in between. Any significant data is typically exchanged in the untagged sections - the final response to a command is indicated by a tagged response, once the client receives this then it knows that the server has finished with the original request.
The IMAP connection will be in one of the following states:
ConnectionEstablished - we have a valid socket but no data has been exchanged yet, waiting for ServerGreeting
ServerGreeting - server has sent an initial greeting, for some servers this may take a few seconds
NotAuthenticated - server is waiting for client response, and the client has not yet been authenticated
Authenticated - server is waiting on client but we have valid authentication credentials, for PREAUTH state this may happen immediately after ServerGreeting
Selected - mailbox has been selected and we have valid context for commands
Logout - logout request has been issued, waiting for server response
ConnectionClosed - connection has been closed on both sides
State changes are provided by the state method. Some actions run automatically on state changes, for example switching to TLS mode and exchanging login information when server greeting has been received.
IMPLEMENTING SUBCLASSES
The Protocol::IMAP classes only provide the framework for handling IMAP data. Typically you would need to subclass this to get a usable IMAP implementation.
The following methods are required:
write - called at various points to send data back across to the other side of the IMAP connection
on_user - called when the user name is required for the login stage
on_pass - called when the password is required for the login stage
start_idle_timer - switching into idle mode, hint to start the timer so that we can refresh the session as required
stop_idle_timer - switch out of idle mode due to other tasks that need to be performed
Optionally, you may consider providing these:
on_starttls - the STARTTLS stanza has been received and we need to upgrade to a TLS connection. This only applies to STARTTLS connections, which start in plaintext - a regular SSL connection will be SSL encrypted from the initial connection onwards.
To pass data back into the Protocol::IMAP layer, you will need the following methods:
is_multi_line - send a single line of data for handling
on_single_line - send a single line of data for handling
on_multi_line - send a multi-line section for handling
LIMITATIONS
There is no provision for dealing with messages that exceed memory limits - if someone has a 2Gb email then this will attempt to read it all into memory, and it's quite possible that buffers are being copied around as well.
Limited support for some of the standard protocol pieces, since I'm mainly interested in pulling all new messages then listening for any new ones.
SASL authentication is not implemented yet.
SEE ALSO
Mail::IMAPClient - up-to-date, supports IDLE, generally seems to be the best of the bunch.
Net::IMAP::Client - rewritten version of Net::IMAP::Simple, seems to be well maintained and up to date although it's not been around as long as some of the other options.
Net::IMAP::Simple - handy for simple one-off mailbox access although has a few API limitations.
Net::IMAP - over a decade since the last update, and doesn't appear to be passing on many platforms, but at least the API is reasonably full-featured.
METHODS
new
Instantiate a new object - the subclass does not need to call this if it hits configure at some point before attempting to transfer data.
on_single_line
Called when there's more data to process for a single-line (standard mode) response.
on_multi_line
Called when we have multi-line data (fixed size in characters).
handle_untagged
Process an untagged message from the server.
untagged_fetch
Fetch untagged message data. Defines the multiline callback so that we build up a buffer for the data to process.
Once we call this method, the pending message takes over input until it has managed to read the entire response.
handle_numeric
Deal with an untagged response with a numeric prefix.
on_server_greeting
Parse the server greeting, and move on to the capabilities step.
on_not_authenticated
Handle the change of state from 'connected' to 'not authenticated', which indicates that we've had a valid server greeting and it's time to get ourselves authenticated.
Depending on whether we're expecting (and supporting) the STARTTLS upgrade, we'll either switch to TLS mode at this point or just log in directly.
on_authenticated
What to do when we've been authenticated and are ready to begin the session. Suggest the subclass overrides this to make it do something useful.
check_capability
Check the server capabilities, and store them locally.
on_capability
Virtual method called when we have capabilities back from the server.
check_greeting
Verify that we had a reasonable response back from the server as an initial greeting, just in case someone pointed us at an SSH listener or something equally unexpected.
get_capabilities
Request capabilities from the server.
next_id
Returns the next ID in the sequence. Uses a standard Perl increment, tags are suggested to be 'alphanumeric' but with no particular restrictions in place so this should be good for even long-running sessions.
push_waitlist
Add a command to the waitlist.
Sometimes we need to wait for the server to catch up before sending the next entry.
TODO - maybe a mergepoint would be better for this?
send_command
Generic helper method to send a command to the server.
login
Issue the LOGIN command.
Takes two parameters:
$user - username to send
$pass - password to send
See also the authenticate command, which does the same thing but via Authen::SASL if I ever get around to writing it.
check_status
Check the mailbox status response as received from the server.
noop
Send a null command to the server, used as a keepalive or server ping.
starttls
Issue the STARTTLS command in an attempt to get the connection upgraded to something more secure.
status
Issue the STATUS command for either the given mailbox, or INBOX if none is provided.
select
Issue the SELECT command to switch to a different mailbox.
examine
Like "select", but readonly.
fetch
Issue the FETCH command to retrieve one or more messages.
delete
Issue the DELETE command, which will delete one or more messages if it can.
expunge
Issue an EXPUNGE to clear any deleted messages from storage.
done
Issue a DONE command, which did something useful and important at the time although I no longer remember what this was.
idle
Switch to IDLE mode. This will put the server into a state where it will continue to send untagged responses as any changes happen to the selected mailboxes.
is_multi_line
Returns true if we're in a multiline (fixed size read) state.
configure
Set up any callbacks that were available.
INHERITED METHODS
- Protocol::IMAP
-
Authenticated, ConnectionClosed, ConnectionEstablished, Logout, NotAuthenticated, STATE_HANDLERS, Selected, ServerGreeting, debug, in_state, state, state_id, write
- Mixin::Event::Dispatch
-
add_handler_for_event, clear_event_handlers, event_handlers, invoke_event, subscribe_to_event, unsubscribe_from_event
AUTHOR
Tom Molesworth <cpan@entitymodel.com>
LICENSE
Licensed under the same terms as Perl itself.