SOAP-Lite
view release on metacpan or search on metacpan
lib/SOAP/Transport/HTTP.pm view on Meta::CPAN
# here doesn't work either, because LWP overwrites it with
# content-length it calculates (which is wrong) AND uses length()
# during syswrite/sysread, so we are in a bad shape anyway.
#
# what to do? we calculate proper content-length (using
# bytelength() function from SOAP::Utils) and then drop utf8 mark
# from string (doing pack with 'C0A*' modifier) if length and
# bytelength are not the same
my $bytelength = SOAP::Utils::bytelength($envelope);
if ($] < 5.008) {
$envelope = pack( 'C0A*', $envelope );
}
else {
require Encode;
$envelope = Encode::encode($encoding, $envelope);
$bytelength = SOAP::Utils::bytelength($envelope);
}
# if !$SOAP::Constants::DO_NOT_USE_LWP_LENGTH_HACK
# && length($envelope) != $bytelength;
# compress after encoding
# doing it before breaks the compressed content (#74577)
$envelope = Compress::Zlib::memGzip($envelope) if $compressed;
$http_request->content($envelope);
$http_request->protocol('HTTP/1.1');
$http_request->proxy_authorization_basic( $ENV{'HTTP_proxy_user'},
$ENV{'HTTP_proxy_pass'} )
if ( $ENV{'HTTP_proxy_user'} && $ENV{'HTTP_proxy_pass'} );
# by Murray Nesbitt
if ( $method eq 'M-POST' ) {
my $prefix = sprintf '%04d', int( rand(1000) );
$http_request->header(
Man => qq!"$SOAP::Constants::NS_ENV"; ns=$prefix! );
$http_request->header( "$prefix-SOAPAction" => $action )
if defined $action;
}
else {
$http_request->header( SOAPAction => $action )
if defined $action;
}
# $http_request->header(Expect => '100-Continue');
# allow compress if present and let server know we could handle it
$http_request->header( 'Accept-Encoding' =>
[$SOAP::Transport::HTTP::Client::COMPRESS] )
if $self->options->{is_compress};
$http_request->content_encoding(
$SOAP::Transport::HTTP::Client::COMPRESS)
if $compressed;
if ( !$http_request->content_type ) {
$http_request->content_type(
join '; ',
$SOAP::Constants::DEFAULT_HTTP_CONTENT_TYPE,
!$SOAP::Constants::DO_NOT_USE_CHARSET && $encoding
? 'charset=' . lc($encoding)
: () );
}
elsif ( !$SOAP::Constants::DO_NOT_USE_CHARSET && $encoding ) {
my $tmpType = $http_request->headers->header('Content-type');
# $http_request->content_type($tmpType.'; charset=' . lc($encoding));
my $addition = '; charset=' . lc($encoding);
$http_request->content_type( $tmpType . $addition )
if ( $tmpType !~ /$addition/ );
}
$http_request->content_length($bytelength) unless $compressed;
SOAP::Trace::transport($http_request);
&{$self->{debug_logger}}($http_request->as_string);
$self->SUPER::env_proxy if $ENV{'HTTP_proxy'};
# send and receive the stuff.
# TODO maybe eval this? what happens on connection close?
$self->http_response( $self->SUPER::request($http_request) );
SOAP::Trace::transport( $self->http_response );
&{$self->{debug_logger}}($self->http_response->as_string);
# 100 OK, continue to read?
if ( (
$self->http_response->code == 510
|| $self->http_response->code == 501
)
&& $method ne 'M-POST'
) {
$mpost{$endpoint} = 1;
}
elsif ( $self->http_response->code == 415 && $compressed ) {
# 415 Unsupported Media Type
$nocompress{$endpoint} = 1;
$envelope = Compress::Zlib::memGunzip($envelope);
$http_request->headers->remove_header('Content-Encoding');
redo COMPRESS; # try again without compression
}
else {
last;
}
}
}
$redirect{$endpoint} = $self->http_response->request->url
if $self->http_response->previous
&& $self->http_response->previous->is_redirect;
$self->code( $self->http_response->code );
$self->message( $self->http_response->message );
$self->is_success( $self->http_response->is_success );
$self->status( $self->http_response->status_line );
# Pull out any cookies from the response headers
$self->{'_cookie_jar'}->extract_cookies( $self->http_response )
if $self->{'_cookie_jar'};
my $content =
( $self->http_response->content_encoding || '' ) =~
/\b$SOAP::Transport::HTTP::Client::COMPRESS\b/o
&& $self->options->{is_compress}
? Compress::Zlib::memGunzip( $self->http_response->content )
: ( $self->http_response->content_encoding || '' ) =~ /\S/ ? die
"Can't understand returned Content-Encoding (@{[$self->http_response->content_encoding]})\n"
: $self->http_response->content;
lib/SOAP/Transport/HTTP.pm view on Meta::CPAN
my $response = $self->SUPER::handle(
$self->request->content_type =~ m!^multipart/!
? join( "\n", $self->request->headers_as_string, $content )
: $content
) or return;
&{$self->{debug_logger}}($response);
$self->make_response( $SOAP::Constants::HTTP_ON_SUCCESS_CODE, $response );
}
sub make_fault {
my $self = shift;
$self->make_response(
$SOAP::Constants::HTTP_ON_FAULT_CODE => $self->SUPER::make_fault(@_)
);
return;
}
sub make_response {
my ( $self, $code, $response ) = @_;
my $encoding = $1
if $response =~ /^<\?xml(?: version="1.0"| encoding="([^\"]+)")+\?>/;
$response =~ s!(\?>)!$1<?xml-stylesheet type="text/css"?>!
if $self->request->content_type eq 'multipart/form-data';
$self->options->{is_compress} ||=
exists $self->options->{compress_threshold}
&& eval { require Compress::Zlib };
my $compressed = $self->options->{is_compress}
&& grep( /\b($COMPRESS|\*)\b/,
$self->request->header('Accept-Encoding') )
&& ( $self->options->{compress_threshold} || 0 ) <
SOAP::Utils::bytelength $response;
if ($] > 5.007 && $encoding) {
require Encode;
$response = Encode::encode( $encoding, $response );
}
$response = Compress::Zlib::compress($response) if $compressed;
# this next line does not look like a good test to see if something is multipart
# perhaps a /content-type:.*multipart\//gi is a better regex?
my ($is_multipart) =
( $response =~ /^content-type:.* boundary="([^\"]*)"/im );
$self->response(
HTTP::Response->new(
$code => undef,
HTTP::Headers->new(
'SOAPServer' => $self->product_tokens,
$compressed ? ( 'Content-Encoding' => $COMPRESS ) : (),
'Content-Type' => join( '; ',
'text/xml',
!$SOAP::Constants::DO_NOT_USE_CHARSET
&& $encoding ? 'charset=' . lc($encoding) : () ),
'Content-Length' => SOAP::Utils::bytelength $response
),
$response,
) );
$self->response->headers->header( 'Content-Type' =>
'Multipart/Related; type="text/xml"; start="<main_envelope>"; boundary="'
. $is_multipart
. '"' )
if $is_multipart;
}
# ->VERSION leaks a scalar every call - no idea why.
sub product_tokens {
join '/', 'SOAP::Lite', 'Perl', $SOAP::Transport::HTTP::VERSION;
}
# ======================================================================
package SOAP::Transport::HTTP::CGI;
use vars qw(@ISA);
@ISA = qw(SOAP::Transport::HTTP::Server);
sub DESTROY { SOAP::Trace::objects('()') }
sub new {
my $self = shift;
return $self if ref $self;
my $class = ref($self) || $self;
$self = $class->SUPER::new(@_);
SOAP::Trace::objects('()');
return $self;
}
sub make_response {
my $self = shift;
$self->SUPER::make_response(@_);
}
sub handle {
my $self = shift->new;
my $length = $ENV{'CONTENT_LENGTH'} || 0;
# if the HTTP_TRANSFER_ENCODING env is defined, set $chunked if it's chunked*
# else to false
my $chunked = (defined $ENV{'HTTP_TRANSFER_ENCODING'}
&& $ENV{'HTTP_TRANSFER_ENCODING'} =~ /^chunked.*$/) || 0;
my $content = q{};
if ($chunked) {
my $buffer;
binmode(STDIN);
while ( read( STDIN, my $buffer, 1024 ) ) {
$content .= $buffer;
( run in 0.551 second using v1.01-cache-2.11-cpan-496ff517765 )