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.

304 lines
8.1 KiB

  1. # $Id: Protocol.pm,v 1.36 2000/04/09 11:20:48 gisle Exp $
  2. package LWP::Protocol;
  3. =head1 NAME
  4. LWP::Protocol - Base class for LWP protocols
  5. =head1 SYNOPSIS
  6. package LWP::Protocol::foo;
  7. require LWP::Protocol;
  8. @ISA=qw(LWP::Protocol);
  9. =head1 DESCRIPTION
  10. This class is used a the base class for all protocol implementations
  11. supported by the LWP library.
  12. When creating an instance of this class using
  13. C<LWP::Protocol::create($url)>, and you get an initialised subclass
  14. appropriate for that access method. In other words, the
  15. LWP::Protocol::create() function calls the constructor for one of its
  16. subclasses.
  17. All derived LWP::Protocol classes need to override the request()
  18. method which is used to service a request. The overridden method can
  19. make use of the collect() function to collect together chunks of data
  20. as it is received.
  21. The following methods and functions are provided:
  22. =over 4
  23. =cut
  24. #####################################################################
  25. require LWP::MemberMixin;
  26. @ISA = qw(LWP::MemberMixin);
  27. $VERSION = sprintf("%d.%02d", q$Revision: 1.36 $ =~ /(\d+)\.(\d+)/);
  28. use strict;
  29. use Carp ();
  30. use HTTP::Status ();
  31. use HTTP::Response;
  32. require HTML::HeadParser;
  33. my %ImplementedBy = (); # scheme => classname
  34. =item $prot = LWP::Protocol->new()
  35. The LWP::Protocol constructor is inherited by subclasses. As this is a
  36. virtual base class this method should B<not> be called directly.
  37. =cut
  38. sub new
  39. {
  40. my($class) = @_;
  41. my $self = bless {
  42. 'timeout' => 0,
  43. 'parse_head' => 1,
  44. }, $class;
  45. $self;
  46. }
  47. =item $prot = LWP::Protocol::create($url)
  48. Create an object of the class implementing the protocol to handle the
  49. given scheme. This is a function, not a method. It is more an object
  50. factory than a constructor. This is the function user agents should
  51. use to access protocols.
  52. =cut
  53. sub create
  54. {
  55. my $scheme = shift;
  56. my $impclass = LWP::Protocol::implementor($scheme) or
  57. Carp::croak("Protocol scheme '$scheme' is not supported");
  58. # hand-off to scheme specific implementation sub-class
  59. return $impclass->new($scheme);
  60. }
  61. =item $class = LWP::Protocol::implementor($scheme, [$class])
  62. Get and/or set implementor class for a scheme. Returns '' if the
  63. specified scheme is not supported.
  64. =cut
  65. sub implementor
  66. {
  67. my($scheme, $impclass) = @_;
  68. if ($impclass) {
  69. $ImplementedBy{$scheme} = $impclass;
  70. }
  71. my $ic = $ImplementedBy{$scheme};
  72. return $ic if $ic;
  73. return '' unless $scheme =~ /^([.+\-\w]+)$/; # check valid URL schemes
  74. $scheme = $1; # untaint
  75. $scheme =~ s/[.+\-]/_/g; # make it a legal module name
  76. # scheme not yet known, look for a 'use'd implementation
  77. $ic = "LWP::Protocol::$scheme"; # default location
  78. $ic = "LWP::Protocol::nntp" if $scheme eq 'news'; #XXX ugly hack
  79. no strict 'refs';
  80. # check we actually have one for the scheme:
  81. unless (@{"${ic}::ISA"}) {
  82. # try to autoload it
  83. eval "require $ic";
  84. if ($@) {
  85. if ($@ =~ /Can't locate/) { #' #emacs get confused by '
  86. $ic = '';
  87. } else {
  88. die "$@\n";
  89. }
  90. }
  91. }
  92. $ImplementedBy{$scheme} = $ic if $ic;
  93. $ic;
  94. }
  95. =item $prot->request(...)
  96. $response = $protocol->request($request, $proxy, undef);
  97. $response = $protocol->request($request, $proxy, '/tmp/sss');
  98. $response = $protocol->request($request, $proxy, \&callback, 1024);
  99. Dispactches a request over the protocol, and returns a response
  100. object. This method needs to be overridden in subclasses. Referer to
  101. L<LWP::UserAgent> for description of the arguments.
  102. =cut
  103. sub request
  104. {
  105. my($self, $request, $proxy, $arg, $size, $timeout) = @_;
  106. Carp::croak('LWP::Protocol::request() needs to be overridden in subclasses');
  107. }
  108. =item $prot->timeout($seconds)
  109. Get and set the timeout value in seconds
  110. =item $prot->parse_head($yesno)
  111. Should we initialize response headers from the <head> section of HTML
  112. documents.
  113. =cut
  114. sub timeout { shift->_elem('timeout', @_); }
  115. sub parse_head { shift->_elem('parse_head', @_); }
  116. sub max_size { shift->_elem('max_size', @_); }
  117. =item $prot->collect($arg, $response, $collector)
  118. Called to collect the content of a request, and process it
  119. appropriately into a scalar, file, or by calling a callback. If $arg
  120. is undefined, then the content is stored within the $response. If
  121. $arg is a simple scalar, then $arg is interpreted as a file name and
  122. the content is written to this file. If $arg is a reference to a
  123. routine, then content is passed to this routine.
  124. The $collector is a routine that will be called and which is
  125. reponsible for returning pieces (as ref to scalar) of the content to
  126. process. The $collector signals EOF by returning a reference to an
  127. empty sting.
  128. The return value from collect() is the $response object reference.
  129. B<Note:> We will only use the callback or file argument if
  130. $response->is_success(). This avoids sendig content data for
  131. redirects and authentization responses to the callback which would be
  132. confusing.
  133. =cut
  134. sub collect
  135. {
  136. my ($self, $arg, $response, $collector) = @_;
  137. my $content;
  138. my($parse_head, $timeout, $max_size) =
  139. @{$self}{qw(parse_head timeout max_size)};
  140. my $parser;
  141. if ($parse_head && $response->content_type eq 'text/html') {
  142. $parser = HTML::HeadParser->new($response->{'_headers'});
  143. }
  144. my $content_size = 0;
  145. if (!defined($arg) || !$response->is_success) {
  146. # scalar
  147. while ($content = &$collector, length $$content) {
  148. if ($parser) {
  149. $parser->parse($$content) or undef($parser);
  150. }
  151. LWP::Debug::debug("read " . length($$content) . " bytes");
  152. $response->add_content($$content);
  153. $content_size += length($$content);
  154. if ($max_size && $content_size > $max_size) {
  155. LWP::Debug::debug("Aborting because size limit exceeded");
  156. my $tot = $response->header("Content-Length") || 0;
  157. $response->header("X-Content-Range", "bytes 0-$content_size/$tot");
  158. last;
  159. }
  160. }
  161. }
  162. elsif (!ref($arg)) {
  163. # filename
  164. open(OUT, ">$arg") or
  165. return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
  166. "Cannot write to '$arg': $!");
  167. binmode(OUT);
  168. local($\) = ""; # ensure standard $OUTPUT_RECORD_SEPARATOR
  169. while ($content = &$collector, length $$content) {
  170. if ($parser) {
  171. $parser->parse($$content) or undef($parser);
  172. }
  173. LWP::Debug::debug("read " . length($$content) . " bytes");
  174. print OUT $$content;
  175. $content_size += length($$content);
  176. if ($max_size && $content_size > $max_size) {
  177. LWP::Debug::debug("Aborting because size limit exceeded");
  178. my $tot = $response->header("Content-Length") || 0;
  179. $response->header("X-Content-Range", "bytes 0-$content_size/$tot");
  180. last;
  181. }
  182. }
  183. close(OUT);
  184. }
  185. elsif (ref($arg) eq 'CODE') {
  186. # read into callback
  187. while ($content = &$collector, length $$content) {
  188. if ($parser) {
  189. $parser->parse($$content) or undef($parser);
  190. }
  191. LWP::Debug::debug("read " . length($$content) . " bytes");
  192. eval {
  193. &$arg($$content, $response, $self);
  194. };
  195. if ($@) {
  196. chomp($@);
  197. $response->header('X-Died' => $@);
  198. last;
  199. }
  200. }
  201. }
  202. else {
  203. return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
  204. "Unexpected collect argument '$arg'");
  205. }
  206. $response;
  207. }
  208. =item $prot->collect_once($arg, $response, $content)
  209. Can be called when the whole response content is available as
  210. $content. This will invoke collect() with a collector callback that
  211. returns a reference to $content the first time and an empty string the
  212. next.
  213. =cut
  214. sub collect_once
  215. {
  216. my($self, $arg, $response) = @_;
  217. my $content = \ $_[3];
  218. my $first = 1;
  219. $self->collect($arg, $response, sub {
  220. return $content if $first--;
  221. return \ "";
  222. });
  223. }
  224. 1;
  225. =head1 SEE ALSO
  226. Inspect the F<LWP/Protocol/file.pm> and F<LWP/Protocol/http.pm> files
  227. for examples of usage.
  228. =head1 COPYRIGHT
  229. Copyright 1995-2000 Gisle Aas.
  230. This library is free software; you can redistribute it and/or
  231. modify it under the same terms as Perl itself.
  232. =cut