m-rau has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I am working with SOAP now. Great! But I am pretty confused about how to get information about the client which connected?

use lib "Message"; use Test; my $daemon = SOAP::Transport::HTTP::Daemon -> new ( LocalAddr => 'localhost', LocalPort => 8080 ); $daemon -> dispatch_to( 'Message/', 'Test' );

How to find out about the client's ip address in my Message/Test.pm? I know how to do this with sockets. But what is the SOAP object/ method to use? Please help!

Test.pm provides i.e. a constructor enqueue:

sub enqueue { my $class = shift; my $self = { }; bless ($self, $class); # # collect identify information about the client, # i.e. IP ==> ??? # # then start working # return $self; }

Thanks in advace.

Replies are listed 'Best First'.
Re: SOAP client IP
by jhourcle (Prior) on Mar 10, 2005 at 03:44 UTC

    I've never used the stand-alone daemon, but if you're running as a CGI, you just check %ENV as if it were any other CGI. You might try something similar to the following. For the server side:

    #!/usr/bin/perl -- use SOAP::Transport::HTTP; SOAP::Transport::HTTP::CGI -> dispatch_to('test') -> handle(); package test; sub function { return \%ENV; }
    and for the client:
    #!/usr/bin/perl -- use SOAP::Lite; use Data::Dumper; my $soap = SOAP::Lite->new( proxy => 'http://127.0.0.1/cgi-bin/soap.pl', uri => 'urn:/test' ); my $som = $soap->function(); print Dumper $som->result();
Re: SOAP client IP
by m-rau (Scribe) on Mar 10, 2005 at 13:44 UTC
    The suggested solution does not work. Apache is not there to set ENV. But I found the solution: It is necessary to write my own SOAP::Transport::HTTP::Daemon as follows:
    package Message::Daemon; use SOAP::Transport::HTTP; use Socket; use Carp (); use vars qw($AUTOLOAD @ISA); @ISA = qw(SOAP::Transport::HTTP::Server); sub DESTROY { SOAP::Trace::objects('()') } sub new { require HTTP::Daemon; my $self = shift; unless (ref $self) { my $class = ref($self) || $self; my(@params, @methods); while (@_) { $class->can($_[0]) ? push(@methods, shift() => shift) + : push(@params, shift) } $self = $class->SUPER::new; $self->{_daemon} = HTTP::Daemon->new(@params) or Carp::croak "Can' +t create daemon: $!"; $self->myuri(URI->new($self->url)->canonical->as_string); while (@methods) { my($method, $params) = splice(@methods,0,2); $self->$method(ref $params eq 'ARRAY' ? @$params : $params) } SOAP::Trace::objects('()'); } return $self; } sub AUTOLOAD { my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2); return if $method eq 'DESTROY'; no strict 'refs'; *$AUTOLOAD = sub { shift->{_daemon}->$method(@_) }; goto &$AUTOLOAD; } sub handle { my $self = shift->new; while (my ($c, $peer) = $self->accept) { my $sockaddr_template = 'Sna4x8'; my ($af,$client_port,$client_ip) = unpack($sockaddr_template,$peer +); my @inetaddr = unpack('C4',$client_ip); warn "$af connection from ".join ('.', @inetaddr).":$client_port\n +"; while (my $r = $c->get_request) { $self->request($r); $self->SUPER::handle; $c->send_response($self->response) } # replaced ->close, thanks to Sean Meisner <Sean.Meisner@VerizonWi +reless.com> # shutdown() doesn't work on AIX. close() is used in this case. Th +anks to Jos Clijmans <jos.clijmans@recyfin.be> UNIVERSAL::isa($c, 'shutdown') ? $c->shutdown(2) : $c->close(); undef $c; } }
    Now I have access to the client's IP and port as can be seen in warn "$af connection from ".join ('.', @inetaddr).":$client_port\n";