The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

IOMux::HTTP::Service - HTTP client handler

INHERITANCE

IOMux::HTTP::Service
  is a IOMux::HTTP
  is a IOMux::Net::TCP
  is a IOMux::Handler::Read
  is a IOMux::Handler

  IOMux::Net::TCP also extends IOMux::Handler::Write
  is a IOMux::Handler::Write
  is a IOMux::Handler

SYNOPSIS

# created by an IOMux::HTTP::Server object

sub handler($$$$)
{   my ($conn, $request, $session, $callback) = @_;
    $self->sendResponse(...);
    $callback->();
}

DESCRIPTION

The managing IOMux::HTTP::Server object creates one IOMux::HTTP::Service object per incoming connection.

METHODS

Constructors

IOMux::HTTP::Service->new(OPTIONS)
-Option     --Defined in     --Default
 add_headers  IOMux::HTTP      []
 fh           IOMux::Handler   <required>
 handler                       <required>
 name         IOMux::Handler   'tcp $host:$port'
 read_size    IOMux::Handler::Read  32768
 socket       IOMux::Net::TCP  <required>
 write_size   IOMux::Handler::Write  4096
add_headers => ARRAY
fh => FILEHANDLE
handler => CODE

This handler is called for each message.

The CODE reference gets four parameters: this connection object, the received request, a free to use session object and a callback. Do not forget to call the callback at the end of your handler.

name => STRING
read_size => INTEGER
socket => IO::Socket::INET
write_size => INTEGER
IOMux::HTTP::Service->open(MODE, WHAT, OPTIONS) See "Constructors" in IOMux::Handler
IOMux::HTTP::Service->open(MODE, WHAT, OPTIONS) See "Constructors" in IOMux::Handler

Accessors

$obj->client

Returns a HASH with some basic information about the client, not the socket itself.

$obj->fh See "Accessors" in IOMux::Handler
$obj->fh See "Accessors" in IOMux::Handler
$obj->fileno See "Accessors" in IOMux::Handler
$obj->fileno See "Accessors" in IOMux::Handler
$obj->msgsSent
$obj->mux See "Accessors" in IOMux::Handler
$obj->mux See "Accessors" in IOMux::Handler
$obj->name See "Accessors" in IOMux::Handler
$obj->name See "Accessors" in IOMux::Handler
$obj->readSize([INTEGER]) See "Accessors" in IOMux::Handler::Read
$obj->socket See "Accessors" in IOMux::Net::TCP
$obj->startTime See "Accessors" in IOMux::HTTP
$obj->usesSSL See "Accessors" in IOMux::Handler
$obj->usesSSL See "Accessors" in IOMux::Handler
$obj->writeSize([INTEGER]) See "Accessors" in IOMux::Handler::Write

User interface

Connection

$obj->close([CALLBACK]) See "Connection" in IOMux::Handler
$obj->close([CALLBACK]) See "Connection" in IOMux::Handler
$obj->shutdown((0|1|2)) See "Connection" in IOMux::Net::TCP
$obj->timeout([TIMEOUT]) See "Connection" in IOMux::Handler
$obj->timeout([TIMEOUT]) See "Connection" in IOMux::Handler

Reading

$obj->readline(CALLBACK) See "Reading" in IOMux::Handler::Read
$obj->slurp(CALLBACK) See "Reading" in IOMux::Handler::Read

Writing

$obj->print(STRING|SCALAR|LIST|ARRAY) See "Writing" in IOMux::Handler::Write
$obj->printf(FORMAT, PARAMS) See "Writing" in IOMux::Handler::Write
$obj->say(STRING|SCALAR|LIST|ARRAY) See "Writing" in IOMux::Handler::Write
$obj->write(SCALAR, [MORE]) See "Writing" in IOMux::Handler::Write

Multiplexer

Connection

$obj->mux_init(MUX, [HANDLER]) See "Connection" in IOMux::Handler
$obj->mux_init(MUX, [HANDLER]) See "Connection" in IOMux::Handler
$obj->mux_remove See "Connection" in IOMux::Handler
$obj->mux_remove See "Connection" in IOMux::Handler
$obj->mux_timeout See "Connection" in IOMux::Handler
$obj->mux_timeout See "Connection" in IOMux::Handler

Reading

$obj->mux_eof See "Multiplexer" in IOMux::Net::TCP
$obj->mux_except_flagged(FILENO) See "Reading" in IOMux::Handler
$obj->mux_except_flagged(FILENO) See "Reading" in IOMux::Handler
$obj->mux_input(BUFFER) See "Reading" in IOMux::Handler::Read
$obj->mux_read_flagged(FILENO) See "Reading" in IOMux::Handler
$obj->mux_read_flagged(FILENO) See "Reading" in IOMux::Handler

Writing

