http://qs321.pair.com?node_id=652292


in reply to SOAP::Transport::HTTP::Daemon and XML

Request

Copy the real service's WSDL description, then serve it from http://fakeserver/service?WDSL. Then you can use SOAP::WSDL to make the request. Because it gets the same WSDL from both services, it will send the same request to both.

Response

validTypes and statistics should probably be returned as array refs, rather than hash refs.

The main problem seems to be that you're not returning the node name info with your data, so SOAP::Lite is using a gensym value.

I can't remember exactly the incantation (I mainly deal with .NET services), but try:

  return bless { info => $serverinfo }, 'getServerInfoResponse';

-David

Replies are listed 'Best First'.
Re^2: SOAP::Transport::HTTP::Daemon and XML
by rppowell (Novice) on Nov 22, 2007 at 03:43 UTC
    I have the WSDL description, but only in file form. Is it necessary that WSDL file be web served? I don't see how to use it as local file, is it possible?
      I have the WSDL description, but only in file form.
      Are you sure?

      Web-services commonly serve their WSDL from the proxy URL with '?WSDL' appended.

      The SOAP::Transport::HTTP::Server subclasses don't make it easy to serve your WSDL from the same service, so what I do is the following:

      1. use the HTTP::Request->parse constructor from HTTP::Request to build a request from the raw incoming request, then
      2. (depending on the $request->uri) I either:
        • build a response containing WSDL, or
        • pass $request directly to SOAP::Transport::HTTP::Server like this:

          my $soap = SOAP::Transport::HTTP::Server -> new(%args) -> dispatch_to(@classes); $soap->request($request); $soap->handle; my $response = $soap->response;

      Is it necessary that WSDL file be web served? I don't see how to use it as local file, is it possible?
      Sure, do something like this:

      my $soap = SOAP::WSDL->new(); $soap->wsdl('file:/path/to/file.wsdl'); $soap->proxy('http://server/service.cgi'); $soap->wsdlinit(caching => 1);
      Loading from the file saves some time on script startup, using caching saves a lot of work on each request.

      Update: Fixed my URLs.

      -David

        Here is my solution of the task. It isn't very graceful. But it works:
        package My::Net::SOAP::Transport::HTTP::Daemon; use SOAP::Transport::HTTP; use My::Net::SOAP::Transport::HTTP::Server; @SOAP::Transport::HTTP::Daemon::ISA = qw( My::Net::SOAP::Transport::HTTP::Server ); @My::Net::SOAP::Transport::HTTP::Daemon::ISA = qw( SOAP::Transport::HTTP::Daemon ); sub setWsdl($$) { my $self = shift; my $wsdlUri = shift; my $wsdlFile = shift; $/ = undef; open FILE, $wsdlFile or die "Cannot open '$wsdlFile' ($!)"; $My::Net::SOAP::Transport::HTTP::Server::WsdlFileContent = <FILE>; close FILE; $My::Net::SOAP::Transport::HTTP::Server::WsdlURI = $wsdlUri; return 1; } 1; package My::Net::SOAP::Transport::HTTP::Server; use strict; use SOAP::Transport::HTTP; our @ISA = qw( SOAP::Transport::HTTP::Server ); our $WsdlFileContent; our $WsdlURI; sub handle { my $class = shift; my $result; eval { my $self = $class->new; if ($self->request->method eq 'GET') { if( $self->request->uri eq $WsdlURI ) { my $response = $WsdlFileContent; print "FOO:\n"; $result = $self->make_response(undef,$response) || 1; } else { print STDERR "Got GET request with wrong URI '".$self- +>request->uri."'!='$WsdlURI', ignoring"; } } }; if( $@ ) { print STDERR "Runtime error ($@)"; return undef; } return $result if $result; return $class->handle(); } 1; # now use derived Daemon class regular way use My::Net::SOAP::Transport::HTTP::Daemon; my $daemon = My::Net::SOAP::Transport::HTTP::Daemon->new( LocalAddr => 'myhostname', LocalPort => 9999, ) or die "Cannot create My::Net::SOAP::Transport::HTTP::Daemon"; $daemon->setWsdl("/$service?WSDL",'/path/to/file.wsdl') or die "Cannot set WSDL ($@)"; my $dispatcher = $daemon->dispatch_with({ 'urn:/'.$service => 'My::WS: +:'.$service }); my $object = $dispatcher->objects_by_reference("My::WS::".$service); $object->dispatch_to('/my/lib/My/WS', $service); $object->handle;