blob: 5c82edd8969725058c919df0b7ed8b8da76afb89 [file] [log] [blame]
Greg Stein5e0fa402000-06-26 08:28:01 +00001"""HTTP/1.1 client library
Guido van Rossum41999c11997-12-09 00:12:23 +00002
Greg Stein5e0fa402000-06-26 08:28:01 +00003<intro stuff goes here>
4<other stuff, too>
Guido van Rossum41999c11997-12-09 00:12:23 +00005
Greg Stein5e0fa402000-06-26 08:28:01 +00006HTTPConnection go through a number of "states", which defines when a client
7may legally make another request or fetch the response for a particular
8request. This diagram details these state transitions:
Guido van Rossum41999c11997-12-09 00:12:23 +00009
Greg Stein5e0fa402000-06-26 08:28:01 +000010 (null)
11 |
12 | HTTPConnection()
13 v
14 Idle
15 |
16 | putrequest()
17 v
18 Request-started
19 |
20 | ( putheader() )* endheaders()
21 v
22 Request-sent
23 |
24 | response = getresponse()
25 v
26 Unread-response [Response-headers-read]
27 |\____________________
Tim Peters5ceadc82001-01-13 19:16:21 +000028 | |
29 | response.read() | putrequest()
30 v v
31 Idle Req-started-unread-response
32 ______/|
33 / |
34 response.read() | | ( putheader() )* endheaders()
35 v v
36 Request-started Req-sent-unread-response
37 |
38 | response.read()
39 v
40 Request-sent
Greg Stein5e0fa402000-06-26 08:28:01 +000041
42This diagram presents the following rules:
43 -- a second request may not be started until {response-headers-read}
44 -- a response [object] cannot be retrieved until {request-sent}
45 -- there is no differentiation between an unread response body and a
46 partially read response body
47
48Note: this enforcement is applied by the HTTPConnection class. The
49 HTTPResponse class does not enforce this state machine, which
50 implies sophisticated clients may accelerate the request/response
51 pipeline. Caution should be taken, though: accelerating the states
52 beyond the above pattern may imply knowledge of the server's
53 connection-close behavior for certain requests. For example, it
54 is impossible to tell whether the server will close the connection
55 UNTIL the response headers have been read; this means that further
56 requests cannot be placed into the pipeline until it is known that
57 the server will NOT be closing the connection.
58
59Logical State __state __response
60------------- ------- ----------
61Idle _CS_IDLE None
62Request-started _CS_REQ_STARTED None
63Request-sent _CS_REQ_SENT None
64Unread-response _CS_IDLE <response_class>
65Req-started-unread-response _CS_REQ_STARTED <response_class>
66Req-sent-unread-response _CS_REQ_SENT <response_class>
Guido van Rossum41999c11997-12-09 00:12:23 +000067"""
Guido van Rossum23acc951994-02-21 16:36:04 +000068
Jeremy Hylton6459c8d2001-10-11 17:47:22 +000069import errno
Guido van Rossum65ab98c1995-08-07 20:13:02 +000070import mimetools
Jeremy Hylton6459c8d2001-10-11 17:47:22 +000071import socket
Jeremy Hylton8acf1e02002-03-08 19:35:51 +000072from urlparse import urlsplit
Guido van Rossum23acc951994-02-21 16:36:04 +000073
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000074try:
Greg Steindd6eefb2000-07-18 09:09:48 +000075 from cStringIO import StringIO
Greg Stein5e0fa402000-06-26 08:28:01 +000076except ImportError:
Greg Steindd6eefb2000-07-18 09:09:48 +000077 from StringIO import StringIO
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000078
Skip Montanaro951a8842001-06-01 16:25:38 +000079__all__ = ["HTTP", "HTTPResponse", "HTTPConnection", "HTTPSConnection",
80 "HTTPException", "NotConnected", "UnknownProtocol",
Jeremy Hylton7c75c992002-06-28 23:38:14 +000081 "UnknownTransferEncoding", "UnimplementedFileMode",
82 "IncompleteRead", "InvalidURL", "ImproperConnectionState",
83 "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
84 "BadStatusLine", "error"]
Skip Montanaro2dd42762001-01-23 15:35:05 +000085
Guido van Rossum23acc951994-02-21 16:36:04 +000086HTTP_PORT = 80
Guido van Rossum09c8b6c1999-12-07 21:37:17 +000087HTTPS_PORT = 443
88
Greg Stein5e0fa402000-06-26 08:28:01 +000089_UNKNOWN = 'UNKNOWN'
90
91# connection states
92_CS_IDLE = 'Idle'
93_CS_REQ_STARTED = 'Request-started'
94_CS_REQ_SENT = 'Request-sent'
95
Martin v. Löwis39a31782004-09-18 09:03:49 +000096# status codes
97# informational
98CONTINUE = 100
99SWITCHING_PROTOCOLS = 101
100PROCESSING = 102
101
102# successful
103OK = 200
104CREATED = 201
105ACCEPTED = 202
106NON_AUTHORITATIVE_INFORMATION = 203
107NO_CONTENT = 204
108RESET_CONTENT = 205
109PARTIAL_CONTENT = 206
110MULTI_STATUS = 207
111IM_USED = 226
112
113# redirection
114MULTIPLE_CHOICES = 300
115MOVED_PERMANENTLY = 301
116FOUND = 302
117SEE_OTHER = 303
118NOT_MODIFIED = 304
119USE_PROXY = 305
120TEMPORARY_REDIRECT = 307
121
122# client error
123BAD_REQUEST = 400
124UNAUTHORIZED = 401
125PAYMENT_REQUIRED = 402
126FORBIDDEN = 403
127NOT_FOUND = 404
128METHOD_NOT_ALLOWED = 405
129NOT_ACCEPTABLE = 406
130PROXY_AUTHENTICATION_REQUIRED = 407
131REQUEST_TIMEOUT = 408
132CONFLICT = 409
133GONE = 410
134LENGTH_REQUIRED = 411
135PRECONDITION_FAILED = 412
136REQUEST_ENTITY_TOO_LARGE = 413
137REQUEST_URI_TOO_LONG = 414
138UNSUPPORTED_MEDIA_TYPE = 415
139REQUESTED_RANGE_NOT_SATISFIABLE = 416
140EXPECTATION_FAILED = 417
141UNPROCESSABLE_ENTITY = 422
142LOCKED = 423
143FAILED_DEPENDENCY = 424
144UPGRADE_REQUIRED = 426
145
146# server error
147INTERNAL_SERVER_ERROR = 500
148NOT_IMPLEMENTED = 501
149BAD_GATEWAY = 502
150SERVICE_UNAVAILABLE = 503
151GATEWAY_TIMEOUT = 504
152HTTP_VERSION_NOT_SUPPORTED = 505
153INSUFFICIENT_STORAGE = 507
154NOT_EXTENDED = 510
155
Georg Brandl80ba8e82005-09-29 20:16:07 +0000156# maximal amount of data to read at one time in _safe_read
157MAXAMOUNT = 1048576
158
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000159class HTTPMessage(mimetools.Message):
160
161 def addheader(self, key, value):
162 """Add header for field key handling repeats."""
163 prev = self.dict.get(key)
164 if prev is None:
165 self.dict[key] = value
166 else:
167 combined = ", ".join((prev, value))
168 self.dict[key] = combined
169
170 def addcontinue(self, key, more):
171 """Add more field data from a continuation line."""
172 prev = self.dict[key]
173 self.dict[key] = prev + "\n " + more
174
175 def readheaders(self):
176 """Read header lines.
177
178 Read header lines up to the entirely blank line that terminates them.
179 The (normally blank) line that ends the headers is skipped, but not
180 included in the returned list. If a non-header line ends the headers,
181 (which is an error), an attempt is made to backspace over it; it is
182 never included in the returned list.
183
184 The variable self.status is set to the empty string if all went well,
185 otherwise it is an error message. The variable self.headers is a
186 completely uninterpreted list of lines contained in the header (so
187 printing them will reproduce the header exactly as it appears in the
188 file).
189
190 If multiple header fields with the same name occur, they are combined
191 according to the rules in RFC 2616 sec 4.2:
192
193 Appending each subsequent field-value to the first, each separated
194 by a comma. The order in which header fields with the same field-name
195 are received is significant to the interpretation of the combined
196 field value.
197 """
198 # XXX The implementation overrides the readheaders() method of
199 # rfc822.Message. The base class design isn't amenable to
200 # customized behavior here so the method here is a copy of the
201 # base class code with a few small changes.
202
203 self.dict = {}
204 self.unixfrom = ''
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000205 self.headers = hlist = []
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000206 self.status = ''
207 headerseen = ""
208 firstline = 1
209 startofline = unread = tell = None
210 if hasattr(self.fp, 'unread'):
211 unread = self.fp.unread
212 elif self.seekable:
213 tell = self.fp.tell
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000214 while True:
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000215 if tell:
216 try:
217 startofline = tell()
218 except IOError:
219 startofline = tell = None
220 self.seekable = 0
221 line = self.fp.readline()
222 if not line:
223 self.status = 'EOF in headers'
224 break
225 # Skip unix From name time lines
226 if firstline and line.startswith('From '):
227 self.unixfrom = self.unixfrom + line
228 continue
229 firstline = 0
230 if headerseen and line[0] in ' \t':
231 # XXX Not sure if continuation lines are handled properly
232 # for http and/or for repeating headers
233 # It's a continuation line.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000234 hlist.append(line)
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000235 self.addcontinue(headerseen, line.strip())
236 continue
237 elif self.iscomment(line):
238 # It's a comment. Ignore it.
239 continue
240 elif self.islast(line):
241 # Note! No pushback here! The delimiter line gets eaten.
242 break
243 headerseen = self.isheader(line)
244 if headerseen:
245 # It's a legal header line, save it.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000246 hlist.append(line)
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000247 self.addheader(headerseen, line[len(headerseen)+1:].strip())
248 continue
249 else:
250 # It's not a header line; throw it back and stop here.
251 if not self.dict:
252 self.status = 'No headers'
253 else:
254 self.status = 'Non-header line where header expected'
255 # Try to undo the read.
256 if unread:
257 unread(line)
258 elif tell:
259 self.fp.seek(startofline)
260 else:
261 self.status = self.status + '; bad seek'
262 break
Greg Stein5e0fa402000-06-26 08:28:01 +0000263
264class HTTPResponse:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000265
266 # strict: If true, raise BadStatusLine if the status line can't be
267 # parsed as a valid HTTP/1.0 or 1.1 status line. By default it is
Skip Montanaro186bec22002-07-25 16:10:38 +0000268 # false because it prevents clients from talking to HTTP/0.9
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000269 # servers. Note that a response with a sufficiently corrupted
270 # status line will look like an HTTP/0.9 response.
271
272 # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
273
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000274 def __init__(self, sock, debuglevel=0, strict=0, method=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000275 self.fp = sock.makefile('rb', 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000276 self.debuglevel = debuglevel
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000277 self.strict = strict
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000278 self._method = method
Greg Stein5e0fa402000-06-26 08:28:01 +0000279
Greg Steindd6eefb2000-07-18 09:09:48 +0000280 self.msg = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000281
Greg Steindd6eefb2000-07-18 09:09:48 +0000282 # from the Status-Line of the response
Tim Peters07e99cb2001-01-14 23:47:14 +0000283 self.version = _UNKNOWN # HTTP-Version
284 self.status = _UNKNOWN # Status-Code
285 self.reason = _UNKNOWN # Reason-Phrase
Greg Stein5e0fa402000-06-26 08:28:01 +0000286
Tim Peters07e99cb2001-01-14 23:47:14 +0000287 self.chunked = _UNKNOWN # is "chunked" being used?
288 self.chunk_left = _UNKNOWN # bytes left to read in current chunk
289 self.length = _UNKNOWN # number of bytes left in response
290 self.will_close = _UNKNOWN # conn will close at end of response
Greg Stein5e0fa402000-06-26 08:28:01 +0000291
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000292 def _read_status(self):
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000293 # Initialize with Simple-Response defaults
Greg Stein5e0fa402000-06-26 08:28:01 +0000294 line = self.fp.readline()
Jeremy Hylton30f86742000-09-18 22:50:38 +0000295 if self.debuglevel > 0:
296 print "reply:", repr(line)
Jeremy Hyltonb6769522003-06-29 17:55:05 +0000297 if not line:
298 # Presumably, the server closed the connection before
299 # sending a valid response.
300 raise BadStatusLine(line)
Greg Steindd6eefb2000-07-18 09:09:48 +0000301 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000302 [version, status, reason] = line.split(None, 2)
Greg Steindd6eefb2000-07-18 09:09:48 +0000303 except ValueError:
304 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000305 [version, status] = line.split(None, 1)
Greg Steindd6eefb2000-07-18 09:09:48 +0000306 reason = ""
307 except ValueError:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000308 # empty version will cause next test to fail and status
309 # will be treated as 0.9 response.
310 version = ""
311 if not version.startswith('HTTP/'):
312 if self.strict:
313 self.close()
314 raise BadStatusLine(line)
315 else:
316 # assume it's a Simple-Response from an 0.9 server
317 self.fp = LineAndFileWrapper(line, self.fp)
318 return "HTTP/0.9", 200, ""
Greg Stein5e0fa402000-06-26 08:28:01 +0000319
Jeremy Hylton23d40472001-04-13 14:57:08 +0000320 # The status code is a three-digit number
321 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000322 status = int(status)
Jeremy Hylton23d40472001-04-13 14:57:08 +0000323 if status < 100 or status > 999:
324 raise BadStatusLine(line)
325 except ValueError:
326 raise BadStatusLine(line)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000327 return version, status, reason
Greg Stein5e0fa402000-06-26 08:28:01 +0000328
Jeremy Hylton39c03802002-07-12 14:04:09 +0000329 def begin(self):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000330 if self.msg is not None:
331 # we've already started reading the response
332 return
333
334 # read until we get a non-100 response
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000335 while True:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000336 version, status, reason = self._read_status()
Martin v. Löwis39a31782004-09-18 09:03:49 +0000337 if status != CONTINUE:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000338 break
339 # skip the header from the 100 response
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000340 while True:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000341 skip = self.fp.readline().strip()
342 if not skip:
343 break
344 if self.debuglevel > 0:
345 print "header:", skip
Tim Petersc411dba2002-07-16 21:35:23 +0000346
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000347 self.status = status
348 self.reason = reason.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +0000349 if version == 'HTTP/1.0':
350 self.version = 10
Jeremy Hylton110941a2000-10-12 19:58:36 +0000351 elif version.startswith('HTTP/1.'):
Tim Peters07e99cb2001-01-14 23:47:14 +0000352 self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
Jeremy Hylton110941a2000-10-12 19:58:36 +0000353 elif version == 'HTTP/0.9':
354 self.version = 9
Greg Steindd6eefb2000-07-18 09:09:48 +0000355 else:
356 raise UnknownProtocol(version)
Greg Stein5e0fa402000-06-26 08:28:01 +0000357
Jeremy Hylton110941a2000-10-12 19:58:36 +0000358 if self.version == 9:
Georg Brandl0aade9a2005-06-26 22:06:54 +0000359 self.length = None
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000360 self.chunked = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000361 self.will_close = 1
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000362 self.msg = HTTPMessage(StringIO())
Jeremy Hylton110941a2000-10-12 19:58:36 +0000363 return
364
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000365 self.msg = HTTPMessage(self.fp, 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000366 if self.debuglevel > 0:
367 for hdr in self.msg.headers:
368 print "header:", hdr,
Greg Stein5e0fa402000-06-26 08:28:01 +0000369
Greg Steindd6eefb2000-07-18 09:09:48 +0000370 # don't let the msg keep an fp
371 self.msg.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000372
Greg Steindd6eefb2000-07-18 09:09:48 +0000373 # are we using the chunked-style of transfer encoding?
374 tr_enc = self.msg.getheader('transfer-encoding')
Jeremy Hyltond229b3a2002-09-03 19:24:24 +0000375 if tr_enc and tr_enc.lower() == "chunked":
Greg Steindd6eefb2000-07-18 09:09:48 +0000376 self.chunked = 1
377 self.chunk_left = None
378 else:
379 self.chunked = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000380
Greg Steindd6eefb2000-07-18 09:09:48 +0000381 # will the connection close at the end of the response?
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000382 self.will_close = self._check_close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000383
Greg Steindd6eefb2000-07-18 09:09:48 +0000384 # do we have a Content-Length?
385 # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
386 length = self.msg.getheader('content-length')
387 if length and not self.chunked:
Jeremy Hylton30a81812000-09-14 20:34:27 +0000388 try:
389 self.length = int(length)
390 except ValueError:
391 self.length = None
Greg Steindd6eefb2000-07-18 09:09:48 +0000392 else:
393 self.length = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000394
Greg Steindd6eefb2000-07-18 09:09:48 +0000395 # does the body have a fixed length? (of zero)
Martin v. Löwis39a31782004-09-18 09:03:49 +0000396 if (status == NO_CONTENT or status == NOT_MODIFIED or
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000397 100 <= status < 200 or # 1xx codes
398 self._method == 'HEAD'):
Greg Steindd6eefb2000-07-18 09:09:48 +0000399 self.length = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000400
Greg Steindd6eefb2000-07-18 09:09:48 +0000401 # if the connection remains open, and we aren't using chunked, and
402 # a content-length was not provided, then assume that the connection
403 # WILL close.
404 if not self.will_close and \
405 not self.chunked and \
406 self.length is None:
407 self.will_close = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000408
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000409 def _check_close(self):
Jeremy Hylton2c178252004-08-07 16:28:14 +0000410 conn = self.msg.getheader('connection')
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000411 if self.version == 11:
412 # An HTTP/1.1 proxy is assumed to stay open unless
413 # explicitly closed.
414 conn = self.msg.getheader('connection')
Raymond Hettingerbac788a2004-05-04 09:21:43 +0000415 if conn and "close" in conn.lower():
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000416 return True
417 return False
418
Jeremy Hylton2c178252004-08-07 16:28:14 +0000419 # Some HTTP/1.0 implementations have support for persistent
420 # connections, using rules different than HTTP/1.1.
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000421
422 # For older HTTP, Keep-Alive indiciates persistent connection.
423 if self.msg.getheader('keep-alive'):
424 return False
Tim Peters77c06fb2002-11-24 02:35:35 +0000425
Jeremy Hylton2c178252004-08-07 16:28:14 +0000426 # At least Akamai returns a "Connection: Keep-Alive" header,
427 # which was supposed to be sent by the client.
428 if conn and "keep-alive" in conn.lower():
429 return False
430
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000431 # Proxy-Connection is a netscape hack.
432 pconn = self.msg.getheader('proxy-connection')
Raymond Hettingerbac788a2004-05-04 09:21:43 +0000433 if pconn and "keep-alive" in pconn.lower():
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000434 return False
435
436 # otherwise, assume it will close
437 return True
438
Greg Steindd6eefb2000-07-18 09:09:48 +0000439 def close(self):
440 if self.fp:
441 self.fp.close()
442 self.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000443
Greg Steindd6eefb2000-07-18 09:09:48 +0000444 def isclosed(self):
445 # NOTE: it is possible that we will not ever call self.close(). This
446 # case occurs when will_close is TRUE, length is None, and we
447 # read up to the last byte, but NOT past it.
448 #
449 # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
450 # called, meaning self.isclosed() is meaningful.
451 return self.fp is None
452
Jeremy Hylton2c178252004-08-07 16:28:14 +0000453 # XXX It would be nice to have readline and __iter__ for this, too.
454
Greg Steindd6eefb2000-07-18 09:09:48 +0000455 def read(self, amt=None):
456 if self.fp is None:
457 return ''
458
459 if self.chunked:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000460 return self._read_chunked(amt)
Tim Peters230a60c2002-11-09 05:08:07 +0000461
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000462 if amt is None:
Greg Steindd6eefb2000-07-18 09:09:48 +0000463 # unbounded read
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000464 if self.length is None:
Greg Steindd6eefb2000-07-18 09:09:48 +0000465 s = self.fp.read()
466 else:
467 s = self._safe_read(self.length)
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000468 self.length = 0
Tim Peters07e99cb2001-01-14 23:47:14 +0000469 self.close() # we read everything
Greg Steindd6eefb2000-07-18 09:09:48 +0000470 return s
471
472 if self.length is not None:
473 if amt > self.length:
474 # clip the read to the "end of response"
475 amt = self.length
Greg Steindd6eefb2000-07-18 09:09:48 +0000476
477 # we do not use _safe_read() here because this may be a .will_close
478 # connection, and the user is reading more bytes than will be provided
479 # (for example, reading in 1k chunks)
480 s = self.fp.read(amt)
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000481 if self.length is not None:
482 self.length -= len(s)
Greg Steindd6eefb2000-07-18 09:09:48 +0000483
Greg Steindd6eefb2000-07-18 09:09:48 +0000484 return s
485
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000486 def _read_chunked(self, amt):
487 assert self.chunked != _UNKNOWN
488 chunk_left = self.chunk_left
489 value = ''
490
491 # XXX This accumulates chunks by repeated string concatenation,
492 # which is not efficient as the number or size of chunks gets big.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000493 while True:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000494 if chunk_left is None:
495 line = self.fp.readline()
496 i = line.find(';')
497 if i >= 0:
498 line = line[:i] # strip chunk-extensions
499 chunk_left = int(line, 16)
500 if chunk_left == 0:
501 break
502 if amt is None:
503 value += self._safe_read(chunk_left)
504 elif amt < chunk_left:
505 value += self._safe_read(amt)
506 self.chunk_left = chunk_left - amt
507 return value
508 elif amt == chunk_left:
509 value += self._safe_read(amt)
510 self._safe_read(2) # toss the CRLF at the end of the chunk
511 self.chunk_left = None
512 return value
513 else:
514 value += self._safe_read(chunk_left)
515 amt -= chunk_left
516
517 # we read the whole chunk, get another
518 self._safe_read(2) # toss the CRLF at the end of the chunk
519 chunk_left = None
520
521 # read and discard trailer up to the CRLF terminator
522 ### note: we shouldn't have any trailers!
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000523 while True:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000524 line = self.fp.readline()
525 if line == '\r\n':
526 break
527
528 # we read everything; close the "file"
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000529 self.close()
530
531 return value
Tim Peters230a60c2002-11-09 05:08:07 +0000532
Greg Steindd6eefb2000-07-18 09:09:48 +0000533 def _safe_read(self, amt):
534 """Read the number of bytes requested, compensating for partial reads.
535
536 Normally, we have a blocking socket, but a read() can be interrupted
537 by a signal (resulting in a partial read).
538
539 Note that we cannot distinguish between EOF and an interrupt when zero
540 bytes have been read. IncompleteRead() will be raised in this
541 situation.
542
543 This function should be used when <amt> bytes "should" be present for
544 reading. If the bytes are truly not available (due to EOF), then the
545 IncompleteRead exception can be used to detect the problem.
546 """
Georg Brandl80ba8e82005-09-29 20:16:07 +0000547 s = []
Greg Steindd6eefb2000-07-18 09:09:48 +0000548 while amt > 0:
Georg Brandl80ba8e82005-09-29 20:16:07 +0000549 chunk = self.fp.read(min(amt, MAXAMOUNT))
Greg Steindd6eefb2000-07-18 09:09:48 +0000550 if not chunk:
551 raise IncompleteRead(s)
Georg Brandl80ba8e82005-09-29 20:16:07 +0000552 s.append(chunk)
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000553 amt -= len(chunk)
Georg Brandl80ba8e82005-09-29 20:16:07 +0000554 return ''.join(s)
Greg Steindd6eefb2000-07-18 09:09:48 +0000555
556 def getheader(self, name, default=None):
557 if self.msg is None:
558 raise ResponseNotReady()
559 return self.msg.getheader(name, default)
Greg Stein5e0fa402000-06-26 08:28:01 +0000560
Martin v. Löwisdeacce22004-08-18 12:46:26 +0000561 def getheaders(self):
562 """Return list of (header, value) tuples."""
563 if self.msg is None:
564 raise ResponseNotReady()
565 return self.msg.items()
566
Greg Stein5e0fa402000-06-26 08:28:01 +0000567
568class HTTPConnection:
569
Greg Steindd6eefb2000-07-18 09:09:48 +0000570 _http_vsn = 11
571 _http_vsn_str = 'HTTP/1.1'
Greg Stein5e0fa402000-06-26 08:28:01 +0000572
Greg Steindd6eefb2000-07-18 09:09:48 +0000573 response_class = HTTPResponse
574 default_port = HTTP_PORT
575 auto_open = 1
Jeremy Hylton30f86742000-09-18 22:50:38 +0000576 debuglevel = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000577 strict = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000578
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000579 def __init__(self, host, port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000580 self.sock = None
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000581 self._buffer = []
Greg Steindd6eefb2000-07-18 09:09:48 +0000582 self.__response = None
583 self.__state = _CS_IDLE
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000584 self._method = None
Tim Petersc411dba2002-07-16 21:35:23 +0000585
Greg Steindd6eefb2000-07-18 09:09:48 +0000586 self._set_hostport(host, port)
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000587 if strict is not None:
588 self.strict = strict
Greg Stein5e0fa402000-06-26 08:28:01 +0000589
Greg Steindd6eefb2000-07-18 09:09:48 +0000590 def _set_hostport(self, host, port):
591 if port is None:
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000592 i = host.rfind(':')
Skip Montanarocae14d22004-09-14 17:55:21 +0000593 j = host.rfind(']') # ipv6 addresses have [...]
594 if i > j:
Skip Montanaro9d389972002-03-24 16:53:50 +0000595 try:
596 port = int(host[i+1:])
597 except ValueError:
Jeremy Hyltonfbd79942002-07-02 20:19:08 +0000598 raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
Greg Steindd6eefb2000-07-18 09:09:48 +0000599 host = host[:i]
600 else:
601 port = self.default_port
Raymond Hettinger4d037912004-10-14 15:23:38 +0000602 if host and host[0] == '[' and host[-1] == ']':
Brett Cannon0a1af4a2004-09-15 23:26:23 +0000603 host = host[1:-1]
Greg Steindd6eefb2000-07-18 09:09:48 +0000604 self.host = host
605 self.port = port
Greg Stein5e0fa402000-06-26 08:28:01 +0000606
Jeremy Hylton30f86742000-09-18 22:50:38 +0000607 def set_debuglevel(self, level):
608 self.debuglevel = level
609
Greg Steindd6eefb2000-07-18 09:09:48 +0000610 def connect(self):
611 """Connect to the host and port specified in __init__."""
Martin v. Löwis2ad25692001-07-31 08:40:21 +0000612 msg = "getaddrinfo returns an empty list"
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000613 for res in socket.getaddrinfo(self.host, self.port, 0,
614 socket.SOCK_STREAM):
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000615 af, socktype, proto, canonname, sa = res
616 try:
617 self.sock = socket.socket(af, socktype, proto)
618 if self.debuglevel > 0:
619 print "connect: (%s, %s)" % (self.host, self.port)
620 self.sock.connect(sa)
621 except socket.error, msg:
622 if self.debuglevel > 0:
623 print 'connect fail:', (self.host, self.port)
Martin v. Löwis322c0d12001-10-07 08:53:32 +0000624 if self.sock:
625 self.sock.close()
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000626 self.sock = None
627 continue
628 break
629 if not self.sock:
630 raise socket.error, msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000631
Greg Steindd6eefb2000-07-18 09:09:48 +0000632 def close(self):
633 """Close the connection to the HTTP server."""
634 if self.sock:
Tim Peters07e99cb2001-01-14 23:47:14 +0000635 self.sock.close() # close it manually... there may be other refs
Greg Steindd6eefb2000-07-18 09:09:48 +0000636 self.sock = None
637 if self.__response:
638 self.__response.close()
639 self.__response = None
640 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000641
Greg Steindd6eefb2000-07-18 09:09:48 +0000642 def send(self, str):
643 """Send `str' to the server."""
644 if self.sock is None:
645 if self.auto_open:
646 self.connect()
647 else:
648 raise NotConnected()
Greg Stein5e0fa402000-06-26 08:28:01 +0000649
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000650 # send the data to the server. if we get a broken pipe, then close
Greg Steindd6eefb2000-07-18 09:09:48 +0000651 # the socket. we want to reconnect when somebody tries to send again.
652 #
653 # NOTE: we DO propagate the error, though, because we cannot simply
654 # ignore the error... the caller will know if they can retry.
Jeremy Hylton30f86742000-09-18 22:50:38 +0000655 if self.debuglevel > 0:
656 print "send:", repr(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000657 try:
Martin v. Löwise12454f2002-02-16 23:06:19 +0000658 self.sock.sendall(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000659 except socket.error, v:
Tim Peters07e99cb2001-01-14 23:47:14 +0000660 if v[0] == 32: # Broken pipe
Greg Steindd6eefb2000-07-18 09:09:48 +0000661 self.close()
662 raise
Greg Stein5e0fa402000-06-26 08:28:01 +0000663
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000664 def _output(self, s):
665 """Add a line of output to the current request buffer.
Tim Peters469cdad2002-08-08 20:19:19 +0000666
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000667 Assumes that the line does *not* end with \\r\\n.
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000668 """
669 self._buffer.append(s)
670
671 def _send_output(self):
672 """Send the currently buffered request and clear the buffer.
673
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000674 Appends an extra \\r\\n to the buffer.
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000675 """
676 self._buffer.extend(("", ""))
677 msg = "\r\n".join(self._buffer)
678 del self._buffer[:]
679 self.send(msg)
680
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000681 def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
Greg Steindd6eefb2000-07-18 09:09:48 +0000682 """Send a request to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000683
Greg Steindd6eefb2000-07-18 09:09:48 +0000684 `method' specifies an HTTP request method, e.g. 'GET'.
685 `url' specifies the object being requested, e.g. '/index.html'.
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000686 `skip_host' if True does not add automatically a 'Host:' header
687 `skip_accept_encoding' if True does not add automatically an
688 'Accept-Encoding:' header
Greg Steindd6eefb2000-07-18 09:09:48 +0000689 """
Greg Stein5e0fa402000-06-26 08:28:01 +0000690
Greg Stein616a58d2003-06-24 06:35:19 +0000691 # if a prior response has been completed, then forget about it.
Greg Steindd6eefb2000-07-18 09:09:48 +0000692 if self.__response and self.__response.isclosed():
693 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000694
Tim Peters58eb11c2004-01-18 20:29:55 +0000695
Greg Steindd6eefb2000-07-18 09:09:48 +0000696 # in certain cases, we cannot issue another request on this connection.
697 # this occurs when:
698 # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
699 # 2) a response to a previous request has signalled that it is going
700 # to close the connection upon completion.
701 # 3) the headers for the previous response have not been read, thus
702 # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
703 #
704 # if there is no prior response, then we can request at will.
705 #
706 # if point (2) is true, then we will have passed the socket to the
707 # response (effectively meaning, "there is no prior response"), and
708 # will open a new one when a new request is made.
709 #
710 # Note: if a prior response exists, then we *can* start a new request.
711 # We are not allowed to begin fetching the response to this new
712 # request, however, until that prior response is complete.
713 #
714 if self.__state == _CS_IDLE:
715 self.__state = _CS_REQ_STARTED
716 else:
717 raise CannotSendRequest()
Greg Stein5e0fa402000-06-26 08:28:01 +0000718
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000719 # Save the method we use, we need it later in the response phase
720 self._method = method
Greg Steindd6eefb2000-07-18 09:09:48 +0000721 if not url:
722 url = '/'
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000723 str = '%s %s %s' % (method, url, self._http_vsn_str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000724
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000725 self._output(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000726
Greg Steindd6eefb2000-07-18 09:09:48 +0000727 if self._http_vsn == 11:
728 # Issue some standard headers for better HTTP/1.1 compliance
Greg Stein5e0fa402000-06-26 08:28:01 +0000729
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000730 if not skip_host:
731 # this header is issued *only* for HTTP/1.1
732 # connections. more specifically, this means it is
733 # only issued when the client uses the new
734 # HTTPConnection() class. backwards-compat clients
735 # will be using HTTP/1.0 and those clients may be
736 # issuing this header themselves. we should NOT issue
737 # it twice; some web servers (such as Apache) barf
738 # when they see two Host: headers
Guido van Rossumf6922aa2001-01-14 21:03:01 +0000739
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000740 # If we need a non-standard port,include it in the
741 # header. If the request is going through a proxy,
742 # but the host of the actual URL, not the host of the
743 # proxy.
Jeremy Hylton8acf1e02002-03-08 19:35:51 +0000744
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000745 netloc = ''
746 if url.startswith('http'):
747 nil, netloc, nil, nil, nil = urlsplit(url)
748
749 if netloc:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000750 self.putheader('Host', netloc.encode("idna"))
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000751 elif self.port == HTTP_PORT:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000752 self.putheader('Host', self.host.encode("idna"))
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000753 else:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000754 self.putheader('Host', "%s:%s" % (self.host.encode("idna"), self.port))
Greg Stein5e0fa402000-06-26 08:28:01 +0000755
Greg Steindd6eefb2000-07-18 09:09:48 +0000756 # note: we are assuming that clients will not attempt to set these
757 # headers since *this* library must deal with the
758 # consequences. this also means that when the supporting
759 # libraries are updated to recognize other forms, then this
760 # code should be changed (removed or updated).
Greg Stein5e0fa402000-06-26 08:28:01 +0000761
Greg Steindd6eefb2000-07-18 09:09:48 +0000762 # we only want a Content-Encoding of "identity" since we don't
763 # support encodings such as x-gzip or x-deflate.
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000764 if not skip_accept_encoding:
765 self.putheader('Accept-Encoding', 'identity')
Greg Stein5e0fa402000-06-26 08:28:01 +0000766
Greg Steindd6eefb2000-07-18 09:09:48 +0000767 # we can accept "chunked" Transfer-Encodings, but no others
768 # NOTE: no TE header implies *only* "chunked"
769 #self.putheader('TE', 'chunked')
Greg Stein5e0fa402000-06-26 08:28:01 +0000770
Greg Steindd6eefb2000-07-18 09:09:48 +0000771 # if TE is supplied in the header, then it must appear in a
772 # Connection header.
773 #self.putheader('Connection', 'TE')
Greg Stein5e0fa402000-06-26 08:28:01 +0000774
Greg Steindd6eefb2000-07-18 09:09:48 +0000775 else:
776 # For HTTP/1.0, the server will assume "not chunked"
777 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000778
Greg Steindd6eefb2000-07-18 09:09:48 +0000779 def putheader(self, header, value):
780 """Send a request header line to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000781
Greg Steindd6eefb2000-07-18 09:09:48 +0000782 For example: h.putheader('Accept', 'text/html')
783 """
784 if self.__state != _CS_REQ_STARTED:
785 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000786
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000787 str = '%s: %s' % (header, value)
788 self._output(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000789
Greg Steindd6eefb2000-07-18 09:09:48 +0000790 def endheaders(self):
791 """Indicate that the last header line has been sent to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000792
Greg Steindd6eefb2000-07-18 09:09:48 +0000793 if self.__state == _CS_REQ_STARTED:
794 self.__state = _CS_REQ_SENT
795 else:
796 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000797
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000798 self._send_output()
Greg Stein5e0fa402000-06-26 08:28:01 +0000799
Greg Steindd6eefb2000-07-18 09:09:48 +0000800 def request(self, method, url, body=None, headers={}):
801 """Send a complete request to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000802
Greg Steindd6eefb2000-07-18 09:09:48 +0000803 try:
804 self._send_request(method, url, body, headers)
805 except socket.error, v:
806 # trap 'Broken pipe' if we're allowed to automatically reconnect
807 if v[0] != 32 or not self.auto_open:
808 raise
809 # try one more time
810 self._send_request(method, url, body, headers)
Greg Stein5e0fa402000-06-26 08:28:01 +0000811
Greg Steindd6eefb2000-07-18 09:09:48 +0000812 def _send_request(self, method, url, body, headers):
Jeremy Hylton2c178252004-08-07 16:28:14 +0000813 # honour explicitly requested Host: and Accept-Encoding headers
814 header_names = dict.fromkeys([k.lower() for k in headers])
815 skips = {}
816 if 'host' in header_names:
817 skips['skip_host'] = 1
818 if 'accept-encoding' in header_names:
819 skips['skip_accept_encoding'] = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000820
Jeremy Hylton2c178252004-08-07 16:28:14 +0000821 self.putrequest(method, url, **skips)
822
823 if body and ('content-length' not in header_names):
Greg Steindd6eefb2000-07-18 09:09:48 +0000824 self.putheader('Content-Length', str(len(body)))
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000825 for hdr, value in headers.iteritems():
Greg Steindd6eefb2000-07-18 09:09:48 +0000826 self.putheader(hdr, value)
827 self.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +0000828
Greg Steindd6eefb2000-07-18 09:09:48 +0000829 if body:
830 self.send(body)
Greg Stein5e0fa402000-06-26 08:28:01 +0000831
Greg Steindd6eefb2000-07-18 09:09:48 +0000832 def getresponse(self):
833 "Get the response from the server."
Greg Stein5e0fa402000-06-26 08:28:01 +0000834
Greg Stein616a58d2003-06-24 06:35:19 +0000835 # if a prior response has been completed, then forget about it.
Greg Steindd6eefb2000-07-18 09:09:48 +0000836 if self.__response and self.__response.isclosed():
837 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000838
Greg Steindd6eefb2000-07-18 09:09:48 +0000839 #
840 # if a prior response exists, then it must be completed (otherwise, we
841 # cannot read this response's header to determine the connection-close
842 # behavior)
843 #
844 # note: if a prior response existed, but was connection-close, then the
845 # socket and response were made independent of this HTTPConnection
846 # object since a new request requires that we open a whole new
847 # connection
848 #
849 # this means the prior response had one of two states:
850 # 1) will_close: this connection was reset and the prior socket and
851 # response operate independently
852 # 2) persistent: the response was retained and we await its
853 # isclosed() status to become true.
854 #
855 if self.__state != _CS_REQ_SENT or self.__response:
856 raise ResponseNotReady()
Greg Stein5e0fa402000-06-26 08:28:01 +0000857
Jeremy Hylton30f86742000-09-18 22:50:38 +0000858 if self.debuglevel > 0:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000859 response = self.response_class(self.sock, self.debuglevel,
Tim Petersc2659cf2003-05-12 20:19:37 +0000860 strict=self.strict,
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000861 method=self._method)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000862 else:
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000863 response = self.response_class(self.sock, strict=self.strict,
864 method=self._method)
Greg Stein5e0fa402000-06-26 08:28:01 +0000865
Jeremy Hylton39c03802002-07-12 14:04:09 +0000866 response.begin()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000867 assert response.will_close != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000868 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000869
Greg Steindd6eefb2000-07-18 09:09:48 +0000870 if response.will_close:
871 # this effectively passes the connection to the response
872 self.close()
873 else:
874 # remember this, so we can tell when it is complete
875 self.__response = response
Greg Stein5e0fa402000-06-26 08:28:01 +0000876
Greg Steindd6eefb2000-07-18 09:09:48 +0000877 return response
Greg Stein5e0fa402000-06-26 08:28:01 +0000878
Jeremy Hylton29d27ac2002-07-09 21:22:36 +0000879# The next several classes are used to define FakeSocket,a socket-like
880# interface to an SSL connection.
881
882# The primary complexity comes from faking a makefile() method. The
883# standard socket makefile() implementation calls dup() on the socket
884# file descriptor. As a consequence, clients can call close() on the
885# parent socket and its makefile children in any order. The underlying
886# socket isn't closed until they are all closed.
887
888# The implementation uses reference counting to keep the socket open
889# until the last client calls close(). SharedSocket keeps track of
890# the reference counting and SharedSocketClient provides an constructor
891# and close() method that call incref() and decref() correctly.
892
893class SharedSocket:
894
895 def __init__(self, sock):
896 self.sock = sock
897 self._refcnt = 0
898
899 def incref(self):
900 self._refcnt += 1
901
902 def decref(self):
903 self._refcnt -= 1
904 assert self._refcnt >= 0
905 if self._refcnt == 0:
906 self.sock.close()
907
908 def __del__(self):
909 self.sock.close()
910
911class SharedSocketClient:
912
913 def __init__(self, shared):
914 self._closed = 0
915 self._shared = shared
916 self._shared.incref()
917 self._sock = shared.sock
918
919 def close(self):
920 if not self._closed:
921 self._shared.decref()
922 self._closed = 1
923 self._shared = None
924
925class SSLFile(SharedSocketClient):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000926 """File-like object wrapping an SSL socket."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000927
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000928 BUFSIZE = 8192
Tim Petersc411dba2002-07-16 21:35:23 +0000929
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000930 def __init__(self, sock, ssl, bufsize=None):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +0000931 SharedSocketClient.__init__(self, sock)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000932 self._ssl = ssl
933 self._buf = ''
934 self._bufsize = bufsize or self.__class__.BUFSIZE
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000935
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000936 def _read(self):
937 buf = ''
938 # put in a loop so that we retry on transient errors
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000939 while True:
Greg Steindd6eefb2000-07-18 09:09:48 +0000940 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000941 buf = self._ssl.read(self._bufsize)
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000942 except socket.sslerror, err:
943 if (err[0] == socket.SSL_ERROR_WANT_READ
Neal Norwitz22c5d772002-02-11 17:59:51 +0000944 or err[0] == socket.SSL_ERROR_WANT_WRITE):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000945 continue
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000946 if (err[0] == socket.SSL_ERROR_ZERO_RETURN
947 or err[0] == socket.SSL_ERROR_EOF):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000948 break
949 raise
950 except socket.error, err:
Tim Petersf3623f32001-10-11 18:15:51 +0000951 if err[0] == errno.EINTR:
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000952 continue
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000953 if err[0] == errno.EBADF:
954 # XXX socket was closed?
955 break
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000956 raise
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000957 else:
Jeremy Hylton42dd01a2001-02-01 23:35:20 +0000958 break
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000959 return buf
960
961 def read(self, size=None):
962 L = [self._buf]
Raymond Hettinger49227682003-03-06 16:31:48 +0000963 avail = len(self._buf)
964 while size is None or avail < size:
965 s = self._read()
966 if s == '':
967 break
968 L.append(s)
969 avail += len(s)
970 all = "".join(L)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000971 if size is None:
972 self._buf = ''
Raymond Hettinger49227682003-03-06 16:31:48 +0000973 return all
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000974 else:
Raymond Hettinger49227682003-03-06 16:31:48 +0000975 self._buf = all[size:]
976 return all[:size]
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000977
978 def readline(self):
979 L = [self._buf]
980 self._buf = ''
Raymond Hettinger49227682003-03-06 16:31:48 +0000981 while 1:
982 i = L[-1].find("\n")
983 if i >= 0:
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000984 break
Raymond Hettinger49227682003-03-06 16:31:48 +0000985 s = self._read()
986 if s == '':
987 break
988 L.append(s)
989 if i == -1:
990 # loop exited because there is no more data
991 return "".join(L)
992 else:
993 all = "".join(L)
994 # XXX could do enough bookkeeping not to do a 2nd search
995 i = all.find("\n") + 1
996 line = all[:i]
997 self._buf = all[i:]
998 return line
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000999
Martin v. Löwis11892ec2003-10-27 14:07:53 +00001000 def readlines(self, sizehint=0):
1001 total = 0
1002 list = []
1003 while True:
1004 line = self.readline()
1005 if not line:
1006 break
1007 list.append(line)
1008 total += len(line)
1009 if sizehint and total >= sizehint:
1010 break
1011 return list
1012
1013 def fileno(self):
1014 return self._sock.fileno()
1015
1016 def __iter__(self):
1017 return self
1018
1019 def next(self):
1020 line = self.readline()
1021 if not line:
1022 raise StopIteration
1023 return line
1024
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001025class FakeSocket(SharedSocketClient):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001026
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001027 class _closedsocket:
1028 def __getattr__(self, name):
1029 raise error(9, 'Bad file descriptor')
1030
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001031 def __init__(self, sock, ssl):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001032 sock = SharedSocket(sock)
1033 SharedSocketClient.__init__(self, sock)
1034 self._ssl = ssl
1035
1036 def close(self):
1037 SharedSocketClient.close(self)
1038 self._sock = self.__class__._closedsocket()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001039
1040 def makefile(self, mode, bufsize=None):
1041 if mode != 'r' and mode != 'rb':
1042 raise UnimplementedFileMode()
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001043 return SSLFile(self._shared, self._ssl, bufsize)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001044
Greg Steindd6eefb2000-07-18 09:09:48 +00001045 def send(self, stuff, flags = 0):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001046 return self._ssl.write(stuff)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001047
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001048 sendall = send
Andrew M. Kuchlinga3c0b932002-03-18 22:51:48 +00001049
Greg Steindd6eefb2000-07-18 09:09:48 +00001050 def recv(self, len = 1024, flags = 0):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001051 return self._ssl.read(len)
Guido van Rossum23acc951994-02-21 16:36:04 +00001052
Greg Steindd6eefb2000-07-18 09:09:48 +00001053 def __getattr__(self, attr):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001054 return getattr(self._sock, attr)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001055
Guido van Rossum23acc951994-02-21 16:36:04 +00001056
Greg Stein5e0fa402000-06-26 08:28:01 +00001057class HTTPSConnection(HTTPConnection):
Greg Steindd6eefb2000-07-18 09:09:48 +00001058 "This class allows communication via SSL."
Greg Stein5e0fa402000-06-26 08:28:01 +00001059
Greg Steindd6eefb2000-07-18 09:09:48 +00001060 default_port = HTTPS_PORT
Greg Stein5e0fa402000-06-26 08:28:01 +00001061
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001062 def __init__(self, host, port=None, key_file=None, cert_file=None,
1063 strict=None):
1064 HTTPConnection.__init__(self, host, port, strict)
Jeremy Hylton7c75c992002-06-28 23:38:14 +00001065 self.key_file = key_file
1066 self.cert_file = cert_file
Greg Stein5e0fa402000-06-26 08:28:01 +00001067
Greg Steindd6eefb2000-07-18 09:09:48 +00001068 def connect(self):
1069 "Connect to a host on a given (SSL) port."
Greg Stein5e0fa402000-06-26 08:28:01 +00001070
Greg Steindd6eefb2000-07-18 09:09:48 +00001071 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1072 sock.connect((self.host, self.port))
Martin v. Löwis1867f242003-06-14 13:30:53 +00001073 ssl = socket.ssl(sock, self.key_file, self.cert_file)
Greg Steindd6eefb2000-07-18 09:09:48 +00001074 self.sock = FakeSocket(sock, ssl)
Greg Stein5e0fa402000-06-26 08:28:01 +00001075
1076
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001077class HTTP:
Greg Steindd6eefb2000-07-18 09:09:48 +00001078 "Compatibility class with httplib.py from 1.5."
Greg Stein5e0fa402000-06-26 08:28:01 +00001079
Greg Steindd6eefb2000-07-18 09:09:48 +00001080 _http_vsn = 10
1081 _http_vsn_str = 'HTTP/1.0'
Greg Stein5e0fa402000-06-26 08:28:01 +00001082
Greg Steindd6eefb2000-07-18 09:09:48 +00001083 debuglevel = 0
Greg Stein5e0fa402000-06-26 08:28:01 +00001084
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001085 _connection_class = HTTPConnection
1086
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001087 def __init__(self, host='', port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +00001088 "Provide a default host, since the superclass requires one."
Greg Stein5e0fa402000-06-26 08:28:01 +00001089
Greg Steindd6eefb2000-07-18 09:09:48 +00001090 # some joker passed 0 explicitly, meaning default port
1091 if port == 0:
1092 port = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001093
Greg Steindd6eefb2000-07-18 09:09:48 +00001094 # Note that we may pass an empty string as the host; this will throw
1095 # an error when we attempt to connect. Presumably, the client code
1096 # will call connect before then, with a proper host.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001097 self._setup(self._connection_class(host, port, strict))
Greg Stein5e0fa402000-06-26 08:28:01 +00001098
Greg Stein81937a42001-08-18 09:20:23 +00001099 def _setup(self, conn):
1100 self._conn = conn
1101
1102 # set up delegation to flesh out interface
1103 self.send = conn.send
1104 self.putrequest = conn.putrequest
1105 self.endheaders = conn.endheaders
1106 self.set_debuglevel = conn.set_debuglevel
1107
1108 conn._http_vsn = self._http_vsn
1109 conn._http_vsn_str = self._http_vsn_str
Greg Stein5e0fa402000-06-26 08:28:01 +00001110
Greg Steindd6eefb2000-07-18 09:09:48 +00001111 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001112
Greg Steindd6eefb2000-07-18 09:09:48 +00001113 def connect(self, host=None, port=None):
1114 "Accept arguments to set the host/port, since the superclass doesn't."
Greg Stein5e0fa402000-06-26 08:28:01 +00001115
Greg Steindd6eefb2000-07-18 09:09:48 +00001116 if host is not None:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001117 self._conn._set_hostport(host, port)
1118 self._conn.connect()
Greg Stein5e0fa402000-06-26 08:28:01 +00001119
Greg Steindd6eefb2000-07-18 09:09:48 +00001120 def getfile(self):
1121 "Provide a getfile, since the superclass' does not use this concept."
1122 return self.file
Greg Stein5e0fa402000-06-26 08:28:01 +00001123
Greg Steindd6eefb2000-07-18 09:09:48 +00001124 def putheader(self, header, *values):
1125 "The superclass allows only one value argument."
Guido van Rossum34735a62000-12-15 15:09:42 +00001126 self._conn.putheader(header, '\r\n\t'.join(values))
Greg Stein5e0fa402000-06-26 08:28:01 +00001127
Greg Steindd6eefb2000-07-18 09:09:48 +00001128 def getreply(self):
1129 """Compat definition since superclass does not define it.
Greg Stein5e0fa402000-06-26 08:28:01 +00001130
Greg Steindd6eefb2000-07-18 09:09:48 +00001131 Returns a tuple consisting of:
1132 - server status code (e.g. '200' if all goes well)
1133 - server "reason" corresponding to status code
1134 - any RFC822 headers in the response from the server
1135 """
1136 try:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001137 response = self._conn.getresponse()
Greg Steindd6eefb2000-07-18 09:09:48 +00001138 except BadStatusLine, e:
1139 ### hmm. if getresponse() ever closes the socket on a bad request,
1140 ### then we are going to have problems with self.sock
Greg Stein5e0fa402000-06-26 08:28:01 +00001141
Greg Steindd6eefb2000-07-18 09:09:48 +00001142 ### should we keep this behavior? do people use it?
1143 # keep the socket open (as a file), and return it
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001144 self.file = self._conn.sock.makefile('rb', 0)
Greg Stein5e0fa402000-06-26 08:28:01 +00001145
Greg Steindd6eefb2000-07-18 09:09:48 +00001146 # close our socket -- we want to restart after any protocol error
1147 self.close()
Greg Stein5e0fa402000-06-26 08:28:01 +00001148
Greg Steindd6eefb2000-07-18 09:09:48 +00001149 self.headers = None
1150 return -1, e.line, None
Greg Stein5e0fa402000-06-26 08:28:01 +00001151
Greg Steindd6eefb2000-07-18 09:09:48 +00001152 self.headers = response.msg
1153 self.file = response.fp
1154 return response.status, response.reason, response.msg
Greg Stein5e0fa402000-06-26 08:28:01 +00001155
Greg Steindd6eefb2000-07-18 09:09:48 +00001156 def close(self):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001157 self._conn.close()
Greg Stein5e0fa402000-06-26 08:28:01 +00001158
Greg Steindd6eefb2000-07-18 09:09:48 +00001159 # note that self.file == response.fp, which gets closed by the
1160 # superclass. just clear the object ref here.
1161 ### hmm. messy. if status==-1, then self.file is owned by us.
1162 ### well... we aren't explicitly closing, but losing this ref will
1163 ### do it
1164 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001165
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001166if hasattr(socket, 'ssl'):
1167 class HTTPS(HTTP):
1168 """Compatibility with 1.5 httplib interface
1169
1170 Python 1.5.2 did not have an HTTPS class, but it defined an
1171 interface for sending http requests that is also useful for
Tim Peters5ceadc82001-01-13 19:16:21 +00001172 https.
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001173 """
1174
Martin v. Löwisd7bf9742000-09-21 22:09:47 +00001175 _connection_class = HTTPSConnection
Tim Peters5ceadc82001-01-13 19:16:21 +00001176
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001177 def __init__(self, host='', port=None, key_file=None, cert_file=None,
1178 strict=None):
Greg Stein81937a42001-08-18 09:20:23 +00001179 # provide a default host, pass the X509 cert info
1180
1181 # urf. compensate for bad input.
1182 if port == 0:
1183 port = None
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001184 self._setup(self._connection_class(host, port, key_file,
1185 cert_file, strict))
Greg Stein81937a42001-08-18 09:20:23 +00001186
1187 # we never actually use these for anything, but we keep them
1188 # here for compatibility with post-1.5.2 CVS.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001189 self.key_file = key_file
1190 self.cert_file = cert_file
Greg Stein81937a42001-08-18 09:20:23 +00001191
Greg Stein5e0fa402000-06-26 08:28:01 +00001192
1193class HTTPException(Exception):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001194 # Subclasses that define an __init__ must call Exception.__init__
1195 # or define self.args. Otherwise, str() will fail.
Greg Steindd6eefb2000-07-18 09:09:48 +00001196 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001197
1198class NotConnected(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001199 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001200
Skip Montanaro9d389972002-03-24 16:53:50 +00001201class InvalidURL(HTTPException):
1202 pass
1203
Greg Stein5e0fa402000-06-26 08:28:01 +00001204class UnknownProtocol(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001205 def __init__(self, version):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001206 self.args = version,
Greg Steindd6eefb2000-07-18 09:09:48 +00001207 self.version = version
Greg Stein5e0fa402000-06-26 08:28:01 +00001208
1209class UnknownTransferEncoding(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001210 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001211
Greg Stein5e0fa402000-06-26 08:28:01 +00001212class UnimplementedFileMode(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001213 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001214
1215class IncompleteRead(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001216 def __init__(self, partial):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001217 self.args = partial,
Greg Steindd6eefb2000-07-18 09:09:48 +00001218 self.partial = partial
Greg Stein5e0fa402000-06-26 08:28:01 +00001219
1220class ImproperConnectionState(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001221 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001222
1223class CannotSendRequest(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001224 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001225
1226class CannotSendHeader(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001227 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001228
1229class ResponseNotReady(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001230 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001231
1232class BadStatusLine(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001233 def __init__(self, line):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001234 self.args = line,
Greg Steindd6eefb2000-07-18 09:09:48 +00001235 self.line = line
Greg Stein5e0fa402000-06-26 08:28:01 +00001236
1237# for backwards compatibility
1238error = HTTPException
1239
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001240class LineAndFileWrapper:
1241 """A limited file-like object for HTTP/0.9 responses."""
1242
1243 # The status-line parsing code calls readline(), which normally
1244 # get the HTTP status line. For a 0.9 response, however, this is
1245 # actually the first line of the body! Clients need to get a
1246 # readable file object that contains that line.
1247
1248 def __init__(self, line, file):
1249 self._line = line
1250 self._file = file
1251 self._line_consumed = 0
1252 self._line_offset = 0
1253 self._line_left = len(line)
1254
1255 def __getattr__(self, attr):
1256 return getattr(self._file, attr)
1257
1258 def _done(self):
1259 # called when the last byte is read from the line. After the
1260 # call, all read methods are delegated to the underlying file
Skip Montanaro74b9a7a2003-02-25 17:48:15 +00001261 # object.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001262 self._line_consumed = 1
1263 self.read = self._file.read
1264 self.readline = self._file.readline
1265 self.readlines = self._file.readlines
1266
1267 def read(self, amt=None):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001268 if self._line_consumed:
1269 return self._file.read(amt)
1270 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001271 if amt is None or amt > self._line_left:
1272 s = self._line[self._line_offset:]
1273 self._done()
1274 if amt is None:
1275 return s + self._file.read()
1276 else:
Tim Petersc411dba2002-07-16 21:35:23 +00001277 return s + self._file.read(amt - len(s))
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001278 else:
1279 assert amt <= self._line_left
1280 i = self._line_offset
1281 j = i + amt
1282 s = self._line[i:j]
1283 self._line_offset = j
1284 self._line_left -= amt
1285 if self._line_left == 0:
1286 self._done()
1287 return s
Tim Petersc411dba2002-07-16 21:35:23 +00001288
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001289 def readline(self):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001290 if self._line_consumed:
1291 return self._file.readline()
1292 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001293 s = self._line[self._line_offset:]
1294 self._done()
1295 return s
1296
1297 def readlines(self, size=None):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001298 if self._line_consumed:
1299 return self._file.readlines(size)
1300 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001301 L = [self._line[self._line_offset:]]
1302 self._done()
1303 if size is None:
1304 return L + self._file.readlines()
1305 else:
1306 return L + self._file.readlines(size)
Greg Stein5e0fa402000-06-26 08:28:01 +00001307
Guido van Rossum23acc951994-02-21 16:36:04 +00001308def test():
Guido van Rossum41999c11997-12-09 00:12:23 +00001309 """Test this module.
1310
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001311 A hodge podge of tests collected here, because they have too many
1312 external dependencies for the regular test suite.
Guido van Rossum41999c11997-12-09 00:12:23 +00001313 """
Greg Stein5e0fa402000-06-26 08:28:01 +00001314
Guido van Rossum41999c11997-12-09 00:12:23 +00001315 import sys
1316 import getopt
1317 opts, args = getopt.getopt(sys.argv[1:], 'd')
1318 dl = 0
1319 for o, a in opts:
1320 if o == '-d': dl = dl + 1
1321 host = 'www.python.org'
1322 selector = '/'
1323 if args[0:]: host = args[0]
1324 if args[1:]: selector = args[1]
1325 h = HTTP()
1326 h.set_debuglevel(dl)
1327 h.connect(host)
1328 h.putrequest('GET', selector)
1329 h.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +00001330 status, reason, headers = h.getreply()
1331 print 'status =', status
1332 print 'reason =', reason
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001333 print "read", len(h.getfile().read())
Guido van Rossum41999c11997-12-09 00:12:23 +00001334 print
1335 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +00001336 for header in headers.headers: print header.strip()
Guido van Rossum41999c11997-12-09 00:12:23 +00001337 print
Greg Stein5e0fa402000-06-26 08:28:01 +00001338
Jeremy Hylton8acf1e02002-03-08 19:35:51 +00001339 # minimal test that code to extract host from url works
1340 class HTTP11(HTTP):
1341 _http_vsn = 11
1342 _http_vsn_str = 'HTTP/1.1'
1343
1344 h = HTTP11('www.python.org')
1345 h.putrequest('GET', 'http://www.python.org/~jeremy/')
1346 h.endheaders()
1347 h.getreply()
1348 h.close()
1349
Greg Stein5e0fa402000-06-26 08:28:01 +00001350 if hasattr(socket, 'ssl'):
Tim Petersc411dba2002-07-16 21:35:23 +00001351
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001352 for host, selector in (('sourceforge.net', '/projects/python'),
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001353 ):
1354 print "https://%s%s" % (host, selector)
1355 hs = HTTPS()
Jeremy Hylton8531b1b2002-07-16 21:21:11 +00001356 hs.set_debuglevel(dl)
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001357 hs.connect(host)
1358 hs.putrequest('GET', selector)
1359 hs.endheaders()
1360 status, reason, headers = hs.getreply()
1361 print 'status =', status
1362 print 'reason =', reason
1363 print "read", len(hs.getfile().read())
1364 print
1365 if headers:
1366 for header in headers.headers: print header.strip()
1367 print
Guido van Rossum23acc951994-02-21 16:36:04 +00001368
Guido van Rossum23acc951994-02-21 16:36:04 +00001369if __name__ == '__main__':
Guido van Rossum41999c11997-12-09 00:12:23 +00001370 test()