$obj->mux_outbuffer_empty See "Writing" in IOMux::Handler::Write
$obj->mux_output_waiting See "Writing" in IOMux::Handler::Write
$obj->mux_write_flagged(FILENO) See "Writing" in IOMux::Handler
$obj->mux_write_flagged(FILENO) See "Writing" in IOMux::Handler

Service

Helpers

$obj->extractSocket(HASH)
IOMux::HTTP::Service->extractSocket(HASH) See "Helpers" in IOMux::Handler
$obj->extractSocket(HASH)
IOMux::HTTP::Service->extractSocket(HASH) See "Helpers" in IOMux::Handler
$obj->fdset(STATE, READ, WRITE, ERROR) See "Helpers" in IOMux::Handler
$obj->fdset(STATE, READ, WRITE, ERROR) See "Helpers" in IOMux::Handler
$obj->show See "Helpers" in IOMux::Handler
$obj->show See "Helpers" in IOMux::Handler

HTTP protocol

$obj->closeConnection See "HTTP protocol" in IOMux::HTTP
$obj->errorResponse(REQUEST, STATUS, [TEXT])
$obj->makeResponse(REQUEST, STATUS, HEADER, [CONTENT])

The STATUS code is used in the response, preferrable use the constants from HTTP::Status.

The HEADER is an ARRAY of header line pairs to be used in the answer or an HTTP::Headers object.

You can use a scalar CONTENT, which will be used as response body. In case the CONTENT parameter is a CODE reference, that CODE will be called until undef is returned. The result of every call will become a chunk in a chunked transfer encoded response.

$obj->redirectResponse(REQUEST, STATUS, LOCATION, [CONTENT])
$obj->sendMessage(MESSAGE, CALLBACK) See "HTTP protocol" in IOMux::HTTP
$obj->sendResponse(RESPONSE, CALLBACK, [SESSION])

DETAILS

Coding examples

simple example

sub incoming_first
{   my ($client, $req) = @_;

    # create a response based on $req, an HTTP::Request object
    my $resp1 = HTTP::Response->new(...);
    $client->sendResponse($resp1, \&step2);
}

# step2 is called when the delivery of $status fails
sub step2
{   my ($client, $resp1, $status, $req2) = @_;

    # Although we only plan to reply a single request, that
    # sending can go wrong
    if($status!=HTTP_OK)
    {   # Some extra error logging, maybe?
        # $resp1 is now not the $resp1 you intended to send, but
        # the error which has been sent (if any)
        return;
    }

    # Of course, the connection can be reused for a next request.
    # Restart thread with this message.
    incoming_first $client, $req2;
}

# cheapest implementation for step2
sub step2
{   my ($client, $resp1, $status, $req2) = @_;
    incoming_first $client, $req2  # not for mee
        if $status==HTTP_OK;
}

more complex example

sub incoming_first
{   my ($client, $req) = @_;

    # Create a response based on $req, an HTTP::Request object
    my $resp1   = HTTP::Response->new(...);

    # Lets have a session object
    my $session = { sent => time() };

    $client->sendResponse($resp1, \&step2, $session);
}

sub step2
{   my ($client, $resp1, $status, $req2, $session) = @_;
    $status!=HTTP_OK or return;

    print "ping time: ", time - $session->{sent}, "\n";

    my $resp2 = $client->makeResponse(...);

    # do not accept more request (there may be queued, which
    # will get removed.
    $client->closeConnection;

    $client->sendReponse($resp2, \&step3, $session);
}

# Although the connection got closed, step3 will still be
# called in case of an error.
sub step3
{   my ($client, $resp2, $status, undef, $session) = @_;
    # $status!=HTTP_OK
}

The server is a daemon: a process which always runs. There are many deamon implementations available for Perl. See the examples/ directory for an example which uses Any::Daemon. The examples below should seamlessly fit in the run_multiplexer() function shown there.

The initiation looks much like that of a client. use HTTP::Status 'HTTP_OK';

# You may also choose IOMux::Select or other
# multiplex instances (to be developed)
use IOMux::Poll;
my $mux    = IOMux::Poll->new;

my $server = "localhost:8081";
my $client = IOMux::HTTP::Server->new
  ( LocalAddr => $server
  , handler   => \&incoming_first
  );
$mux->add($client);

# You may initiate multiple clients and start many different steps
# until you start the loop.
$mux->loop;

# The loop is left when all connections have closed
exit 0;

# Now here comes the implementation as shown in the examples below.

SEE ALSO

This module is part of IOMux-HTTP distribution version 0.11, built on January 27, 2011. Website: http://perl.overmeer.net/ All modules in this suite: "Any::Daemon", "IOMux", and "IOMux::HTTP".

Please post questions or ideas to perl@overmeer.net

LICENSE

Copyrights 2011 by Mark Overmeer. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html