blob: e017cdfcd519e4df19270e2d9b1c23ae4c095a06 [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
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000156class HTTPMessage(mimetools.Message):
157
158 def addheader(self, key, value):
159 """Add header for field key handling repeats."""
160 prev = self.dict.get(key)
161 if prev is None:
162 self.dict[key] = value
163 else:
164 combined = ", ".join((prev, value))
165 self.dict[key] = combined
166
167 def addcontinue(self, key, more):
168 """Add more field data from a continuation line."""
169 prev = self.dict[key]
170 self.dict[key] = prev + "\n " + more
171
172 def readheaders(self):
173 """Read header lines.
174
175 Read header lines up to the entirely blank line that terminates them.
176 The (normally blank) line that ends the headers is skipped, but not
177 included in the returned list. If a non-header line ends the headers,
178 (which is an error), an attempt is made to backspace over it; it is
179 never included in the returned list.
180
181 The variable self.status is set to the empty string if all went well,
182 otherwise it is an error message. The variable self.headers is a
183 completely uninterpreted list of lines contained in the header (so
184 printing them will reproduce the header exactly as it appears in the
185 file).
186
187 If multiple header fields with the same name occur, they are combined
188 according to the rules in RFC 2616 sec 4.2:
189
190 Appending each subsequent field-value to the first, each separated
191 by a comma. The order in which header fields with the same field-name
192 are received is significant to the interpretation of the combined
193 field value.
194 """
195 # XXX The implementation overrides the readheaders() method of
196 # rfc822.Message. The base class design isn't amenable to
197 # customized behavior here so the method here is a copy of the
198 # base class code with a few small changes.
199
200 self.dict = {}
201 self.unixfrom = ''
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000202 self.headers = hlist = []
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000203 self.status = ''
204 headerseen = ""
205 firstline = 1
206 startofline = unread = tell = None
207 if hasattr(self.fp, 'unread'):
208 unread = self.fp.unread
209 elif self.seekable:
210 tell = self.fp.tell
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000211 while True:
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000212 if tell:
213 try:
214 startofline = tell()
215 except IOError:
216 startofline = tell = None
217 self.seekable = 0
218 line = self.fp.readline()
219 if not line:
220 self.status = 'EOF in headers'
221 break
222 # Skip unix From name time lines
223 if firstline and line.startswith('From '):
224 self.unixfrom = self.unixfrom + line
225 continue
226 firstline = 0
227 if headerseen and line[0] in ' \t':
228 # XXX Not sure if continuation lines are handled properly
229 # for http and/or for repeating headers
230 # It's a continuation line.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000231 hlist.append(line)
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000232 self.addcontinue(headerseen, line.strip())
233 continue
234 elif self.iscomment(line):
235 # It's a comment. Ignore it.
236 continue
237 elif self.islast(line):
238 # Note! No pushback here! The delimiter line gets eaten.
239 break
240 headerseen = self.isheader(line)
241 if headerseen:
242 # It's a legal header line, save it.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000243 hlist.append(line)
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000244 self.addheader(headerseen, line[len(headerseen)+1:].strip())
245 continue
246 else:
247 # It's not a header line; throw it back and stop here.
248 if not self.dict:
249 self.status = 'No headers'
250 else:
251 self.status = 'Non-header line where header expected'
252 # Try to undo the read.
253 if unread:
254 unread(line)
255 elif tell:
256 self.fp.seek(startofline)
257 else:
258 self.status = self.status + '; bad seek'
259 break
Greg Stein5e0fa402000-06-26 08:28:01 +0000260
261class HTTPResponse:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000262
263 # strict: If true, raise BadStatusLine if the status line can't be
264 # parsed as a valid HTTP/1.0 or 1.1 status line. By default it is
Skip Montanaro186bec22002-07-25 16:10:38 +0000265 # false because it prevents clients from talking to HTTP/0.9
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000266 # servers. Note that a response with a sufficiently corrupted
267 # status line will look like an HTTP/0.9 response.
268
269 # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
270
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000271 def __init__(self, sock, debuglevel=0, strict=0, method=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000272 self.fp = sock.makefile('rb', 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000273 self.debuglevel = debuglevel
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000274 self.strict = strict
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000275 self._method = method
Greg Stein5e0fa402000-06-26 08:28:01 +0000276
Greg Steindd6eefb2000-07-18 09:09:48 +0000277 self.msg = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000278
Greg Steindd6eefb2000-07-18 09:09:48 +0000279 # from the Status-Line of the response
Tim Peters07e99cb2001-01-14 23:47:14 +0000280 self.version = _UNKNOWN # HTTP-Version
281 self.status = _UNKNOWN # Status-Code
282 self.reason = _UNKNOWN # Reason-Phrase
Greg Stein5e0fa402000-06-26 08:28:01 +0000283
Tim Peters07e99cb2001-01-14 23:47:14 +0000284 self.chunked = _UNKNOWN # is "chunked" being used?
285 self.chunk_left = _UNKNOWN # bytes left to read in current chunk
286 self.length = _UNKNOWN # number of bytes left in response
287 self.will_close = _UNKNOWN # conn will close at end of response
Greg Stein5e0fa402000-06-26 08:28:01 +0000288
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000289 def _read_status(self):
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000290 # Initialize with Simple-Response defaults
Greg Stein5e0fa402000-06-26 08:28:01 +0000291 line = self.fp.readline()
Jeremy Hylton30f86742000-09-18 22:50:38 +0000292 if self.debuglevel > 0:
293 print "reply:", repr(line)
Jeremy Hyltonb6769522003-06-29 17:55:05 +0000294 if not line:
295 # Presumably, the server closed the connection before
296 # sending a valid response.
297 raise BadStatusLine(line)
Greg Steindd6eefb2000-07-18 09:09:48 +0000298 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000299 [version, status, reason] = line.split(None, 2)
Greg Steindd6eefb2000-07-18 09:09:48 +0000300 except ValueError:
301 try:
Guido van Rossum34735a62000-12-15 15:09:42 +0000302 [version, status] = line.split(None, 1)
Greg Steindd6eefb2000-07-18 09:09:48 +0000303 reason = ""
304 except ValueError:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000305 # empty version will cause next test to fail and status
306 # will be treated as 0.9 response.
307 version = ""
308 if not version.startswith('HTTP/'):
309 if self.strict:
310 self.close()
311 raise BadStatusLine(line)
312 else:
313 # assume it's a Simple-Response from an 0.9 server
314 self.fp = LineAndFileWrapper(line, self.fp)
315 return "HTTP/0.9", 200, ""
Greg Stein5e0fa402000-06-26 08:28:01 +0000316
Jeremy Hylton23d40472001-04-13 14:57:08 +0000317 # The status code is a three-digit number
318 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000319 status = int(status)
Jeremy Hylton23d40472001-04-13 14:57:08 +0000320 if status < 100 or status > 999:
321 raise BadStatusLine(line)
322 except ValueError:
323 raise BadStatusLine(line)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000324 return version, status, reason
Greg Stein5e0fa402000-06-26 08:28:01 +0000325
Jeremy Hylton39c03802002-07-12 14:04:09 +0000326 def begin(self):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000327 if self.msg is not None:
328 # we've already started reading the response
329 return
330
331 # read until we get a non-100 response
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000332 while True:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000333 version, status, reason = self._read_status()
Martin v. Löwis39a31782004-09-18 09:03:49 +0000334 if status != CONTINUE:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000335 break
336 # skip the header from the 100 response
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000337 while True:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000338 skip = self.fp.readline().strip()
339 if not skip:
340 break
341 if self.debuglevel > 0:
342 print "header:", skip
Tim Petersc411dba2002-07-16 21:35:23 +0000343
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000344 self.status = status
345 self.reason = reason.strip()
Greg Steindd6eefb2000-07-18 09:09:48 +0000346 if version == 'HTTP/1.0':
347 self.version = 10
Jeremy Hylton110941a2000-10-12 19:58:36 +0000348 elif version.startswith('HTTP/1.'):
Tim Peters07e99cb2001-01-14 23:47:14 +0000349 self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
Jeremy Hylton110941a2000-10-12 19:58:36 +0000350 elif version == 'HTTP/0.9':
351 self.version = 9
Greg Steindd6eefb2000-07-18 09:09:48 +0000352 else:
353 raise UnknownProtocol(version)
Greg Stein5e0fa402000-06-26 08:28:01 +0000354
Jeremy Hylton110941a2000-10-12 19:58:36 +0000355 if self.version == 9:
Georg Brandl0aade9a2005-06-26 22:06:54 +0000356 self.length = None
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000357 self.chunked = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000358 self.will_close = 1
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000359 self.msg = HTTPMessage(StringIO())
Jeremy Hylton110941a2000-10-12 19:58:36 +0000360 return
361
Jeremy Hylton6d0a4c72002-07-07 16:51:37 +0000362 self.msg = HTTPMessage(self.fp, 0)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000363 if self.debuglevel > 0:
364 for hdr in self.msg.headers:
365 print "header:", hdr,
Greg Stein5e0fa402000-06-26 08:28:01 +0000366
Greg Steindd6eefb2000-07-18 09:09:48 +0000367 # don't let the msg keep an fp
368 self.msg.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000369
Greg Steindd6eefb2000-07-18 09:09:48 +0000370 # are we using the chunked-style of transfer encoding?
371 tr_enc = self.msg.getheader('transfer-encoding')
Jeremy Hyltond229b3a2002-09-03 19:24:24 +0000372 if tr_enc and tr_enc.lower() == "chunked":
Greg Steindd6eefb2000-07-18 09:09:48 +0000373 self.chunked = 1
374 self.chunk_left = None
375 else:
376 self.chunked = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000377
Greg Steindd6eefb2000-07-18 09:09:48 +0000378 # will the connection close at the end of the response?
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000379 self.will_close = self._check_close()
Greg Stein5e0fa402000-06-26 08:28:01 +0000380
Greg Steindd6eefb2000-07-18 09:09:48 +0000381 # do we have a Content-Length?
382 # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
383 length = self.msg.getheader('content-length')
384 if length and not self.chunked:
Jeremy Hylton30a81812000-09-14 20:34:27 +0000385 try:
386 self.length = int(length)
387 except ValueError:
388 self.length = None
Greg Steindd6eefb2000-07-18 09:09:48 +0000389 else:
390 self.length = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000391
Greg Steindd6eefb2000-07-18 09:09:48 +0000392 # does the body have a fixed length? (of zero)
Martin v. Löwis39a31782004-09-18 09:03:49 +0000393 if (status == NO_CONTENT or status == NOT_MODIFIED or
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000394 100 <= status < 200 or # 1xx codes
395 self._method == 'HEAD'):
Greg Steindd6eefb2000-07-18 09:09:48 +0000396 self.length = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000397
Greg Steindd6eefb2000-07-18 09:09:48 +0000398 # if the connection remains open, and we aren't using chunked, and
399 # a content-length was not provided, then assume that the connection
400 # WILL close.
401 if not self.will_close and \
402 not self.chunked and \
403 self.length is None:
404 self.will_close = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000405
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000406 def _check_close(self):
Jeremy Hylton2c178252004-08-07 16:28:14 +0000407 conn = self.msg.getheader('connection')
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000408 if self.version == 11:
409 # An HTTP/1.1 proxy is assumed to stay open unless
410 # explicitly closed.
411 conn = self.msg.getheader('connection')
Raymond Hettingerbac788a2004-05-04 09:21:43 +0000412 if conn and "close" in conn.lower():
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000413 return True
414 return False
415
Jeremy Hylton2c178252004-08-07 16:28:14 +0000416 # Some HTTP/1.0 implementations have support for persistent
417 # connections, using rules different than HTTP/1.1.
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000418
419 # For older HTTP, Keep-Alive indiciates persistent connection.
420 if self.msg.getheader('keep-alive'):
421 return False
Tim Peters77c06fb2002-11-24 02:35:35 +0000422
Jeremy Hylton2c178252004-08-07 16:28:14 +0000423 # At least Akamai returns a "Connection: Keep-Alive" header,
424 # which was supposed to be sent by the client.
425 if conn and "keep-alive" in conn.lower():
426 return False
427
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000428 # Proxy-Connection is a netscape hack.
429 pconn = self.msg.getheader('proxy-connection')
Raymond Hettingerbac788a2004-05-04 09:21:43 +0000430 if pconn and "keep-alive" in pconn.lower():
Jeremy Hylton22b3a492002-11-13 17:27:43 +0000431 return False
432
433 # otherwise, assume it will close
434 return True
435
Greg Steindd6eefb2000-07-18 09:09:48 +0000436 def close(self):
437 if self.fp:
438 self.fp.close()
439 self.fp = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000440
Greg Steindd6eefb2000-07-18 09:09:48 +0000441 def isclosed(self):
442 # NOTE: it is possible that we will not ever call self.close(). This
443 # case occurs when will_close is TRUE, length is None, and we
444 # read up to the last byte, but NOT past it.
445 #
446 # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
447 # called, meaning self.isclosed() is meaningful.
448 return self.fp is None
449
Jeremy Hylton2c178252004-08-07 16:28:14 +0000450 # XXX It would be nice to have readline and __iter__ for this, too.
451
Greg Steindd6eefb2000-07-18 09:09:48 +0000452 def read(self, amt=None):
453 if self.fp is None:
454 return ''
455
456 if self.chunked:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000457 return self._read_chunked(amt)
Tim Peters230a60c2002-11-09 05:08:07 +0000458
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000459 if amt is None:
Greg Steindd6eefb2000-07-18 09:09:48 +0000460 # unbounded read
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000461 if self.length is None:
Greg Steindd6eefb2000-07-18 09:09:48 +0000462 s = self.fp.read()
463 else:
464 s = self._safe_read(self.length)
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000465 self.length = 0
Tim Peters07e99cb2001-01-14 23:47:14 +0000466 self.close() # we read everything
Greg Steindd6eefb2000-07-18 09:09:48 +0000467 return s
468
469 if self.length is not None:
470 if amt > self.length:
471 # clip the read to the "end of response"
472 amt = self.length
Greg Steindd6eefb2000-07-18 09:09:48 +0000473
474 # we do not use _safe_read() here because this may be a .will_close
475 # connection, and the user is reading more bytes than will be provided
476 # (for example, reading in 1k chunks)
477 s = self.fp.read(amt)
Jeremy Hyltondef9d2a2004-11-07 16:13:49 +0000478 if self.length is not None:
479 self.length -= len(s)
Greg Steindd6eefb2000-07-18 09:09:48 +0000480
Greg Steindd6eefb2000-07-18 09:09:48 +0000481 return s
482
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000483 def _read_chunked(self, amt):
484 assert self.chunked != _UNKNOWN
485 chunk_left = self.chunk_left
486 value = ''
487
488 # XXX This accumulates chunks by repeated string concatenation,
489 # which is not efficient as the number or size of chunks gets big.
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000490 while True:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000491 if chunk_left is None:
492 line = self.fp.readline()
493 i = line.find(';')
494 if i >= 0:
495 line = line[:i] # strip chunk-extensions
496 chunk_left = int(line, 16)
497 if chunk_left == 0:
498 break
499 if amt is None:
500 value += self._safe_read(chunk_left)
501 elif amt < chunk_left:
502 value += self._safe_read(amt)
503 self.chunk_left = chunk_left - amt
504 return value
505 elif amt == chunk_left:
506 value += self._safe_read(amt)
507 self._safe_read(2) # toss the CRLF at the end of the chunk
508 self.chunk_left = None
509 return value
510 else:
511 value += self._safe_read(chunk_left)
512 amt -= chunk_left
513
514 # we read the whole chunk, get another
515 self._safe_read(2) # toss the CRLF at the end of the chunk
516 chunk_left = None
517
518 # read and discard trailer up to the CRLF terminator
519 ### note: we shouldn't have any trailers!
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000520 while True:
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000521 line = self.fp.readline()
522 if line == '\r\n':
523 break
524
525 # we read everything; close the "file"
Jeremy Hyltond4c472c2002-09-03 20:49:06 +0000526 self.close()
527
528 return value
Tim Peters230a60c2002-11-09 05:08:07 +0000529
Greg Steindd6eefb2000-07-18 09:09:48 +0000530 def _safe_read(self, amt):
531 """Read the number of bytes requested, compensating for partial reads.
532
533 Normally, we have a blocking socket, but a read() can be interrupted
534 by a signal (resulting in a partial read).
535
536 Note that we cannot distinguish between EOF and an interrupt when zero
537 bytes have been read. IncompleteRead() will be raised in this
538 situation.
539
540 This function should be used when <amt> bytes "should" be present for
541 reading. If the bytes are truly not available (due to EOF), then the
542 IncompleteRead exception can be used to detect the problem.
543 """
544 s = ''
545 while amt > 0:
546 chunk = self.fp.read(amt)
547 if not chunk:
548 raise IncompleteRead(s)
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000549 s += chunk
550 amt -= len(chunk)
Greg Steindd6eefb2000-07-18 09:09:48 +0000551 return s
552
553 def getheader(self, name, default=None):
554 if self.msg is None:
555 raise ResponseNotReady()
556 return self.msg.getheader(name, default)
Greg Stein5e0fa402000-06-26 08:28:01 +0000557
Martin v. Löwisdeacce22004-08-18 12:46:26 +0000558 def getheaders(self):
559 """Return list of (header, value) tuples."""
560 if self.msg is None:
561 raise ResponseNotReady()
562 return self.msg.items()
563
Greg Stein5e0fa402000-06-26 08:28:01 +0000564
565class HTTPConnection:
566
Greg Steindd6eefb2000-07-18 09:09:48 +0000567 _http_vsn = 11
568 _http_vsn_str = 'HTTP/1.1'
Greg Stein5e0fa402000-06-26 08:28:01 +0000569
Greg Steindd6eefb2000-07-18 09:09:48 +0000570 response_class = HTTPResponse
571 default_port = HTTP_PORT
572 auto_open = 1
Jeremy Hylton30f86742000-09-18 22:50:38 +0000573 debuglevel = 0
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000574 strict = 0
Greg Stein5e0fa402000-06-26 08:28:01 +0000575
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000576 def __init__(self, host, port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +0000577 self.sock = None
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000578 self._buffer = []
Greg Steindd6eefb2000-07-18 09:09:48 +0000579 self.__response = None
580 self.__state = _CS_IDLE
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000581 self._method = None
Tim Petersc411dba2002-07-16 21:35:23 +0000582
Greg Steindd6eefb2000-07-18 09:09:48 +0000583 self._set_hostport(host, port)
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000584 if strict is not None:
585 self.strict = strict
Greg Stein5e0fa402000-06-26 08:28:01 +0000586
Greg Steindd6eefb2000-07-18 09:09:48 +0000587 def _set_hostport(self, host, port):
588 if port is None:
Skip Montanaro10e6e0e2004-09-14 16:32:02 +0000589 i = host.rfind(':')
Skip Montanarocae14d22004-09-14 17:55:21 +0000590 j = host.rfind(']') # ipv6 addresses have [...]
591 if i > j:
Skip Montanaro9d389972002-03-24 16:53:50 +0000592 try:
593 port = int(host[i+1:])
594 except ValueError:
Jeremy Hyltonfbd79942002-07-02 20:19:08 +0000595 raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
Greg Steindd6eefb2000-07-18 09:09:48 +0000596 host = host[:i]
597 else:
598 port = self.default_port
Raymond Hettinger4d037912004-10-14 15:23:38 +0000599 if host and host[0] == '[' and host[-1] == ']':
Brett Cannon0a1af4a2004-09-15 23:26:23 +0000600 host = host[1:-1]
Greg Steindd6eefb2000-07-18 09:09:48 +0000601 self.host = host
602 self.port = port
Greg Stein5e0fa402000-06-26 08:28:01 +0000603
Jeremy Hylton30f86742000-09-18 22:50:38 +0000604 def set_debuglevel(self, level):
605 self.debuglevel = level
606
Greg Steindd6eefb2000-07-18 09:09:48 +0000607 def connect(self):
608 """Connect to the host and port specified in __init__."""
Martin v. Löwis2ad25692001-07-31 08:40:21 +0000609 msg = "getaddrinfo returns an empty list"
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000610 for res in socket.getaddrinfo(self.host, self.port, 0,
611 socket.SOCK_STREAM):
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000612 af, socktype, proto, canonname, sa = res
613 try:
614 self.sock = socket.socket(af, socktype, proto)
615 if self.debuglevel > 0:
616 print "connect: (%s, %s)" % (self.host, self.port)
617 self.sock.connect(sa)
618 except socket.error, msg:
619 if self.debuglevel > 0:
620 print 'connect fail:', (self.host, self.port)
Martin v. Löwis322c0d12001-10-07 08:53:32 +0000621 if self.sock:
622 self.sock.close()
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000623 self.sock = None
624 continue
625 break
626 if not self.sock:
627 raise socket.error, msg
Greg Stein5e0fa402000-06-26 08:28:01 +0000628
Greg Steindd6eefb2000-07-18 09:09:48 +0000629 def close(self):
630 """Close the connection to the HTTP server."""
631 if self.sock:
Tim Peters07e99cb2001-01-14 23:47:14 +0000632 self.sock.close() # close it manually... there may be other refs
Greg Steindd6eefb2000-07-18 09:09:48 +0000633 self.sock = None
634 if self.__response:
635 self.__response.close()
636 self.__response = None
637 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000638
Greg Steindd6eefb2000-07-18 09:09:48 +0000639 def send(self, str):
640 """Send `str' to the server."""
641 if self.sock is None:
642 if self.auto_open:
643 self.connect()
644 else:
645 raise NotConnected()
Greg Stein5e0fa402000-06-26 08:28:01 +0000646
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000647 # send the data to the server. if we get a broken pipe, then close
Greg Steindd6eefb2000-07-18 09:09:48 +0000648 # the socket. we want to reconnect when somebody tries to send again.
649 #
650 # NOTE: we DO propagate the error, though, because we cannot simply
651 # ignore the error... the caller will know if they can retry.
Jeremy Hylton30f86742000-09-18 22:50:38 +0000652 if self.debuglevel > 0:
653 print "send:", repr(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000654 try:
Martin v. Löwise12454f2002-02-16 23:06:19 +0000655 self.sock.sendall(str)
Greg Steindd6eefb2000-07-18 09:09:48 +0000656 except socket.error, v:
Tim Peters07e99cb2001-01-14 23:47:14 +0000657 if v[0] == 32: # Broken pipe
Greg Steindd6eefb2000-07-18 09:09:48 +0000658 self.close()
659 raise
Greg Stein5e0fa402000-06-26 08:28:01 +0000660
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000661 def _output(self, s):
662 """Add a line of output to the current request buffer.
Tim Peters469cdad2002-08-08 20:19:19 +0000663
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000664 Assumes that the line does *not* end with \\r\\n.
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000665 """
666 self._buffer.append(s)
667
668 def _send_output(self):
669 """Send the currently buffered request and clear the buffer.
670
Jeremy Hyltone3252ec2002-07-16 21:41:43 +0000671 Appends an extra \\r\\n to the buffer.
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000672 """
673 self._buffer.extend(("", ""))
674 msg = "\r\n".join(self._buffer)
675 del self._buffer[:]
676 self.send(msg)
677
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000678 def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0):
Greg Steindd6eefb2000-07-18 09:09:48 +0000679 """Send a request to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000680
Greg Steindd6eefb2000-07-18 09:09:48 +0000681 `method' specifies an HTTP request method, e.g. 'GET'.
682 `url' specifies the object being requested, e.g. '/index.html'.
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000683 `skip_host' if True does not add automatically a 'Host:' header
684 `skip_accept_encoding' if True does not add automatically an
685 'Accept-Encoding:' header
Greg Steindd6eefb2000-07-18 09:09:48 +0000686 """
Greg Stein5e0fa402000-06-26 08:28:01 +0000687
Greg Stein616a58d2003-06-24 06:35:19 +0000688 # if a prior response has been completed, then forget about it.
Greg Steindd6eefb2000-07-18 09:09:48 +0000689 if self.__response and self.__response.isclosed():
690 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000691
Tim Peters58eb11c2004-01-18 20:29:55 +0000692
Greg Steindd6eefb2000-07-18 09:09:48 +0000693 # in certain cases, we cannot issue another request on this connection.
694 # this occurs when:
695 # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
696 # 2) a response to a previous request has signalled that it is going
697 # to close the connection upon completion.
698 # 3) the headers for the previous response have not been read, thus
699 # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
700 #
701 # if there is no prior response, then we can request at will.
702 #
703 # if point (2) is true, then we will have passed the socket to the
704 # response (effectively meaning, "there is no prior response"), and
705 # will open a new one when a new request is made.
706 #
707 # Note: if a prior response exists, then we *can* start a new request.
708 # We are not allowed to begin fetching the response to this new
709 # request, however, until that prior response is complete.
710 #
711 if self.__state == _CS_IDLE:
712 self.__state = _CS_REQ_STARTED
713 else:
714 raise CannotSendRequest()
Greg Stein5e0fa402000-06-26 08:28:01 +0000715
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000716 # Save the method we use, we need it later in the response phase
717 self._method = method
Greg Steindd6eefb2000-07-18 09:09:48 +0000718 if not url:
719 url = '/'
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000720 str = '%s %s %s' % (method, url, self._http_vsn_str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000721
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000722 self._output(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000723
Greg Steindd6eefb2000-07-18 09:09:48 +0000724 if self._http_vsn == 11:
725 # Issue some standard headers for better HTTP/1.1 compliance
Greg Stein5e0fa402000-06-26 08:28:01 +0000726
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000727 if not skip_host:
728 # this header is issued *only* for HTTP/1.1
729 # connections. more specifically, this means it is
730 # only issued when the client uses the new
731 # HTTPConnection() class. backwards-compat clients
732 # will be using HTTP/1.0 and those clients may be
733 # issuing this header themselves. we should NOT issue
734 # it twice; some web servers (such as Apache) barf
735 # when they see two Host: headers
Guido van Rossumf6922aa2001-01-14 21:03:01 +0000736
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000737 # If we need a non-standard port,include it in the
738 # header. If the request is going through a proxy,
739 # but the host of the actual URL, not the host of the
740 # proxy.
Jeremy Hylton8acf1e02002-03-08 19:35:51 +0000741
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000742 netloc = ''
743 if url.startswith('http'):
744 nil, netloc, nil, nil, nil = urlsplit(url)
745
746 if netloc:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000747 self.putheader('Host', netloc.encode("idna"))
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000748 elif self.port == HTTP_PORT:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000749 self.putheader('Host', self.host.encode("idna"))
Jeremy Hylton3921ff62002-03-09 06:07:23 +0000750 else:
Martin v. Löwis2548c732003-04-18 10:39:54 +0000751 self.putheader('Host', "%s:%s" % (self.host.encode("idna"), self.port))
Greg Stein5e0fa402000-06-26 08:28:01 +0000752
Greg Steindd6eefb2000-07-18 09:09:48 +0000753 # note: we are assuming that clients will not attempt to set these
754 # headers since *this* library must deal with the
755 # consequences. this also means that when the supporting
756 # libraries are updated to recognize other forms, then this
757 # code should be changed (removed or updated).
Greg Stein5e0fa402000-06-26 08:28:01 +0000758
Greg Steindd6eefb2000-07-18 09:09:48 +0000759 # we only want a Content-Encoding of "identity" since we don't
760 # support encodings such as x-gzip or x-deflate.
Martin v. Löwisaf7dc8d2003-11-19 19:51:55 +0000761 if not skip_accept_encoding:
762 self.putheader('Accept-Encoding', 'identity')
Greg Stein5e0fa402000-06-26 08:28:01 +0000763
Greg Steindd6eefb2000-07-18 09:09:48 +0000764 # we can accept "chunked" Transfer-Encodings, but no others
765 # NOTE: no TE header implies *only* "chunked"
766 #self.putheader('TE', 'chunked')
Greg Stein5e0fa402000-06-26 08:28:01 +0000767
Greg Steindd6eefb2000-07-18 09:09:48 +0000768 # if TE is supplied in the header, then it must appear in a
769 # Connection header.
770 #self.putheader('Connection', 'TE')
Greg Stein5e0fa402000-06-26 08:28:01 +0000771
Greg Steindd6eefb2000-07-18 09:09:48 +0000772 else:
773 # For HTTP/1.0, the server will assume "not chunked"
774 pass
Greg Stein5e0fa402000-06-26 08:28:01 +0000775
Greg Steindd6eefb2000-07-18 09:09:48 +0000776 def putheader(self, header, value):
777 """Send a request header line to the server.
Greg Stein5e0fa402000-06-26 08:28:01 +0000778
Greg Steindd6eefb2000-07-18 09:09:48 +0000779 For example: h.putheader('Accept', 'text/html')
780 """
781 if self.__state != _CS_REQ_STARTED:
782 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000783
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000784 str = '%s: %s' % (header, value)
785 self._output(str)
Greg Stein5e0fa402000-06-26 08:28:01 +0000786
Greg Steindd6eefb2000-07-18 09:09:48 +0000787 def endheaders(self):
788 """Indicate that the last header line has been sent to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000789
Greg Steindd6eefb2000-07-18 09:09:48 +0000790 if self.__state == _CS_REQ_STARTED:
791 self.__state = _CS_REQ_SENT
792 else:
793 raise CannotSendHeader()
Greg Stein5e0fa402000-06-26 08:28:01 +0000794
Jeremy Hylton8531b1b2002-07-16 21:21:11 +0000795 self._send_output()
Greg Stein5e0fa402000-06-26 08:28:01 +0000796
Greg Steindd6eefb2000-07-18 09:09:48 +0000797 def request(self, method, url, body=None, headers={}):
798 """Send a complete request to the server."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000799
Greg Steindd6eefb2000-07-18 09:09:48 +0000800 try:
801 self._send_request(method, url, body, headers)
802 except socket.error, v:
803 # trap 'Broken pipe' if we're allowed to automatically reconnect
804 if v[0] != 32 or not self.auto_open:
805 raise
806 # try one more time
807 self._send_request(method, url, body, headers)
Greg Stein5e0fa402000-06-26 08:28:01 +0000808
Greg Steindd6eefb2000-07-18 09:09:48 +0000809 def _send_request(self, method, url, body, headers):
Jeremy Hylton2c178252004-08-07 16:28:14 +0000810 # honour explicitly requested Host: and Accept-Encoding headers
811 header_names = dict.fromkeys([k.lower() for k in headers])
812 skips = {}
813 if 'host' in header_names:
814 skips['skip_host'] = 1
815 if 'accept-encoding' in header_names:
816 skips['skip_accept_encoding'] = 1
Greg Stein5e0fa402000-06-26 08:28:01 +0000817
Jeremy Hylton2c178252004-08-07 16:28:14 +0000818 self.putrequest(method, url, **skips)
819
820 if body and ('content-length' not in header_names):
Greg Steindd6eefb2000-07-18 09:09:48 +0000821 self.putheader('Content-Length', str(len(body)))
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000822 for hdr, value in headers.iteritems():
Greg Steindd6eefb2000-07-18 09:09:48 +0000823 self.putheader(hdr, value)
824 self.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +0000825
Greg Steindd6eefb2000-07-18 09:09:48 +0000826 if body:
827 self.send(body)
Greg Stein5e0fa402000-06-26 08:28:01 +0000828
Greg Steindd6eefb2000-07-18 09:09:48 +0000829 def getresponse(self):
830 "Get the response from the server."
Greg Stein5e0fa402000-06-26 08:28:01 +0000831
Greg Stein616a58d2003-06-24 06:35:19 +0000832 # if a prior response has been completed, then forget about it.
Greg Steindd6eefb2000-07-18 09:09:48 +0000833 if self.__response and self.__response.isclosed():
834 self.__response = None
Greg Stein5e0fa402000-06-26 08:28:01 +0000835
Greg Steindd6eefb2000-07-18 09:09:48 +0000836 #
837 # if a prior response exists, then it must be completed (otherwise, we
838 # cannot read this response's header to determine the connection-close
839 # behavior)
840 #
841 # note: if a prior response existed, but was connection-close, then the
842 # socket and response were made independent of this HTTPConnection
843 # object since a new request requires that we open a whole new
844 # connection
845 #
846 # this means the prior response had one of two states:
847 # 1) will_close: this connection was reset and the prior socket and
848 # response operate independently
849 # 2) persistent: the response was retained and we await its
850 # isclosed() status to become true.
851 #
852 if self.__state != _CS_REQ_SENT or self.__response:
853 raise ResponseNotReady()
Greg Stein5e0fa402000-06-26 08:28:01 +0000854
Jeremy Hylton30f86742000-09-18 22:50:38 +0000855 if self.debuglevel > 0:
Jeremy Hyltond46aa372002-07-06 18:48:07 +0000856 response = self.response_class(self.sock, self.debuglevel,
Tim Petersc2659cf2003-05-12 20:19:37 +0000857 strict=self.strict,
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000858 method=self._method)
Jeremy Hylton30f86742000-09-18 22:50:38 +0000859 else:
Jeremy Hyltonc1b2cb92003-05-05 16:13:58 +0000860 response = self.response_class(self.sock, strict=self.strict,
861 method=self._method)
Greg Stein5e0fa402000-06-26 08:28:01 +0000862
Jeremy Hylton39c03802002-07-12 14:04:09 +0000863 response.begin()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000864 assert response.will_close != _UNKNOWN
Greg Steindd6eefb2000-07-18 09:09:48 +0000865 self.__state = _CS_IDLE
Greg Stein5e0fa402000-06-26 08:28:01 +0000866
Greg Steindd6eefb2000-07-18 09:09:48 +0000867 if response.will_close:
868 # this effectively passes the connection to the response
869 self.close()
870 else:
871 # remember this, so we can tell when it is complete
872 self.__response = response
Greg Stein5e0fa402000-06-26 08:28:01 +0000873
Greg Steindd6eefb2000-07-18 09:09:48 +0000874 return response
Greg Stein5e0fa402000-06-26 08:28:01 +0000875
Jeremy Hylton29d27ac2002-07-09 21:22:36 +0000876# The next several classes are used to define FakeSocket,a socket-like
877# interface to an SSL connection.
878
879# The primary complexity comes from faking a makefile() method. The
880# standard socket makefile() implementation calls dup() on the socket
881# file descriptor. As a consequence, clients can call close() on the
882# parent socket and its makefile children in any order. The underlying
883# socket isn't closed until they are all closed.
884
885# The implementation uses reference counting to keep the socket open
886# until the last client calls close(). SharedSocket keeps track of
887# the reference counting and SharedSocketClient provides an constructor
888# and close() method that call incref() and decref() correctly.
889
890class SharedSocket:
891
892 def __init__(self, sock):
893 self.sock = sock
894 self._refcnt = 0
895
896 def incref(self):
897 self._refcnt += 1
898
899 def decref(self):
900 self._refcnt -= 1
901 assert self._refcnt >= 0
902 if self._refcnt == 0:
903 self.sock.close()
904
905 def __del__(self):
906 self.sock.close()
907
908class SharedSocketClient:
909
910 def __init__(self, shared):
911 self._closed = 0
912 self._shared = shared
913 self._shared.incref()
914 self._sock = shared.sock
915
916 def close(self):
917 if not self._closed:
918 self._shared.decref()
919 self._closed = 1
920 self._shared = None
921
922class SSLFile(SharedSocketClient):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000923 """File-like object wrapping an SSL socket."""
Greg Stein5e0fa402000-06-26 08:28:01 +0000924
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000925 BUFSIZE = 8192
Tim Petersc411dba2002-07-16 21:35:23 +0000926
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000927 def __init__(self, sock, ssl, bufsize=None):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +0000928 SharedSocketClient.__init__(self, sock)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000929 self._ssl = ssl
930 self._buf = ''
931 self._bufsize = bufsize or self.__class__.BUFSIZE
Guido van Rossum09c8b6c1999-12-07 21:37:17 +0000932
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000933 def _read(self):
934 buf = ''
935 # put in a loop so that we retry on transient errors
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000936 while True:
Greg Steindd6eefb2000-07-18 09:09:48 +0000937 try:
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000938 buf = self._ssl.read(self._bufsize)
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000939 except socket.sslerror, err:
940 if (err[0] == socket.SSL_ERROR_WANT_READ
Neal Norwitz22c5d772002-02-11 17:59:51 +0000941 or err[0] == socket.SSL_ERROR_WANT_WRITE):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000942 continue
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000943 if (err[0] == socket.SSL_ERROR_ZERO_RETURN
944 or err[0] == socket.SSL_ERROR_EOF):
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000945 break
946 raise
947 except socket.error, err:
Tim Petersf3623f32001-10-11 18:15:51 +0000948 if err[0] == errno.EINTR:
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000949 continue
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000950 if err[0] == errno.EBADF:
951 # XXX socket was closed?
952 break
Jeremy Hylton6459c8d2001-10-11 17:47:22 +0000953 raise
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000954 else:
Jeremy Hylton42dd01a2001-02-01 23:35:20 +0000955 break
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000956 return buf
957
958 def read(self, size=None):
959 L = [self._buf]
Raymond Hettinger49227682003-03-06 16:31:48 +0000960 avail = len(self._buf)
961 while size is None or avail < size:
962 s = self._read()
963 if s == '':
964 break
965 L.append(s)
966 avail += len(s)
967 all = "".join(L)
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000968 if size is None:
969 self._buf = ''
Raymond Hettinger49227682003-03-06 16:31:48 +0000970 return all
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000971 else:
Raymond Hettinger49227682003-03-06 16:31:48 +0000972 self._buf = all[size:]
973 return all[:size]
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000974
975 def readline(self):
976 L = [self._buf]
977 self._buf = ''
Raymond Hettinger49227682003-03-06 16:31:48 +0000978 while 1:
979 i = L[-1].find("\n")
980 if i >= 0:
Raymond Hettingerb2e0b922003-02-26 22:45:18 +0000981 break
Raymond Hettinger49227682003-03-06 16:31:48 +0000982 s = self._read()
983 if s == '':
984 break
985 L.append(s)
986 if i == -1:
987 # loop exited because there is no more data
988 return "".join(L)
989 else:
990 all = "".join(L)
991 # XXX could do enough bookkeeping not to do a 2nd search
992 i = all.find("\n") + 1
993 line = all[:i]
994 self._buf = all[i:]
995 return line
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +0000996
Martin v. Löwis11892ec2003-10-27 14:07:53 +0000997 def readlines(self, sizehint=0):
998 total = 0
999 list = []
1000 while True:
1001 line = self.readline()
1002 if not line:
1003 break
1004 list.append(line)
1005 total += len(line)
1006 if sizehint and total >= sizehint:
1007 break
1008 return list
1009
1010 def fileno(self):
1011 return self._sock.fileno()
1012
1013 def __iter__(self):
1014 return self
1015
1016 def next(self):
1017 line = self.readline()
1018 if not line:
1019 raise StopIteration
1020 return line
1021
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001022class FakeSocket(SharedSocketClient):
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001023
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001024 class _closedsocket:
1025 def __getattr__(self, name):
1026 raise error(9, 'Bad file descriptor')
1027
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001028 def __init__(self, sock, ssl):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001029 sock = SharedSocket(sock)
1030 SharedSocketClient.__init__(self, sock)
1031 self._ssl = ssl
1032
1033 def close(self):
1034 SharedSocketClient.close(self)
1035 self._sock = self.__class__._closedsocket()
Jeremy Hyltonbe4fcf12002-06-28 22:38:01 +00001036
1037 def makefile(self, mode, bufsize=None):
1038 if mode != 'r' and mode != 'rb':
1039 raise UnimplementedFileMode()
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001040 return SSLFile(self._shared, self._ssl, bufsize)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001041
Greg Steindd6eefb2000-07-18 09:09:48 +00001042 def send(self, stuff, flags = 0):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001043 return self._ssl.write(stuff)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001044
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001045 sendall = send
Andrew M. Kuchlinga3c0b932002-03-18 22:51:48 +00001046
Greg Steindd6eefb2000-07-18 09:09:48 +00001047 def recv(self, len = 1024, flags = 0):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001048 return self._ssl.read(len)
Guido van Rossum23acc951994-02-21 16:36:04 +00001049
Greg Steindd6eefb2000-07-18 09:09:48 +00001050 def __getattr__(self, attr):
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001051 return getattr(self._sock, attr)
Guido van Rossum09c8b6c1999-12-07 21:37:17 +00001052
Guido van Rossum23acc951994-02-21 16:36:04 +00001053
Greg Stein5e0fa402000-06-26 08:28:01 +00001054class HTTPSConnection(HTTPConnection):
Greg Steindd6eefb2000-07-18 09:09:48 +00001055 "This class allows communication via SSL."
Greg Stein5e0fa402000-06-26 08:28:01 +00001056
Greg Steindd6eefb2000-07-18 09:09:48 +00001057 default_port = HTTPS_PORT
Greg Stein5e0fa402000-06-26 08:28:01 +00001058
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001059 def __init__(self, host, port=None, key_file=None, cert_file=None,
1060 strict=None):
1061 HTTPConnection.__init__(self, host, port, strict)
Jeremy Hylton7c75c992002-06-28 23:38:14 +00001062 self.key_file = key_file
1063 self.cert_file = cert_file
Greg Stein5e0fa402000-06-26 08:28:01 +00001064
Greg Steindd6eefb2000-07-18 09:09:48 +00001065 def connect(self):
1066 "Connect to a host on a given (SSL) port."
Greg Stein5e0fa402000-06-26 08:28:01 +00001067
Greg Steindd6eefb2000-07-18 09:09:48 +00001068 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1069 sock.connect((self.host, self.port))
Martin v. Löwis1867f242003-06-14 13:30:53 +00001070 ssl = socket.ssl(sock, self.key_file, self.cert_file)
Greg Steindd6eefb2000-07-18 09:09:48 +00001071 self.sock = FakeSocket(sock, ssl)
Greg Stein5e0fa402000-06-26 08:28:01 +00001072
1073
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001074class HTTP:
Greg Steindd6eefb2000-07-18 09:09:48 +00001075 "Compatibility class with httplib.py from 1.5."
Greg Stein5e0fa402000-06-26 08:28:01 +00001076
Greg Steindd6eefb2000-07-18 09:09:48 +00001077 _http_vsn = 10
1078 _http_vsn_str = 'HTTP/1.0'
Greg Stein5e0fa402000-06-26 08:28:01 +00001079
Greg Steindd6eefb2000-07-18 09:09:48 +00001080 debuglevel = 0
Greg Stein5e0fa402000-06-26 08:28:01 +00001081
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001082 _connection_class = HTTPConnection
1083
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001084 def __init__(self, host='', port=None, strict=None):
Greg Steindd6eefb2000-07-18 09:09:48 +00001085 "Provide a default host, since the superclass requires one."
Greg Stein5e0fa402000-06-26 08:28:01 +00001086
Greg Steindd6eefb2000-07-18 09:09:48 +00001087 # some joker passed 0 explicitly, meaning default port
1088 if port == 0:
1089 port = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001090
Greg Steindd6eefb2000-07-18 09:09:48 +00001091 # Note that we may pass an empty string as the host; this will throw
1092 # an error when we attempt to connect. Presumably, the client code
1093 # will call connect before then, with a proper host.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001094 self._setup(self._connection_class(host, port, strict))
Greg Stein5e0fa402000-06-26 08:28:01 +00001095
Greg Stein81937a42001-08-18 09:20:23 +00001096 def _setup(self, conn):
1097 self._conn = conn
1098
1099 # set up delegation to flesh out interface
1100 self.send = conn.send
1101 self.putrequest = conn.putrequest
1102 self.endheaders = conn.endheaders
1103 self.set_debuglevel = conn.set_debuglevel
1104
1105 conn._http_vsn = self._http_vsn
1106 conn._http_vsn_str = self._http_vsn_str
Greg Stein5e0fa402000-06-26 08:28:01 +00001107
Greg Steindd6eefb2000-07-18 09:09:48 +00001108 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001109
Greg Steindd6eefb2000-07-18 09:09:48 +00001110 def connect(self, host=None, port=None):
1111 "Accept arguments to set the host/port, since the superclass doesn't."
Greg Stein5e0fa402000-06-26 08:28:01 +00001112
Greg Steindd6eefb2000-07-18 09:09:48 +00001113 if host is not None:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001114 self._conn._set_hostport(host, port)
1115 self._conn.connect()
Greg Stein5e0fa402000-06-26 08:28:01 +00001116
Greg Steindd6eefb2000-07-18 09:09:48 +00001117 def getfile(self):
1118 "Provide a getfile, since the superclass' does not use this concept."
1119 return self.file
Greg Stein5e0fa402000-06-26 08:28:01 +00001120
Greg Steindd6eefb2000-07-18 09:09:48 +00001121 def putheader(self, header, *values):
1122 "The superclass allows only one value argument."
Guido van Rossum34735a62000-12-15 15:09:42 +00001123 self._conn.putheader(header, '\r\n\t'.join(values))
Greg Stein5e0fa402000-06-26 08:28:01 +00001124
Greg Steindd6eefb2000-07-18 09:09:48 +00001125 def getreply(self):
1126 """Compat definition since superclass does not define it.
Greg Stein5e0fa402000-06-26 08:28:01 +00001127
Greg Steindd6eefb2000-07-18 09:09:48 +00001128 Returns a tuple consisting of:
1129 - server status code (e.g. '200' if all goes well)
1130 - server "reason" corresponding to status code
1131 - any RFC822 headers in the response from the server
1132 """
1133 try:
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001134 response = self._conn.getresponse()
Greg Steindd6eefb2000-07-18 09:09:48 +00001135 except BadStatusLine, e:
1136 ### hmm. if getresponse() ever closes the socket on a bad request,
1137 ### then we are going to have problems with self.sock
Greg Stein5e0fa402000-06-26 08:28:01 +00001138
Greg Steindd6eefb2000-07-18 09:09:48 +00001139 ### should we keep this behavior? do people use it?
1140 # keep the socket open (as a file), and return it
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001141 self.file = self._conn.sock.makefile('rb', 0)
Greg Stein5e0fa402000-06-26 08:28:01 +00001142
Greg Steindd6eefb2000-07-18 09:09:48 +00001143 # close our socket -- we want to restart after any protocol error
1144 self.close()
Greg Stein5e0fa402000-06-26 08:28:01 +00001145
Greg Steindd6eefb2000-07-18 09:09:48 +00001146 self.headers = None
1147 return -1, e.line, None
Greg Stein5e0fa402000-06-26 08:28:01 +00001148
Greg Steindd6eefb2000-07-18 09:09:48 +00001149 self.headers = response.msg
1150 self.file = response.fp
1151 return response.status, response.reason, response.msg
Greg Stein5e0fa402000-06-26 08:28:01 +00001152
Greg Steindd6eefb2000-07-18 09:09:48 +00001153 def close(self):
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001154 self._conn.close()
Greg Stein5e0fa402000-06-26 08:28:01 +00001155
Greg Steindd6eefb2000-07-18 09:09:48 +00001156 # note that self.file == response.fp, which gets closed by the
1157 # superclass. just clear the object ref here.
1158 ### hmm. messy. if status==-1, then self.file is owned by us.
1159 ### well... we aren't explicitly closing, but losing this ref will
1160 ### do it
1161 self.file = None
Greg Stein5e0fa402000-06-26 08:28:01 +00001162
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001163if hasattr(socket, 'ssl'):
1164 class HTTPS(HTTP):
1165 """Compatibility with 1.5 httplib interface
1166
1167 Python 1.5.2 did not have an HTTPS class, but it defined an
1168 interface for sending http requests that is also useful for
Tim Peters5ceadc82001-01-13 19:16:21 +00001169 https.
Jeremy Hylton29b8d5a2000-08-01 17:33:32 +00001170 """
1171
Martin v. Löwisd7bf9742000-09-21 22:09:47 +00001172 _connection_class = HTTPSConnection
Tim Peters5ceadc82001-01-13 19:16:21 +00001173
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001174 def __init__(self, host='', port=None, key_file=None, cert_file=None,
1175 strict=None):
Greg Stein81937a42001-08-18 09:20:23 +00001176 # provide a default host, pass the X509 cert info
1177
1178 # urf. compensate for bad input.
1179 if port == 0:
1180 port = None
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001181 self._setup(self._connection_class(host, port, key_file,
1182 cert_file, strict))
Greg Stein81937a42001-08-18 09:20:23 +00001183
1184 # we never actually use these for anything, but we keep them
1185 # here for compatibility with post-1.5.2 CVS.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001186 self.key_file = key_file
1187 self.cert_file = cert_file
Greg Stein81937a42001-08-18 09:20:23 +00001188
Greg Stein5e0fa402000-06-26 08:28:01 +00001189
1190class HTTPException(Exception):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001191 # Subclasses that define an __init__ must call Exception.__init__
1192 # or define self.args. Otherwise, str() will fail.
Greg Steindd6eefb2000-07-18 09:09:48 +00001193 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001194
1195class NotConnected(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001196 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001197
Skip Montanaro9d389972002-03-24 16:53:50 +00001198class InvalidURL(HTTPException):
1199 pass
1200
Greg Stein5e0fa402000-06-26 08:28:01 +00001201class UnknownProtocol(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001202 def __init__(self, version):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001203 self.args = version,
Greg Steindd6eefb2000-07-18 09:09:48 +00001204 self.version = version
Greg Stein5e0fa402000-06-26 08:28:01 +00001205
1206class UnknownTransferEncoding(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001207 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001208
Greg Stein5e0fa402000-06-26 08:28:01 +00001209class UnimplementedFileMode(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001210 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001211
1212class IncompleteRead(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001213 def __init__(self, partial):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001214 self.args = partial,
Greg Steindd6eefb2000-07-18 09:09:48 +00001215 self.partial = partial
Greg Stein5e0fa402000-06-26 08:28:01 +00001216
1217class ImproperConnectionState(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001218 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001219
1220class CannotSendRequest(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001221 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001222
1223class CannotSendHeader(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001224 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001225
1226class ResponseNotReady(ImproperConnectionState):
Greg Steindd6eefb2000-07-18 09:09:48 +00001227 pass
Greg Stein5e0fa402000-06-26 08:28:01 +00001228
1229class BadStatusLine(HTTPException):
Greg Steindd6eefb2000-07-18 09:09:48 +00001230 def __init__(self, line):
Jeremy Hylton12f4f352002-07-06 18:55:01 +00001231 self.args = line,
Greg Steindd6eefb2000-07-18 09:09:48 +00001232 self.line = line
Greg Stein5e0fa402000-06-26 08:28:01 +00001233
1234# for backwards compatibility
1235error = HTTPException
1236
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001237class LineAndFileWrapper:
1238 """A limited file-like object for HTTP/0.9 responses."""
1239
1240 # The status-line parsing code calls readline(), which normally
1241 # get the HTTP status line. For a 0.9 response, however, this is
1242 # actually the first line of the body! Clients need to get a
1243 # readable file object that contains that line.
1244
1245 def __init__(self, line, file):
1246 self._line = line
1247 self._file = file
1248 self._line_consumed = 0
1249 self._line_offset = 0
1250 self._line_left = len(line)
1251
1252 def __getattr__(self, attr):
1253 return getattr(self._file, attr)
1254
1255 def _done(self):
1256 # called when the last byte is read from the line. After the
1257 # call, all read methods are delegated to the underlying file
Skip Montanaro74b9a7a2003-02-25 17:48:15 +00001258 # object.
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001259 self._line_consumed = 1
1260 self.read = self._file.read
1261 self.readline = self._file.readline
1262 self.readlines = self._file.readlines
1263
1264 def read(self, amt=None):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001265 if self._line_consumed:
1266 return self._file.read(amt)
1267 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001268 if amt is None or amt > self._line_left:
1269 s = self._line[self._line_offset:]
1270 self._done()
1271 if amt is None:
1272 return s + self._file.read()
1273 else:
Tim Petersc411dba2002-07-16 21:35:23 +00001274 return s + self._file.read(amt - len(s))
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001275 else:
1276 assert amt <= self._line_left
1277 i = self._line_offset
1278 j = i + amt
1279 s = self._line[i:j]
1280 self._line_offset = j
1281 self._line_left -= amt
1282 if self._line_left == 0:
1283 self._done()
1284 return s
Tim Petersc411dba2002-07-16 21:35:23 +00001285
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001286 def readline(self):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001287 if self._line_consumed:
1288 return self._file.readline()
1289 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001290 s = self._line[self._line_offset:]
1291 self._done()
1292 return s
1293
1294 def readlines(self, size=None):
Hye-Shik Chang39aef792004-06-05 13:30:56 +00001295 if self._line_consumed:
1296 return self._file.readlines(size)
1297 assert self._line_left
Jeremy Hyltond46aa372002-07-06 18:48:07 +00001298 L = [self._line[self._line_offset:]]
1299 self._done()
1300 if size is None:
1301 return L + self._file.readlines()
1302 else:
1303 return L + self._file.readlines(size)
Greg Stein5e0fa402000-06-26 08:28:01 +00001304
Guido van Rossum23acc951994-02-21 16:36:04 +00001305def test():
Guido van Rossum41999c11997-12-09 00:12:23 +00001306 """Test this module.
1307
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001308 A hodge podge of tests collected here, because they have too many
1309 external dependencies for the regular test suite.
Guido van Rossum41999c11997-12-09 00:12:23 +00001310 """
Greg Stein5e0fa402000-06-26 08:28:01 +00001311
Guido van Rossum41999c11997-12-09 00:12:23 +00001312 import sys
1313 import getopt
1314 opts, args = getopt.getopt(sys.argv[1:], 'd')
1315 dl = 0
1316 for o, a in opts:
1317 if o == '-d': dl = dl + 1
1318 host = 'www.python.org'
1319 selector = '/'
1320 if args[0:]: host = args[0]
1321 if args[1:]: selector = args[1]
1322 h = HTTP()
1323 h.set_debuglevel(dl)
1324 h.connect(host)
1325 h.putrequest('GET', selector)
1326 h.endheaders()
Greg Stein5e0fa402000-06-26 08:28:01 +00001327 status, reason, headers = h.getreply()
1328 print 'status =', status
1329 print 'reason =', reason
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001330 print "read", len(h.getfile().read())
Guido van Rossum41999c11997-12-09 00:12:23 +00001331 print
1332 if headers:
Guido van Rossum34735a62000-12-15 15:09:42 +00001333 for header in headers.headers: print header.strip()
Guido van Rossum41999c11997-12-09 00:12:23 +00001334 print
Greg Stein5e0fa402000-06-26 08:28:01 +00001335
Jeremy Hylton8acf1e02002-03-08 19:35:51 +00001336 # minimal test that code to extract host from url works
1337 class HTTP11(HTTP):
1338 _http_vsn = 11
1339 _http_vsn_str = 'HTTP/1.1'
1340
1341 h = HTTP11('www.python.org')
1342 h.putrequest('GET', 'http://www.python.org/~jeremy/')
1343 h.endheaders()
1344 h.getreply()
1345 h.close()
1346
Greg Stein5e0fa402000-06-26 08:28:01 +00001347 if hasattr(socket, 'ssl'):
Tim Petersc411dba2002-07-16 21:35:23 +00001348
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001349 for host, selector in (('sourceforge.net', '/projects/python'),
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001350 ):
1351 print "https://%s%s" % (host, selector)
1352 hs = HTTPS()
Jeremy Hylton8531b1b2002-07-16 21:21:11 +00001353 hs.set_debuglevel(dl)
Jeremy Hylton29d27ac2002-07-09 21:22:36 +00001354 hs.connect(host)
1355 hs.putrequest('GET', selector)
1356 hs.endheaders()
1357 status, reason, headers = hs.getreply()
1358 print 'status =', status
1359 print 'reason =', reason
1360 print "read", len(hs.getfile().read())
1361 print
1362 if headers:
1363 for header in headers.headers: print header.strip()
1364 print
Guido van Rossum23acc951994-02-21 16:36:04 +00001365
Guido van Rossum23acc951994-02-21 16:36:04 +00001366if __name__ == '__main__':
Guido van Rossum41999c11997-12-09 00:12:23 +00001367 test()