The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

SOAP::Transport::HTTP - Server/Client side HTTP support for SOAP::Lite for Perl

SYNOPSIS

  use SOAP::Transport::HTTP;            
  my $server = SOAP::Transport::HTTP::Server->new; # create new server
# set path for deployed modules (see explanation below)
  $server->dispatch_to('/Path/To/Deployed/Modules');
  $server->request(new HTTP::Request); # set request object  HTTP::Request
  $server->handle($content);           # handle request
  $server->response;                   # get response object HTTP::Response

DESCRIPTION

This class encapsulates all HTTP related logic for a SOAP server, independent of what web server it's attached to. If you want to use this class you should follow simple guideline mentioned above.

Following methods are available:

on_action()

on_action method lets you specify SOAPAction understanding. It accepts reference to subroutine that takes three parameters:

  SOAPAction, method_uri and method_name. 

SOAPAction is taken from HTTP header and method_uri and method_name are extracted from request's body. Default behavior is match SOAPAction if present and ignore it otherwise. You can specify you own, for example die if SOAPAction doesn't match with following code:

  $server->on_action(sub {
    (my $action = shift) =~ s/^("?)(.+)\1$/$2/;
    die "SOAPAction shall match 'uri#method'\n" if $action ne join '#', @_;
  });
dispatch_to()

dispatch_to lets you specify where you want to dispatch your services to. More precisely, you can specify PATH, MODULE, method or combination MODULE::method. Example:

  dispatch_to( 
    'PATH/',          # dynamic: load anything from there, any module, any method
    'MODULE',         # static: any method from this module 
    'MODULE::method', # static: specified method from this module
    'method',         # static: specified method from main:: 
  );

If you specify PATH/ name of module/classes will be taken from uri as path component and converted to Perl module name with substitution '::' for '/'. Example:

  urn:My/Examples              => My::Examples
  urn://localhost/My/Examples  => My::Examples
  http://localhost/My/Examples => My::Examples

For consistency first '/' in the path will be ignored.

According to this scheme to deploy new class you should put this class in one of the specified directories and enjoy its services. Easy, eh?

handle()

handle method will handle your request. You should provide parameters with request() method, call handle() and get it back with response() .

request()

request method gives you access to HTTP::Request object which you can provide for Server component to handle request.

response()

response method gives you access to HTTP::Response object which you can access to get results from Server component after request was handled.

SERVICE DEPLOYMENT. STATIC AND DYNAMIC

Let us scrutinize deployment process. Designing your SOAP server you can consider two kind of deployment: static and dynamic. For both static and dynamic deployment you should specify MODULE, MODULE::method, method or PATH/. Difference between static and dynamic deployment is that if module is not present it'll be loaded on demand. See "SECURITY" section for detailed description.

Example for static deployment:

  use SOAP::Transport::HTTP;
  use My::Examples;           # module is preloaded 

  SOAP::Transport::HTTP::CGI
    # deployed module should be present here or client will get 'access denied'
    -> dispatch_to('My::Examples') 
    -> handle;

Example for dynamic deployment:

  use SOAP::Transport::HTTP;
  # name is unknown, module will be loaded on demand

  SOAP::Transport::HTTP::CGI
    # deployed module should be present here or client will get 'access denied'
    -> dispatch_to('/Your/Path/To/Deployed/Modules', 'My::Examples') 
    -> handle;

For static deployment you should specify MODULE name directly. For dynamic deployment you can specify name either directly (in that case it'll be required with no restriction) or indirectly, with PATH (in that case ONLY path that'll be available will be PATH from dispatch_to() parameters). For information how to handle this situation see "SECURITY" section.

SECURITY

Due to security reasons if you choose dynamic deployment and specified PATH/, current path for perl modules (@INC) will be disabled. If you want to access other modules in your included package you have several options:

  1. Switch to static linking:

       use MODULE;
       $server->dispatch_to('MODULE');

    It can be usable also when you want to import something specific from deployed modules:

       use MODULE qw(import_list);
  2. Change use to require. Path is unavailable only during initialization part, and it's available again during execution. So, if you do require somewhere in your package it'll work.

  3. Same thing, but you can do:

       eval 'use MODULE qw(import_list)'; die if $@;
  4. Assign @INC directory in your package and then make use. Don't forget to put @INC in BEGIN{} block or it won't work:

       BEGIN { @INC = qw(my_directory); use MODULE }

    Personally I don't like this method, better options are available.

EXAMPLES

Consider following examples of SOAP servers:

CGI:
  use SOAP::Transport::HTTP;

  SOAP::Transport::HTTP::CGI
    -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 
    -> handle
  ;
daemon:
  use SOAP::Transport::HTTP;

  my $daemon = SOAP::Transport::HTTP::Daemon
    -> new (LocalAddr => 'localhost', LocalPort => 80)
    -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method') 
  ;
  print "Contact to SOAP server at ", $daemon->url, "\n";
  $daemon->handle;
mod_perl:

httpd.conf:

  <Location /soap>
    SetHandler perl-script
    PerlHandler SOAP::Apache
  </Location>

Apache.pm:

  package SOAP::Apache;

  use SOAP::Transport::HTTP;

  my $server = SOAP::Transport::HTTP::Apache
    -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method'); 

  sub handler { $server->handler(@_) }

  1;

DEPENDENCIES

 Crypt::SSLeay             for HTTPS/SSL
 SOAP::Lite, URI           for SOAP::Transport::HTTP::Server
 LWP::UserAgent, URI       for SOAP::Transport::HTTP::Client
 HTTP::Daemon              for SOAP::Transport::HTTP::Daemon
 Apache, Apache::Constants for SOAP::Transport::HTTP::Apache

SEE ALSO

 See ::CGI, ::Daemon and ::Apache for implementation details.
 See examples/soap.cgi as SOAP::Transport::HTTP::CGI example.
 See examples/soap.daemon as SOAP::Transport::HTTP::Daemon example.
 See examples/My/Apache.pm as SOAP::Transport::HTTP::Apache example.

COPYRIGHT

Copyright (C) 2000 Paul Kulchenko. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

AUTHOR

Paul Kulchenko (paulclinger@yahoo.com)