POE-Component-Server-Bayeux
view release on metacpan or search on metacpan
lib/POE/Component/Server/Bayeux.pm view on Meta::CPAN
$request->complete();
}
$kernel->alarm_remove_all();
$kernel->alias_set( $heap->{manager} );
$kernel->call( $heap->{http_aliases}{httpd}, 'shutdown' );
$kernel->call( $heap->{http_aliases}{tcp}, 'shutdown' );
}
sub http_server_generic {
my ($kernel, $heap, $request, $response) = @_[KERNEL, HEAP, ARG0, ARG1];
my $uri = URI->new($request->uri);
my $path = $heap->{args}{DocumentRoot} . '/' . $uri->path;
# Attempt to find a directory index
if (-d $path) {
$path .= '/' unless $path =~ m{/$};
foreach my $index_name (@{ $heap->{args}{DirectoryIndex} }) {
next unless -f $path . $index_name;
$path .= $index_name;
last;
}
}
if (-d $path) {
$response->code(RC_OK);
$response->content("Directory listing denied");
}
elsif (-f $path) {
$response->code(RC_OK);
open my $in, '<', $path;
if (! $in) {
$response->content("Unable to open '$path': $!");
return RC_OK;
}
# Find a file type
my $type;
foreach my $possible_type (keys %file_types) {
next unless grep { $path =~ $_ } @{ $file_types{$possible_type} };
$type = $possible_type;
last;
}
$type ||= 'text/plain';
$response->content_type($type);
if (my $whence = $heap->{args}{TypeExpires}{$type}) {
$response->expires( time() + $whence );
}
my $content;
{
local $/ = undef;
$content = <$in>;
}
close $in;
$response->content($content);
my $ip = $request->header('X-Forwarded-For') || $request->{connection}{remote_ip};
$heap->{logger}->info(sprintf 'Serving %s %s %s', $ip, $uri->path, $response->content_type);
}
else {
$response->code(RC_NOT_FOUND);
$response->content("Path '".$uri->path."' not found");
}
if ($heap->{args}{PostHandle}) {
$heap->{args}{PostHandle}($request, $response);
}
# Ensure no KeepAlive
$request->header(Connection => 'close');
return RC_OK;
}
## Remote clients, long-polling ###
sub handle_cometd {
my ($kernel, $heap, $request, $response) = @_[KERNEL, HEAP, ARG0, ARG1];
# Deny based upon ClientMaxConnections restrictions
my $ip = $request->header('X-Forwarded-For') || $request->{connection}{remote_ip};
if (! $ip) {
$ip = '0.0.0.0';
$heap->{logger}->error("No IP found for cometd request");
}
$heap->{requests_by_ip}{$ip} ||= {};
my @request_ids = keys %{ $heap->{requests_by_ip}{$ip} };
if (int @request_ids > $heap->{args}{ClientMaxConnections}) {
$heap->{logger}->info("Denying $ip; too many connections (".int(@request_ids).")");
$response->code(RC_SERVICE_UNAVAILABLE);
$response->header( 'Content-Type' => "text/json; charset=utf-8" );
$response->content( '{ "error": "Too many connections from your IP", "successful": false }' );
return RC_OK;
}
else {
#$heap->{logger}->info("IP $ip has " . int(@request_ids) . " connections");
}
# Proceed with processing
#$heap->{logger}->debug("Handling new cometd request");
#$heap->{logger}->debug($request->as_string);
my $bayeux_request = POE::Component::Server::Bayeux::Request->new(
request => $request,
response => $response,
server_heap => $heap,
ip => $ip,
);
$bayeux_request->handle();
if ($bayeux_request->is_complete) {
$heap->{logger}->debug("Immediate remote response:", $bayeux_request->json_response);
return RC_OK;
}
else {
$heap->{requests}{ $bayeux_request->id } = $bayeux_request;
$heap->{requests_by_ip}{$ip}{ $bayeux_request->id } = $bayeux_request;
return RC_WAIT;
}
}
sub delay_request {
my ($kernel, $heap, $request_id, $delay) = @_[KERNEL, HEAP, ARG0, ARG1];
$heap->{logger}->debug("Delaying $delay to process request $request_id");
$kernel->delay_add('complete_request', $delay, $request_id);
}
sub complete_request {
my ($kernel, $heap, $request_id) = @_[KERNEL, HEAP, ARG0];
return unless defined $heap->{requests}{$request_id};
my $request = delete $heap->{requests}{$request_id};
my $ip = $request->ip;
if ($heap->{requests_by_ip}{$ip}) {
delete $heap->{requests_by_ip}{$ip}{$request_id};
( run in 1.748 second using v1.01-cache-2.11-cpan-39bf76dae61 )