Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
7.6 KiB

  1. # ======================================================================
  2. #
  3. # Copyright (C) 2000-2001 Paul Kulchenko ([email protected])
  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: SOAP::Transport::JABBER.pm,v 0.51 2001/07/18 15:15:14 $
  8. #
  9. # ======================================================================
  10. package SOAP::Transport::JABBER;
  11. use strict;
  12. use vars qw($VERSION);
  13. $VERSION = '0.51';
  14. use Net::Jabber 1.0021;
  15. use URI::Escape;
  16. use URI;
  17. use SOAP::Lite;
  18. my $NAMESPACE = "http://namespaces.soaplite.com/transport/jabber";
  19. # fix problem with printData in 1.0021
  20. { local $^W; *Net::Jabber::printData = sub {'nothing'} if Net::Jabber->VERSION == 1.0021 }
  21. # fix problem with Unicode encoding in EscapeXML. Jabber ALWAYS convert latin to utf8
  22. { local $^W; *Net::Jabber::EscapeXML = \&SOAP::Utils::encode_data; }
  23. # ======================================================================
  24. package URI::jabber; # ok, lets do 'jabber://' scheme
  25. require URI::_server; require URI::_userpass;
  26. @URI::jabber::ISA=qw(URI::_server URI::_userpass);
  27. # jabber://soaplite_client:[email protected]:5222/[email protected]/Home
  28. # ^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
  29. # ======================================================================
  30. package SOAP::Transport::JABBER::Query;
  31. sub new {
  32. my $proto = shift;
  33. bless {} => ref($proto) || $proto;
  34. }
  35. sub SetPayload {
  36. shift; Net::Jabber::SetXMLData("single",shift->{QUERY},"payload",shift,{});
  37. }
  38. sub GetPayload {
  39. shift; Net::Jabber::GetXMLData("value",shift->{QUERY},"payload","");
  40. }
  41. # ======================================================================
  42. package SOAP::Transport::JABBER::Client;
  43. use vars qw(@ISA);
  44. @ISA = qw(SOAP::Client Net::Jabber::Client);
  45. sub DESTROY { SOAP::Trace::objects('()') }
  46. sub new {
  47. my $self = shift;
  48. unless (ref $self) {
  49. my $class = ref($self) || $self;
  50. my(@params, @methods);
  51. while (@_) { $class->can($_[0]) ? push(@methods, shift() => shift) : push(@params, shift) }
  52. $self = $class->SUPER::new(@params);
  53. while (@methods) { my($method, $params) = splice(@methods,0,2);
  54. $self->$method(ref $params eq 'ARRAY' ? @$params : $params)
  55. }
  56. SOAP::Trace::objects('()');
  57. }
  58. return $self;
  59. }
  60. sub endpoint {
  61. my $self = shift;
  62. return $self->SUPER::endpoint unless @_;
  63. my $endpoint = shift;
  64. # nothing to do if new endpoint is the same as current one
  65. return $self if $self->SUPER::endpoint && $self->SUPER::endpoint eq $endpoint;
  66. my $uri = URI->new($endpoint);
  67. my($undef, $to, $resource) = split m!/!, $uri->path, 3;
  68. $self->Connect(
  69. hostname => $uri->host,
  70. port => $uri->port,
  71. ) or Carp::croak "Can't connect to @{[$uri->host_port]}: $!";
  72. my @result = $self->AuthSend(
  73. username => $uri->user,
  74. password => $uri->password,
  75. resource => 'soapliteClient',
  76. );
  77. $result[0] eq "ok" or Carp::croak "Can't authenticate to @{[$uri->host_port]}: @result";
  78. $self->AddDelegate(
  79. namespace => $NAMESPACE,
  80. parent => 'Net::Jabber::Query',
  81. parenttype => 'query',
  82. delegate => 'SOAP::Transport::JABBER::Query',
  83. );
  84. # Get roster and announce presence
  85. $self->RosterGet();
  86. $self->PresenceSend();
  87. $self->SUPER::endpoint($endpoint);
  88. }
  89. sub send_receive {
  90. my($self, %parameters) = @_;
  91. my($envelope, $endpoint, $encoding) =
  92. @parameters{qw(envelope endpoint encoding)};
  93. $self->endpoint($endpoint ||= $self->endpoint);
  94. my($undef, $to, $resource) = split m!/!, URI->new($endpoint)->path, 3;
  95. # Create a Jabber info/query message
  96. my $iq = new Net::Jabber::IQ();
  97. $iq->SetIQ(
  98. type => 'set',
  99. to => join '/', $to => $resource || 'soapliteServer',
  100. );
  101. my $query = $iq->NewQuery($NAMESPACE);
  102. $query->SetPayload($envelope);
  103. SOAP::Trace::debug($envelope);
  104. my $iq_rcvd = $self->SendAndReceiveWithID($iq);
  105. my($query_rcvd) = $iq_rcvd->GetQuery($NAMESPACE) if $iq_rcvd; # expect only one
  106. my $msg = $query_rcvd->GetPayload() if $query_rcvd;
  107. SOAP::Trace::debug($msg);
  108. my $code = $self->GetErrorCode();
  109. $self->code($code);
  110. $self->message($code);
  111. $self->is_success(!defined $code || $code eq '');
  112. $self->status($code);
  113. return $msg;
  114. }
  115. # ======================================================================
  116. package SOAP::Transport::JABBER::Server;
  117. use Carp ();
  118. use vars qw(@ISA $AUTOLOAD);
  119. @ISA = qw(SOAP::Server);
  120. sub new {
  121. my $self = shift;
  122. unless (ref $self) {
  123. my $class = ref($self) || $self;
  124. my $uri = URI->new(shift);
  125. $self = $class->SUPER::new(@_);
  126. $self->{_jabberserver} = Net::Jabber::Client->new;
  127. $self->{_jabberserver}->Connect(
  128. hostname => $uri->host,
  129. port => $uri->port,
  130. ) or Carp::croak "Can't connect to @{[$uri->host_port]}: $!";
  131. my($undef, $resource) = split m!/!, $uri->path, 2;
  132. my @result = $self->AuthSend(
  133. username => $uri->user,
  134. password => $uri->password,
  135. resource => $resource || 'soapliteServer',
  136. );
  137. $result[0] eq "ok" or Carp::croak "Can't authenticate to @{[$uri->host_port]}: @result";
  138. $self->{_jabberserver}->SetCallBacks(
  139. iq => sub {
  140. shift;
  141. my $iq = new Net::Jabber::IQ(@_);
  142. my($query) = $iq->GetQuery($NAMESPACE); # expect only one
  143. my $request = $query->GetPayload();
  144. SOAP::Trace::debug($request);
  145. # Set up response
  146. my $reply = $iq->Reply;
  147. my $x = $reply->NewQuery($NAMESPACE);
  148. my $response = $self->SUPER::handle($request);
  149. $x->SetPayload($response);
  150. # Send response
  151. $self->{_jabberserver}->Send($reply);
  152. }
  153. );
  154. $self->AddDelegate(
  155. namespace => $NAMESPACE,
  156. parent => 'Net::Jabber::Query',
  157. parenttype => 'query',
  158. delegate => 'SOAP::Transport::JABBER::Query',
  159. );
  160. $self->RosterGet();
  161. $self->PresenceSend();
  162. }
  163. return $self;
  164. }
  165. sub AUTOLOAD {
  166. my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
  167. return if $method eq 'DESTROY';
  168. no strict 'refs';
  169. *$AUTOLOAD = sub { shift->{_jabberserver}->$method(@_) };
  170. goto &$AUTOLOAD;
  171. }
  172. sub handle {
  173. shift->Process();
  174. }
  175. # ======================================================================
  176. 1;
  177. __END__
  178. =head1 NAME
  179. SOAP::Transport::JABBER - Server/Client side JABBER support for SOAP::Lite
  180. =head1 SYNOPSIS
  181. =over 4
  182. =item Client
  183. use SOAP::Lite
  184. uri => 'http://my.own.site.com/My/Examples',
  185. proxy => 'jabber://username:[email protected]:5222/[email protected]/',
  186. # proto username passwd server port destination resource (optional)
  187. ;
  188. print getStateName(1);
  189. =item Server
  190. use SOAP::Transport::JABBER;
  191. my $server = SOAP::Transport::JABBER::Server
  192. -> new('jabber://username:[email protected]:5222')
  193. # specify list of objects-by-reference here
  194. -> objects_by_reference(qw(My::PersistentIterator My::SessionIterator My::Chat))
  195. # specify path to My/Examples.pm here
  196. -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
  197. ;
  198. print "Contact to SOAP server\n";
  199. do { $server->handle } while sleep 10;
  200. =back
  201. =head1 DESCRIPTION
  202. =head1 COPYRIGHT
  203. Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved.
  204. This library is free software; you can redistribute it and/or modify
  205. it under the same terms as Perl itself.
  206. =head1 AUTHOR
  207. Paul Kulchenko (paulclinger@yahoo.com)
  208. =cut