POE-Component-Client-HTTP
view release on metacpan or search on metacpan
lib/POE/Component/Client/HTTP/Request.pm view on Meta::CPAN
# Add a host header if one isn't included. Must do this before
# we reset the $host for the proxy!
unless (
defined $http_request->header('Host') and
length $http_request->header('Host')
) {
my $error = _set_host_header($http_request);
croak "Can't set Host header: $error" if $error;
}
if (defined $params{Proxy}) {
# This request qualifies for proxying. Replace the host and port
# with the proxy's host and port. This comes after the Host:
# header is set, so it doesn't break the request object.
($host, $port) = @{$params{Proxy}->[rand @{$params{Proxy}}]};
$using_proxy = 1;
}
else {
$using_proxy = 0;
}
# Build the request.
my $self = [
$request_id, # REQ_ID
$postback, # REQ_POSTBACK
undef, # REQ_CONNECTION
$http_request, # REQ_HTTP_REQUEST
RS_CONNECT, # REQ_STATE
undef, # REQ_RESPONSE
'', # REQ_BUFFER
undef, # unused
0, # REQ_OCTETS_GOT
undef, # REQ_TIMER
$progress, # REQ_PROG_POSTBACK
$using_proxy, # REQ_USING_PROXY
$host, # REQ_HOST
$port, # REQ_PORT
undef, # REQ_HISTORY
time(), # REQ_START_TIME
$factory, # REQ_FACTORY
undef, # REQ_CONN_ID
undef, # REQ_PEERNAME
];
return bless $self, $class;
}
sub return_response {
my ($self) = @_;
DEBUG and warn "in return_response ", sprintf ("0x%02X", $self->[REQ_STATE]);
return if ($self->[REQ_STATE] & RS_POSTED);
my $response = $self->[REQ_RESPONSE];
# If we have a cookie jar, have it frob our headers. LWP rocks!
$self->[REQ_FACTORY]->frob_cookies ($response);
# If we're done, send back the HTTP::Response object, which
# is filled with content if we aren't streaming, or empty
# if we are. that there's no ARG1 lets the client know we're done
# with the content in the latter case
if ($self->[REQ_STATE] & RS_DONE) {
DEBUG and warn "done; returning $response for ", $self->[REQ_ID];
$self->[REQ_POSTBACK]->($self->[REQ_RESPONSE]);
$self->[REQ_STATE] |= RS_POSTED;
#warn "state is now ", $self->[REQ_STATE];
}
elsif ($self->[REQ_STATE] & RS_IN_CONTENT) {
# If we are streaming, send the chunk back to the client session.
# Otherwise add the new octets to the response's content.
# This should only add up to content-length octets total!
if ($self->[REQ_FACTORY]->is_streaming) {
DEBUG and warn "returning partial $response";
$self->[REQ_POSTBACK]->($self->[REQ_RESPONSE], $self->[REQ_BUFFER]);
}
else {
DEBUG and warn "adding to $response";
$self->[REQ_RESPONSE]->add_content($self->[REQ_BUFFER]);
}
}
$self->[REQ_BUFFER] = '';
}
sub add_eof {
my ($self) = @_;
return if ($self->[REQ_STATE] & RS_POSTED);
unless (defined $self->[REQ_RESPONSE]) {
# XXX I don't know if this is actually used
$self->error(400, "incomplete response a " . $self->[REQ_ID]);
return;
}
# RFC 2616: "If a message is received with both a Transfer-Encoding
# header field and a Content-Length header field, the latter MUST be
# ignored."
#
# Google returns a Content-Length header with its HEAD request,
# generating "incomplete response" errors. Added a special case to
# ignore content for HEAD requests. This may thwart keep-alive,
# however.
if (
$self->[REQ_HTTP_REQUEST]->method() ne "HEAD" and
defined $self->[REQ_RESPONSE]->content_length and
not defined $self->[REQ_RESPONSE]->header("Transfer-Encoding") and
$self->[REQ_OCTETS_GOT] < $self->[REQ_RESPONSE]->content_length
) {
DEBUG and warn(
"got " . $self->[REQ_OCTETS_GOT] . " of " .
$self->[REQ_RESPONSE]->content_length
);
$self->error(
400,
"incomplete response b " . $self->[REQ_ID] . ". Wanted " .
$self->[REQ_RESPONSE]->content_length() . " octets. Got " .
$self->[REQ_OCTETS_GOT] . "."
);
}
else {
$self->[REQ_STATE] |= RS_DONE;
$self->return_response();
}
}
sub add_content {
my ($self, $data) = @_;
( run in 0.507 second using v1.01-cache-2.11-cpan-39bf76dae61 )