Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

SOAP::Lite dispatch routine

by gildir (Pilgrim)
on Jan 03, 2002 at 13:51 UTC ( #135951=perlquestion: print w/replies, xml ) Need Help??

gildir has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

I have recently came up to SOAP::Lite and made som experiment with it, but for a real use i will nett some kind of custom dispatch routine for SOAP::Lite.

What I'm trying to do:
I have a bunch of persistent objects stored in LDAP or RDBMs or wherever. I have a good perl home-brewn module for object persistence. Now I want to 'publish' this interface to other applications using SOAP.
My semantics works like this:

my $object = $factory->instantiate('My::User', id => 'uid=semancik,ou= +people,o=bgs,c=sk'); print $object->realName; # read attribute $object->realName('Radovan Semancik'); # Set attribute
I have tried it this way (mod_perl style):
# server my $server = SOAP::Transport::HTTP::Apache->new; $server->dispatch_with({ '' => $factory, }); sub handler { $server->handler(@_) }; # client my $soap = SOAP::Lite ->uri('') ->proxy(''); my $object = $soap->instantiate('My::User','whateverId')->result;
But alas, $object is just a simple blessed hash. This won't work, because server side objects has open database handles and several non-travsferable attributes. The only way to do this is to make a proxy object and instantiate server side object on every request.

But SOAP is supposed to be Object Access protocol, not procedural RPC ..... so I want to use it the right way.

Well, I have decided to try it another way around. I want to access objects with URI like this: '' and have it dispatched the way I like it.
How can I do this in SOAP::Lite? How can I substitute my very own dispatch routine to SOAP server?

Or am I going wrong way from the very beginning?
Any help/suggestion appreciated.

Replies are listed 'Best First'.
Re (tilly) 1: SOAP::Lite dispatch routine
by tilly (Archbishop) on Jan 03, 2002 at 22:03 UTC
    Sorry this isn't an answer, but I would strongly recommend that anyone considering SOAP should understand the issues raised at SOAP::Lite and Security (Phrack #58).

    As for what SOAP is or isn't, I would suggest thinking of it as insecure procedural RPC hidden behind some OO terminology.

      As for what SOAP is or isn't, I would suggest thinking of it as insecure procedural RPC hidden behind some OO terminology.

      I'm not sure that we should blaim SOAP protocol itself. Obviously SOAP::Lite has a security bug but it doesn't make SOAP protocol insecure itself. It's all about writting properly SOAP servers and clients.

      Ilya Martynov (

        SOAP has no security model.

        According to Microsoft, ones of its primary purposes is to enable people to bypass existing security checks.

        Now you say that there is no security problem here, we just need to get the servers and clients right. I say that anyone who thinks there is a snowball's chance in Hell of this really happening doesn't understand the realities of software development. If security is something people have to get right again and again, then mistakes will happen. Repeatedly. And people will turn out to (quite predictably) wind up making similar mistakes, making life quite convenient for crackers.

        Yes. There is a specific gaping security hole in SOAP::Lite. That mistake is directly in the module, not the protocol. But that mistake should be regarded as a symptom of something that will happen.

        Dominus draws a nice analogy to unsafe programming practices being like smoking in bed. Everything is fine as long as you don't fall asleep and drop the cigarette. And that is the problem with SOAP. Its complete regard for security is an unsafe programming practice. Everything will be fine as long as you make no mistakes. This is true, but it is still a piece of stupidity.

        And continuing the analogy, using SOAP to tunnel to the Internet through a firewall for applications is like sprinkling gasoline on your bed before smoking. Again, everything will be fine if you do nothing wrong. Isn't that comforting?

        I would like to avoid having software developed by developers who fail to understand this being used inside my network, thankyouverymuch...

(jeffa) Re: SOAP::Lite dispatch routine
by jeffa (Bishop) on Jan 03, 2002 at 22:58 UTC
    I was going to point you to the security link, but tilly beat me to it. When you say that your $object is just a simple blessed hash, well, isn't that what all Perl objects are, simple blessed thingies? You aren't trying to pass the database handle back inside your SOAP object, are you?

    Here an example that uses mod_soap, if you are not using mod_soap then i recommend you take a look at it. First, my Apache http.conf directive to make mod_soap autodispatch:

    <Location /mod_soap> SetHandler perl-script PerlHandler Apache::SOAP PerlSetVar dispatch_to "/usr/local/apache/lib/soap" </Location>
    Next, the dispatch object code -
    package Factory; use strict; use DBI; my $dbh = DBI->connect( qw(DBI:vendor:database:host user pass), { RaiseError => 1} ); sub instantiate { my ($self,$package,$id) = @_; my $sth = $dbh->selectall_arrayref(' select title,artist,year from songs where id = ? ',undef,$id)->[0]; my $obj = eval { $package->new($id,@$sth) }; return $@ ? undef : $obj; } package My::User; use strict; sub new { my ($class,$id,$title,$artist,$year) = @_; my $self = { id => $id, title => $title, artist => $artist, year => $year, }; return bless $self,$class; } # this will be discussed later ... sub foo { 'foo' } 1;
    And finally, the client:
    use strict; use SOAP::Lite; use Data::Dumper; my $soap = SOAP::Lite ->uri("") ->proxy(""); my $object = $soap->instantiate('My::User','5')->result; print Dumper $object;
    When run, the following is printing:
    $VAR1 = bless( { 'artist' => 'Van Halen', 'title' => 'You Really Got Me', 'id' => '5', 'year' => '1978' }, 'My::User' );
    The idea is to just return data - not code. SOAP is insecure enough already. As a matter of fact, if you try to return a DBI handle, you get back a nice fat undefined value.

    SOAP really helped me to understand more about Perl OO, especially the fact that an object DOES NOT carry its methods with it - instead, the interpreter knows which package the object is blessed and is able to find the method in question because you use'ed or require'ed the package.

    To see what i mean, call the foo method from package My::User inside your SOAP client ...

    my $object = $soap->instantiate('My::User','5')->result; print $object->foo(); # yields: Can't locate object method "foo" via package "My::User" at ./instantia line 23.
    Pass data - not code, that's what COM and DCOM do (pass code and/or data). Hope this helps, and feel free to ask more. ;)


    (the triplet paradiddle)
      Yes and No,

      Yes, Perl objects are just a blessed references, but they may have inner objects which in turn may have other inner objects .. which may have xsub references in them or even open file descriptors. And that is a kind of my case. Every persistent object ($object) has in it a reference to its storage object. And that storage object includes an open (and bound) handle to LDAP storage.

      And No, your example will not work in any elegant way if you want to modify an object. Look at an example.

      use strict; use SOAP::Lite; use Data::Dumper; my $soap = SOAP::Lite ->uri("") ->proxy(""); my $object = $soap->instantiate('My::User','5')->result; print Dumper $object; #$VAR1 = bless( { # 'artist' => 'Van Halen', # 'title' => 'You Really Got Me', # 'id' => '5', # 'year' => '1999' hmm, aparently wrong # }, 'My::User' ); $object->year(1978); # modify the year # aaaagrh, it does not work!
      I have fetched $object by use of instantiate() method as you suggested. But as the object is just a plain hash, it has no connection with original object on server. Modification of this object will no modify server-side object. Too bad. No persistence.

      What I'm trying to achieve is to get a 'proxy object' or a 'remote reference' on the SOAP client side. Something that I call $object->year(2002), it will call year() method on the original server-side object. This is more like CORBA IORs work.

      Passing object by reference, not by value.

        IIRC, SOAP doesn't act like CORBA by design, but you can fake it if you like. Like jeffa said, you should be able to pass the modified object back with a command to save it. The SOAP process acting as a proxy could have remembered the object when you requested it and when you pass it back for modification, save that particular object. It's not as elegant or clean as CORBA, but it's not as hairy or expensive either.

        M-x auto-bs-mode

        I was waiting for you to take the bait ;).

        You can't do that with SOAP. You will have to pass the object back to the server if you want to modify it.

        Think about it. Looks like you need a COM/DCOM/CORBA solution, because SOAP don't do that. It's Simple Object Access PROTOCOL, not PERSISTANCE. It IS procedural RPC, just made easier.

        Have you looked into SPOPS yet?


        (the triplet paradiddle)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://135951]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2020-11-29 05:04 GMT
Find Nodes?
    Voting Booth?

    No recent polls found