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.

275 lines
7.9 KiB

  1. #
  2. # $Id: http.pm,v 1.50 2000/05/24 09:41:13 gisle Exp $
  3. package LWP::Protocol::http;
  4. use strict;
  5. require LWP::Debug;
  6. require HTTP::Response;
  7. require HTTP::Status;
  8. require IO::Socket;
  9. require IO::Select;
  10. use vars qw(@ISA @EXTRA_SOCK_OPTS);
  11. require LWP::Protocol;
  12. @ISA = qw(LWP::Protocol);
  13. my $CRLF = "\015\012"; # how lines should be terminated;
  14. # "\r\n" is not correct on all systems, for
  15. # instance MacPerl defines it to "\012\015"
  16. sub _new_socket
  17. {
  18. my($self, $host, $port, $timeout) = @_;
  19. local($^W) = 0; # IO::Socket::INET can be noisy
  20. my $sock = IO::Socket::INET->new(PeerAddr => $host,
  21. PeerPort => $port,
  22. Proto => 'tcp',
  23. Timeout => $timeout,
  24. $self->_extra_sock_opts($host, $port),
  25. );
  26. unless ($sock) {
  27. # IO::Socket::INET leaves additional error messages in $@
  28. $@ =~ s/^.*?: //;
  29. die "Can't connect to $host:$port ($@)";
  30. }
  31. $sock;
  32. }
  33. sub _extra_sock_opts # to be overridden by subclass
  34. {
  35. return @EXTRA_SOCK_OPTS;
  36. }
  37. sub _check_sock
  38. {
  39. #my($self, $req, $sock) = @_;
  40. }
  41. sub _get_sock_info
  42. {
  43. my($self, $res, $sock) = @_;
  44. if (defined(my $peerhost = $sock->peerhost)) {
  45. $res->header("Client-Peer" => "$peerhost:" . $sock->peerport);
  46. }
  47. }
  48. sub _fixup_header
  49. {
  50. my($self, $h, $url) = @_;
  51. $h->remove_header('Connection'); # need support here to be useful
  52. # HTTP/1.1 will require us to send the 'Host' header, so we might
  53. # as well start now.
  54. my $hhost = $url->authority;
  55. $hhost =~ s/^([^\@]*)\@//; # get rid of potential "user:pass@"
  56. $h->header('Host' => $hhost) unless defined $h->header('Host');
  57. # add authorization header if we need them. HTTP URLs do
  58. # not really support specification of user and password, but
  59. # we allow it.
  60. if (defined($1) && not $h->header('Authorization')) {
  61. require URI::Escape;
  62. $h->authorization_basic(map URI::Escape::uri_unescape($_),
  63. split(":", $1));
  64. }
  65. }
  66. sub request
  67. {
  68. my($self, $request, $proxy, $arg, $size, $timeout) = @_;
  69. LWP::Debug::trace('()');
  70. $size ||= 4096;
  71. # check method
  72. my $method = $request->method;
  73. unless ($method =~ /^[A-Za-z0-9_!\#\$%&\'*+\-.^\`|~]+$/) { # HTTP token
  74. return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
  75. 'Library does not allow method ' .
  76. "$method for 'http:' URLs";
  77. }
  78. my $url = $request->url;
  79. my($host, $port, $fullpath);
  80. # Check if we're proxy'ing
  81. if (defined $proxy) {
  82. # $proxy is an URL to an HTTP server which will proxy this request
  83. $host = $proxy->host;
  84. $port = $proxy->port;
  85. $fullpath = $method eq "CONNECT" ?
  86. ($url->host . ":" . $url->port) :
  87. $url->as_string;
  88. }
  89. else {
  90. $host = $url->host;
  91. $port = $url->port;
  92. $fullpath = $url->path_query;
  93. $fullpath = "/" unless length $fullpath;
  94. }
  95. # connect to remote site
  96. my $socket = $self->_new_socket($host, $port, $timeout);
  97. $self->_check_sock($request, $socket);
  98. my $sel = IO::Select->new($socket) if $timeout;
  99. my $request_line = "$method $fullpath HTTP/1.0$CRLF";
  100. my $h = $request->headers->clone;
  101. my $cont_ref = $request->content_ref;
  102. $cont_ref = $$cont_ref if ref($$cont_ref);
  103. my $ctype = ref($cont_ref);
  104. # If we're sending content we *have* to specify a content length
  105. # otherwise the server won't know a messagebody is coming.
  106. if ($ctype eq 'CODE') {
  107. die 'No Content-Length header for request with dynamic content'
  108. unless defined($h->header('Content-Length')) ||
  109. $h->content_type =~ /^multipart\//;
  110. # For HTTP/1.1 we could have used chunked transfer encoding...
  111. }
  112. else {
  113. $h->header('Content-Length' => length $$cont_ref)
  114. if defined($$cont_ref) && length($$cont_ref);
  115. }
  116. $self->_fixup_header($h, $url);
  117. my $buf = $request_line . $h->as_string($CRLF) . $CRLF;
  118. my $n; # used for return value from syswrite/sysread
  119. die "write timeout" if $timeout && !$sel->can_write($timeout);
  120. $n = $socket->syswrite($buf, length($buf));
  121. die $! unless defined($n);
  122. die "short write" unless $n == length($buf);
  123. LWP::Debug::conns($buf);
  124. if ($ctype eq 'CODE') {
  125. while ( ($buf = &$cont_ref()), defined($buf) && length($buf)) {
  126. die "write timeout" if $timeout && !$sel->can_write($timeout);
  127. $n = $socket->syswrite($buf, length($buf));
  128. die $! unless defined($n);
  129. die "short write" unless $n == length($buf);
  130. LWP::Debug::conns($buf);
  131. }
  132. }
  133. elsif (defined($$cont_ref) && length($$cont_ref)) {
  134. die "write timeout" if $timeout && !$sel->can_write($timeout);
  135. $n = $socket->syswrite($$cont_ref, length($$cont_ref));
  136. die $! unless defined($n);
  137. die "short write" unless $n == length($$cont_ref);
  138. LWP::Debug::conns($buf);
  139. }
  140. # read response line from server
  141. LWP::Debug::debug('reading response');
  142. my $response;
  143. $buf = '';
  144. # Inside this loop we will read the response line and all headers
  145. # found in the response.
  146. while (1) {
  147. die "read timeout" if $timeout && !$sel->can_read($timeout);
  148. $n = $socket->sysread($buf, $size, length($buf));
  149. die $! unless defined($n);
  150. die "unexpected EOF before status line seen" unless $n;
  151. LWP::Debug::conns($buf);
  152. if ($buf =~ s/^(HTTP\/\d+\.\d+)[ \t]+(\d+)[ \t]*([^\012]*)\012//) {
  153. # HTTP/1.0 response or better
  154. my($ver,$code,$msg) = ($1, $2, $3);
  155. $msg =~ s/\015$//;
  156. LWP::Debug::debug("$ver $code $msg");
  157. $response = HTTP::Response->new($code, $msg);
  158. $response->protocol($ver);
  159. # ensure that we have read all headers. The headers will be
  160. # terminated by two blank lines
  161. until ($buf =~ /^\015?\012/ || $buf =~ /\015?\012\015?\012/) {
  162. # must read more if we can...
  163. LWP::Debug::debug("need more header data");
  164. die "read timeout" if $timeout && !$sel->can_read($timeout);
  165. $n = $socket->sysread($buf, $size, length($buf));
  166. die $! unless defined($n);
  167. die "unexpected EOF before all headers seen" unless $n;
  168. #LWP::Debug::conns($buf);
  169. }
  170. # now we start parsing the headers. The strategy is to
  171. # remove one line at a time from the beginning of the header
  172. # buffer ($res).
  173. my($key, $val);
  174. while ($buf =~ s/([^\012]*)\012//) {
  175. my $line = $1;
  176. # if we need to restore as content when illegal headers
  177. # are found.
  178. my $save = "$line\012";
  179. $line =~ s/\015$//;
  180. last unless length $line;
  181. if ($line =~ /^([a-zA-Z0-9_\-.]+)\s*:\s*(.*)/) {
  182. $response->push_header($key, $val) if $key;
  183. ($key, $val) = ($1, $2);
  184. } elsif ($line =~ /^\s+(.*)/ && $key) {
  185. $val .= " $1";
  186. } else {
  187. $response->push_header("Client-Bad-Header-Line" => $line);
  188. }
  189. }
  190. $response->push_header($key, $val) if $key;
  191. last;
  192. }
  193. elsif ((length($buf) >= 5 and $buf !~ /^HTTP\//) or
  194. $buf =~ /\012/ ) {
  195. # HTTP/0.9 or worse
  196. LWP::Debug::debug("HTTP/0.9 assume OK");
  197. $response = HTTP::Response->new(&HTTP::Status::RC_OK, "OK");
  198. $response->protocol('HTTP/0.9');
  199. last;
  200. }
  201. else {
  202. # need more data
  203. LWP::Debug::debug("need more status line data");
  204. }
  205. };
  206. $response->request($request);
  207. $self->_get_sock_info($response, $socket);
  208. if ($method eq "CONNECT") {
  209. $response->{client_socket} = $socket; # so it can be picked up
  210. $response->content($buf); # in case we read more than the headers
  211. return $response;
  212. }
  213. my $usebuf = length($buf) > 0;
  214. $response = $self->collect($arg, $response, sub {
  215. if ($usebuf) {
  216. $usebuf = 0;
  217. return \$buf;
  218. }
  219. die "read timeout" if $timeout && !$sel->can_read($timeout);
  220. my $n = $socket->sysread($buf, $size);
  221. die $! unless defined($n);
  222. #LWP::Debug::conns($buf);
  223. return \$buf;
  224. } );
  225. #$socket->close;
  226. $response;
  227. }
  228. 1;