1# ====================================================================== 2# 3# Copyright (C) 2000-2004 Paul Kulchenko (paulclinger@yahoo.com) 4# SOAP::Lite is free software; you can redistribute it 5# and/or modify it under the same terms as Perl itself. 6# 7# $Id: HTTP.pm,v 1.1 2004/10/16 17:45:17 byrnereese Exp $ 8# 9# ====================================================================== 10 11__END__ 12 13=head1 NAME 14 15SOAP::Transport::HTTP - Server/Client side HTTP support for SOAP::Lite 16 17=head1 SYNOPSIS 18 19=over 4 20 21=item Client 22 23 use SOAP::Lite 24 uri => 'http://my.own.site.com/My/Examples', 25 proxy => 'http://localhost/', 26 # proxy => 'http://localhost/cgi-bin/soap.cgi', # local CGI server 27 # proxy => 'http://localhost/', # local daemon server 28 # proxy => 'http://localhost/soap', # local mod_perl server 29 # proxy => 'https://localhost/soap', # local mod_perl SECURE server 30 # proxy => 'http://login:password@localhost/cgi-bin/soap.cgi', # local CGI server with authentication 31 ; 32 33 print getStateName(1); 34 35=item CGI server 36 37 use SOAP::Transport::HTTP; 38 39 SOAP::Transport::HTTP::CGI 40 # specify path to My/Examples.pm here 41 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 42 -> handle 43 ; 44 45=item Daemon server 46 47 use SOAP::Transport::HTTP; 48 49 # change LocalPort to 81 if you want to test it with soapmark.pl 50 51 my $daemon = SOAP::Transport::HTTP::Daemon 52 -> new (LocalAddr => 'localhost', LocalPort => 80) 53 # specify list of objects-by-reference here 54 -> objects_by_reference(qw(My::PersistentIterator My::SessionIterator My::Chat)) 55 # specify path to My/Examples.pm here 56 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 57 ; 58 print "Contact to SOAP server at ", $daemon->url, "\n"; 59 $daemon->handle; 60 61=item Apache mod_perl server 62 63See F<examples/server/Apache.pm> and L</"EXAMPLES"> section for more information. 64 65=item mod_soap server (.htaccess, directory-based access) 66 67 SetHandler perl-script 68 PerlHandler Apache::SOAP 69 PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, Module::Name, Module::method" 70 PerlSetVar options "compress_threshold => 10000" 71 72See L<Apache::SOAP> for more information. 73 74=back 75 76=head1 DESCRIPTION 77 78This class encapsulates all HTTP related logic for a SOAP server, 79independent of what web server it's attached to. 80If you want to use this class you should follow simple guideline 81mentioned above. 82 83Following methods are available: 84 85=over 4 86 87=item on_action() 88 89on_action method lets you specify SOAPAction understanding. It accepts 90reference to subroutine that takes three parameters: 91 92 SOAPAction, method_uri and method_name. 93 94C<SOAPAction> is taken from HTTP header and method_uri and method_name are 95extracted from request's body. Default behavior is match C<SOAPAction> if 96present and ignore it otherwise. You can specify you own, for example 97die if C<SOAPAction> doesn't match with following code: 98 99 $server->on_action(sub { 100 (my $action = shift) =~ s/^("?)(.+)\1$/$2/; 101 die "SOAPAction shall match 'uri#method'\n" if $action ne join '#', @_; 102 }); 103 104=item dispatch_to() 105 106dispatch_to lets you specify where you want to dispatch your services 107to. More precisely, you can specify C<PATH>, C<MODULE>, C<method> or 108combination C<MODULE::method>. Example: 109 110 dispatch_to( 111 'PATH/', # dynamic: load anything from there, any module, any method 112 'MODULE', # static: any method from this module 113 'MODULE::method', # static: specified method from this module 114 'method', # static: specified method from main:: 115 ); 116 117If you specify C<PATH/> name of module/classes will be taken from uri as 118path component and converted to Perl module name with substitution 119'::' for '/'. Example: 120 121 urn:My/Examples => My::Examples 122 urn://localhost/My/Examples => My::Examples 123 http://localhost/My/Examples => My::Examples 124 125For consistency first '/' in the path will be ignored. 126 127According to this scheme to deploy new class you should put this 128class in one of the specified directories and enjoy its services. 129Easy, eh? 130 131=item handle() 132 133handle method will handle your request. You should provide parameters 134with request() method, call handle() and get it back with response() . 135 136=item request() 137 138request method gives you access to HTTP::Request object which you 139can provide for Server component to handle request. 140 141=item response() 142 143response method gives you access to HTTP::Response object which 144you can access to get results from Server component after request was 145handled. 146 147=back 148 149=head2 PROXY SETTINGS 150 151You can use any proxy setting you use with LWP::UserAgent modules: 152 153 SOAP::Lite->proxy('http://endpoint.server/', 154 proxy => ['http' => 'http://my.proxy.server']); 155 156or 157 158 $soap->transport->proxy('http' => 'http://my.proxy.server'); 159 160should specify proxy server for you. And if you use C<HTTP_proxy_user> 161and C<HTTP_proxy_pass> for proxy authorization SOAP::Lite should know 162how to handle it properly. 163 164=head2 COOKIE-BASED AUTHENTICATION 165 166 use HTTP::Cookies; 167 168 my $cookies = HTTP::Cookies->new(ignore_discard => 1); 169 # you may also add 'file' if you want to keep them between sessions 170 171 my $soap = SOAP::Lite->proxy('http://localhost/'); 172 $soap->transport->cookie_jar($cookies); 173 174Cookies will be taken from response and provided for request. You may 175always add another cookie (or extract what you need after response) 176with HTTP::Cookies interface. 177 178You may also do it in one line: 179 180 $soap->proxy('http://localhost/', 181 cookie_jar => HTTP::Cookies->new(ignore_discard => 1)); 182 183=head2 SSL CERTIFICATE AUTHENTICATION 184 185To get certificate authentication working you need to specify three 186environment variables: C<HTTPS_CERT_FILE>, C<HTTPS_KEY_FILE>, and 187(optionally) C<HTTPS_CERT_PASS>: 188 189 $ENV{HTTPS_CERT_FILE} = 'client-cert.pem'; 190 $ENV{HTTPS_KEY_FILE} = 'client-key.pem'; 191 192Crypt::SSLeay (which is used for https support) will take care about 193everything else. Other options (like CA peer verification) can be specified 194in a similar way. See Crypt::SSLeay documentation for more details. 195 196Those who would like to use encrypted keys may check 197http://groups.yahoo.com/group/soaplite/message/729 for details. 198 199=head2 COMPRESSION 200 201SOAP::Lite provides you with the option for enabling compression on the 202wire (for HTTP transport only). Both server and client should support 203this capability, but this should be absolutely transparent to your 204application. The Server will respond with an encoded message only if 205the client can accept it (indicated by client sending an Accept-Encoding 206header with 'deflate' or '*' values) and client has fallback logic, 207so if server doesn't understand specified encoding 208(Content-Encoding: deflate) and returns proper error code 209(415 NOT ACCEPTABLE) client will repeat the same request without encoding 210and will store this server in a per-session cache, so all other requests 211will go there without encoding. 212 213Having options on client and server side that let you specify threshold 214for compression you can safely enable this feature on both client and 215server side. 216 217=over 4 218 219=item Client 220 221 print SOAP::Lite 222 -> uri('http://localhost/My/Parameters') 223 -> proxy('http://localhost/', options => {compress_threshold => 10000}) 224 -> echo(1 x 10000) 225 -> result 226 ; 227 228=item Server 229 230 my $server = SOAP::Transport::HTTP::CGI 231 -> dispatch_to('My::Parameters') 232 -> options({compress_threshold => 10000}) 233 -> handle; 234 235=back 236 237Compression will be enabled on the client side 238B<if> the threshold is specified 239B<and> the size of current message is bigger than the threshold 240B<and> the module Compress::Zlib is available. 241 242The Client will send the header 'Accept-Encoding' with value 'deflate' 243B<if> the threshold is specified 244B<and> the module Compress::Zlib is available. 245 246Server will accept the compressed message if the module Compress::Zlib 247is available, and will respond with the compressed message 248B<only if> the threshold is specified 249B<and> the size of the current message is bigger than the threshold 250B<and> the module Compress::Zlib is available 251B<and> the header 'Accept-Encoding' is presented in the request. 252 253=head1 EXAMPLES 254 255Consider following examples of SOAP servers: 256 257=over 4 258 259=item CGI: 260 261 use SOAP::Transport::HTTP; 262 263 SOAP::Transport::HTTP::CGI 264 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 265 -> handle 266 ; 267 268=item daemon: 269 270 use SOAP::Transport::HTTP; 271 272 my $daemon = SOAP::Transport::HTTP::Daemon 273 -> new (LocalAddr => 'localhost', LocalPort => 80) 274 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 275 ; 276 print "Contact to SOAP server at ", $daemon->url, "\n"; 277 $daemon->handle; 278 279=item mod_perl: 280 281httpd.conf: 282 283 <Location /soap> 284 SetHandler perl-script 285 PerlHandler SOAP::Apache 286 </Location> 287 288Apache.pm: 289 290 package SOAP::Apache; 291 292 use SOAP::Transport::HTTP; 293 294 my $server = SOAP::Transport::HTTP::Apache 295 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method'); 296 297 sub handler { $server->handler(@_) } 298 299 1; 300 301=item Apache::Registry: 302 303httpd.conf: 304 305 Alias /mod_perl/ "/Apache/mod_perl/" 306 <Location /mod_perl> 307 SetHandler perl-script 308 PerlHandler Apache::Registry 309 PerlSendHeader On 310 Options +ExecCGI 311 </Location> 312 313soap.mod_cgi (put it in /Apache/mod_perl/ directory mentioned above) 314 315 use SOAP::Transport::HTTP; 316 317 SOAP::Transport::HTTP::CGI 318 -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 319 -> handle 320 ; 321 322=back 323 324WARNING: dynamic deployment with Apache::Registry will fail, because 325module will be loaded dynamically only for the first time. After that 326it is already in the memory, that will bypass dynamic deployment and 327produces error about denied access. Specify both PATH/ and MODULE name 328in dispatch_to() and module will be loaded dynamically and then will work 329as under static deployment. See examples/server/soap.mod_cgi for example. 330 331=head1 TROUBLESHOOTING 332 333=over 4 334 335=item Dynamic libraries are not found 336 337If you see in webserver's log file something like this: 338 339Can't load '/usr/local/lib/perl5/site_perl/.../XML/Parser/Expat/Expat.so' 340for module XML::Parser::Expat: dynamic linker: /usr/local/bin/perl: 341 libexpat.so.0 is NEEDED, but object does not exist at 342/usr/local/lib/perl5/.../DynaLoader.pm line 200. 343 344and you are using Apache web server, try to put into your httpd.conf 345 346 <IfModule mod_env.c> 347 PassEnv LD_LIBRARY_PATH 348 </IfModule> 349 350=item Apache is crashing with segfaults (it may looks like "500 unexpected EOF before status line seen" on client side) 351 352If using SOAP::Lite (or XML::Parser::Expat) in combination with mod_perl 353causes random segmentation faults in httpd processes try to configure 354Apache with: 355 356 RULE_EXPAT=no 357 358-- OR (for Apache 1.3.20 and later) -- 359 360 ./configure --disable-rule=EXPAT 361 362See http://archive.covalent.net/modperl/2000/04/0185.xml for more 363details and lot of thanks to Robert Barta <rho@bigpond.net.au> for 364explaining this weird behavior. 365 366If it doesn't help, you may also try -Uusemymalloc 367(or something like that) to get perl to use the system's own malloc. 368Thanks to Tim Bunce <Tim.Bunce@pobox.com>. 369 370=item CGI scripts are not running under Microsoft Internet Information Server (IIS) 371 372CGI scripts may not work under IIS unless scripts are .pl, not .cgi. 373 374=back 375 376=head1 DEPENDENCIES 377 378 Crypt::SSLeay for HTTPS/SSL 379 SOAP::Lite, URI for SOAP::Transport::HTTP::Server 380 LWP::UserAgent, URI for SOAP::Transport::HTTP::Client 381 HTTP::Daemon for SOAP::Transport::HTTP::Daemon 382 Apache, Apache::Constants for SOAP::Transport::HTTP::Apache 383 384=head1 SEE ALSO 385 386 See ::CGI, ::Daemon and ::Apache for implementation details. 387 See examples/server/soap.cgi as SOAP::Transport::HTTP::CGI example. 388 See examples/server/soap.daemon as SOAP::Transport::HTTP::Daemon example. 389 See examples/My/Apache.pm as SOAP::Transport::HTTP::Apache example. 390 391=head1 COPYRIGHT 392 393Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved. 394 395This library is free software; you can redistribute it and/or modify 396it under the same terms as Perl itself. 397 398=head1 AUTHOR 399 400Paul Kulchenko (paulclinger@yahoo.com) 401 402=cut 403