NAME
UniEvent::HTTP::Server - efficient asynchronous http server
SYNOPSIS
my $server = UE::HTTP::Server->new({
locations => [
{host => '*', port => 80},
{host => '*', port => 443, ssl_ctx => $ssl_ctx, reuse_port => 0},
{path => '/var/run/mysock.sock'},
]
}, $loop);
$server->request_callback(sub {
my $request = shift;
if ($request->uri->path eq "/hello") {
$request->respond({
code => 200,
headers => {...}
body => "Hi",
});
} else {
$request->respond({code => 404});
}
});
$server->run;
$loop->run;
DESCRIPTION
UniEvent::HTTP::Server
respresents an asynchronous multiplexing http server working in single process/thread. To utilize several cpu cores, several server objects should be created in different processes/threads. Out-of-the-box multi-process/thread solution is implemented in UniEvent::HTTP::Manager.
Server supports keep-alive connections, compression, http pipelining, request/response body streaming.
Server supports for listening host:port, unix socket, windows named pipe or custom socket. Multiple listening locations can be defined.
KEEP-ALIVE
If an incoming request is a keep-alive request and given response is also keep-alive (by default), then server will keep the connection opened waiting for more requests. Connection will stay opened until either client closes it or max_keepalive_requests
is reached or user sends non-keep-alive response.
COMPRESSION
Compression / uncompression is handled by Protocol::HTTP transparently. See its docs for info how to compress a response.
HTTP PIPELINING
When a client sends several requests in a single connection at once, server will call callbacks as requests arrive from network, not waiting for the responses for previous requests in the pipeline. User is not required to give responses in order - server will hold such responses and send them in order by itself. The API in case of pipelining is not affected - everything works as if there were no pipelining. If user gives a non-keep-alive response (Connection: close) for a request in the pipeline and this request is not the last one, then server will cancel all further requests in the pipeline and close the connection. In this case callbacks for such canceled requests will be called with error UniEvent::HTTP::Error::pipeline_canceled
.
METHODS
new([$loop = default])
Creates server object which will run in $loop
UniEvent::Loop.
new(\%config, [$loop = default])
Creates and configures server, same as:
my $server = UniEvent::HTTP::Server->new($loop);
$server->configure($config);
configure(\%config)
Configures server. Server can be configured multiple times even if it is running (done gracefully, without service interruption).
config
is a hashref with the following params:
- locations [required]
-
Arrayref of server locations to listen. Each location is a hashref with the following params
- host
-
Host name or human-readable ip address of interface to listen. "*" will bind to all available interfaces
- port
-
Port to listen. Can be zero, in which case server will bind to a random free port. You can then get the port server was bound to via
$server->sockaddr->port; # from the first location $server->listeners->[$n]->sockaddr->port; # from the $n-th location
- path
-
Path to unix socket or name for named pipe (on windows) to listen. If defined, ignores
host
,port
,reuse_port
,domain
,sock
,tcp_nodelay
. - reuse_port [true]
-
If set to true, will use
REUSE_PORT
feature when binding. This is the simplest (and efficient) way to create several server objects on the same port. This option is ignored on systems where it's not supported (for example, windows). - tcp_nodelay [false]
-
Sets the corresponding socket option if location is a tcp location. Option is ignored otherwise.
- backlog [4096]
-
Defines the maximum length to which the queue of pending connections for this location may grow
- domain [AF_INET]
-
Used when resolving
host
domain name into IP address. Can beUniEvent::AF_INET
orUniEvent::AF_INET6
. - ssl_ctx
-
Enables SSL for this location. Must be an SSL context object which you can create via Net::SSLeay.
- sock
-
Allows to pass previously created socket. Socket must be bound to an address, but MUST NOT listen (
listen()
must not be called). Server will calllisten()
by itself. Useful if you want to useprefork-socket
scheme (i.e. create socket in master process, then fork and create server object and listen the same socket in multiple child processes). This socket can be of family AF_INET, AF_INET6 or AF_UNIX (except for windows).sock
andhost
,port
,path
,reuse_port
,domain
are mutually exclusive.
- idle_timeout [300]
-
Max idle time in seconds for a http connection before server force-closes it. Can be fractional.
Connection is idle: 1) After physical tcp connection established till first byte of request received (including possible SSL connection time). 2) After last part of the http response sent till first byte of the next request received (for keep-alive connections). 3) After last part of the last http response sent till the moment when the connection is properly shut down.
- max_headers_size [16384]
-
Max http request headers size. If server receives request with bigger headers, callbacks will be called with error
Protocol::HTTP::Error::headers_too_large
. - max_body_size [unlimited]
-
Max http request body size. If server receives request with bigger body, callbacks will be called with error
Protocol::HTTP::Error::body_too_large
. - tcp_nodelay [false]
-
If set to true, will set
tcp_nodelay
feature for all tcp locations. - max_keepalive_requests [unlimited]
-
Max number of requests per keep-alive connection. If limit is exceeded, server closes keep-alive connection (sending last response with
Connection: close
header).
loop()
Returns UniEvent::Loop object which server runs in.
run()
Starts server. This function will not block execution, you must call run()
on appropriate unievent loop afterwards. Thus it is possible to run more than one server in one process.
running()
Returns true if server is running.
listeners()
Returns listeners for all configured locations as arrayref of UniEvent::Tcp objects. If server is not running, returns empty arrayref.
sockaddr()
Returns sockaddr of the first listener (if any) as Net::SockAddr object. Effect is similar to:
$server->listeners->[0]->sockaddr;
stop()
Immediately stops the server. Will close all connections and cancel all active requests. Callbacks will be called with UniEvent::HTTP::Error::server_stopping
error.
graceful_stop()
Stops the server gracefully. Stops listening immediately and will close connections after its active requests are finished. After that, normally, if you don't have other active event objects in UniEvent (or they are weak), event loop execution will bail out of run()
function.
If you want to force bailing out of loop execution when server get stopped, use stop_callback
/stop_event
.
stopping()
Returns true if server is stopping now.
stop_listening()
Temporarily suspend listening for new requests. Will continue to process current active requests and receiving new requests in keep-alive connections.
start_listening()
Resumes listening for new requests after stop_listening()
.
run_callback($sub)
run_event()
Callbacks set via these methods will be invoked right after server is started.
Callback doesn't receive anything.
See "EVENT CALLBACKS" in UniEvent for differences between _callback
and _event
versions of methods.
request_callback($sub)
request_event()
The simplest way of making http server.
Callbacks set via these methods will be invoked when new request fully received (including body). Body will be located in memory.
Callback signature:
my $request = shift;
Where $request
is a UniEvent::HTTP::ServerRequest object.
If you don't want to have body in-memory and want precise control over how body is received, use route_callback
/route_event
.
See "EVENT CALLBACKS" in UniEvent for differences between _callback
and _event
versions of methods.
route_callback($sub)
route_event()
Callbacks set via these methods will be invoked on new request when at least its headers are fully received.
Callback signature:
my $request = shift;
Where $request
is a UniEvent::HTTP::ServerRequest object.
These callbacks allows to add callbacks to the request object before it is received and control the process. This event is designed for URI dispatchers. URI dispatcher is a some logic that decides how this request will be processed depending on request URI, headers, etc... A part of this process is to decide how request (its body) will be received: part by part, as data arrives from network, or when data is fully arrived.
If we decide to process request with all body available (the simplest way), we can use receive_callback
/receive_event
in request object
$request->receive_callback(sub {
my $request = shift;
# process request and send response
});
Other way is to process data as it arrives from network via enable_partial()
and partial_callback
/partial_event
in request object
$request->enable_partial;
$request->partial_callback(sub {
my ($request, $error) = @_;
# process partial data
if ($request->is_done) {
# process request and send response
}
});
See UniEvent::HTTP::ServerRequest for more detailed description.
error_callback($sub)
error_event()
Callbacks set via these methods will be invoked when error occured during receiving a request. But not in all cases. Only for cases when only simple callbacks are set for the request (which are called only when request is fully received, i.e. not a partial receival mode). That's because user doesn't know anything about such request yet (no callbacks has been called for this request so far), so that we don't need to do anything special in this case. Usually this event is used for logging purposes only.
In contrast, in partial receival mode, partial callbacks might have been called for this request already and user might have started some work, so that the error in this case is directly delivered into request's partial callback and this event is not called.
NOTE: errors occured during sending response are always delivered into request's drop_callback
/drop_event
.
stop_callback($sub)
stop_event()
Callbacks set via these methods will be invoked when server has been fully stopped. In case of stop()
method, callbacks will be called immediately. In case of graceful_stop()
method, callbacks will be called when last active request is processed and its response is sent.