ยปCore Development>Code coverage>Lib/http/client.py

Python code coverage for Lib/http/client.py

#countcontent
1n/ar"""HTTP/1.1 client library
2n/a
3n/a<intro stuff goes here>
4n/a<other stuff, too>
5n/a
6n/aHTTPConnection goes through a number of "states", which define when a client
7n/amay legally make another request or fetch the response for a particular
8n/arequest. This diagram details these state transitions:
9n/a
10n/a (null)
11n/a |
12n/a | HTTPConnection()
13n/a v
14n/a Idle
15n/a |
16n/a | putrequest()
17n/a v
18n/a Request-started
19n/a |
20n/a | ( putheader() )* endheaders()
21n/a v
22n/a Request-sent
23n/a |\_____________________________
24n/a | | getresponse() raises
25n/a | response = getresponse() | ConnectionError
26n/a v v
27n/a Unread-response Idle
28n/a [Response-headers-read]
29n/a |\____________________
30n/a | |
31n/a | response.read() | putrequest()
32n/a v v
33n/a Idle Req-started-unread-response
34n/a ______/|
35n/a / |
36n/a response.read() | | ( putheader() )* endheaders()
37n/a v v
38n/a Request-started Req-sent-unread-response
39n/a |
40n/a | response.read()
41n/a v
42n/a Request-sent
43n/a
44n/aThis diagram presents the following rules:
45n/a -- a second request may not be started until {response-headers-read}
46n/a -- a response [object] cannot be retrieved until {request-sent}
47n/a -- there is no differentiation between an unread response body and a
48n/a partially read response body
49n/a
50n/aNote: this enforcement is applied by the HTTPConnection class. The
51n/a HTTPResponse class does not enforce this state machine, which
52n/a implies sophisticated clients may accelerate the request/response
53n/a pipeline. Caution should be taken, though: accelerating the states
54n/a beyond the above pattern may imply knowledge of the server's
55n/a connection-close behavior for certain requests. For example, it
56n/a is impossible to tell whether the server will close the connection
57n/a UNTIL the response headers have been read; this means that further
58n/a requests cannot be placed into the pipeline until it is known that
59n/a the server will NOT be closing the connection.
60n/a
61n/aLogical State __state __response
62n/a------------- ------- ----------
63n/aIdle _CS_IDLE None
64n/aRequest-started _CS_REQ_STARTED None
65n/aRequest-sent _CS_REQ_SENT None
66n/aUnread-response _CS_IDLE <response_class>
67n/aReq-started-unread-response _CS_REQ_STARTED <response_class>
68n/aReq-sent-unread-response _CS_REQ_SENT <response_class>
69n/a"""
70n/a
71n/aimport email.parser
72n/aimport email.message
73n/aimport http
74n/aimport io
75n/aimport re
76n/aimport socket
77n/aimport collections
78n/afrom urllib.parse import urlsplit
79n/a
80n/a# HTTPMessage, parse_headers(), and the HTTP status code constants are
81n/a# intentionally omitted for simplicity
82n/a__all__ = ["HTTPResponse", "HTTPConnection",
83n/a "HTTPException", "NotConnected", "UnknownProtocol",
84n/a "UnknownTransferEncoding", "UnimplementedFileMode",
85n/a "IncompleteRead", "InvalidURL", "ImproperConnectionState",
86n/a "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
87n/a "BadStatusLine", "LineTooLong", "RemoteDisconnected", "error",
88n/a "responses"]
89n/a
90n/aHTTP_PORT = 80
91n/aHTTPS_PORT = 443
92n/a
93n/a_UNKNOWN = 'UNKNOWN'
94n/a
95n/a# connection states
96n/a_CS_IDLE = 'Idle'
97n/a_CS_REQ_STARTED = 'Request-started'
98n/a_CS_REQ_SENT = 'Request-sent'
99n/a
100n/a
101n/a# hack to maintain backwards compatibility
102n/aglobals().update(http.HTTPStatus.__members__)
103n/a
104n/a# another hack to maintain backwards compatibility
105n/a# Mapping status codes to official W3C names
106n/aresponses = {v: v.phrase for v in http.HTTPStatus.__members__.values()}
107n/a
108n/a# maximal amount of data to read at one time in _safe_read
109n/aMAXAMOUNT = 1048576
110n/a
111n/a# maximal line length when calling readline().
112n/a_MAXLINE = 65536
113n/a_MAXHEADERS = 100
114n/a
115n/a# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
116n/a#
117n/a# VCHAR = %x21-7E
118n/a# obs-text = %x80-FF
119n/a# header-field = field-name ":" OWS field-value OWS
120n/a# field-name = token
121n/a# field-value = *( field-content / obs-fold )
122n/a# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
123n/a# field-vchar = VCHAR / obs-text
124n/a#
125n/a# obs-fold = CRLF 1*( SP / HTAB )
126n/a# ; obsolete line folding
127n/a# ; see Section 3.2.4
128n/a
129n/a# token = 1*tchar
130n/a#
131n/a# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
132n/a# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
133n/a# / DIGIT / ALPHA
134n/a# ; any VCHAR, except delimiters
135n/a#
136n/a# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1
137n/a
138n/a# the patterns for both name and value are more lenient than RFC
139n/a# definitions to allow for backwards compatibility
140n/a_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch
141n/a_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
142n/a
143n/a# We always set the Content-Length header for these methods because some
144n/a# servers will otherwise respond with a 411
145n/a_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
146n/a
147n/a
148n/adef _encode(data, name='data'):
149n/a """Call data.encode("latin-1") but show a better error message."""
150n/a try:
151n/a return data.encode("latin-1")
152n/a except UnicodeEncodeError as err:
153n/a raise UnicodeEncodeError(
154n/a err.encoding,
155n/a err.object,
156n/a err.start,
157n/a err.end,
158n/a "%s (%.20r) is not valid Latin-1. Use %s.encode('utf-8') "
159n/a "if you want to send it encoded in UTF-8." %
160n/a (name.title(), data[err.start:err.end], name)) from None
161n/a
162n/a
163n/aclass HTTPMessage(email.message.Message):
164n/a # XXX The only usage of this method is in
165n/a # http.server.CGIHTTPRequestHandler. Maybe move the code there so
166n/a # that it doesn't need to be part of the public API. The API has
167n/a # never been defined so this could cause backwards compatibility
168n/a # issues.
169n/a
170n/a def getallmatchingheaders(self, name):
171n/a """Find all header lines matching a given header name.
172n/a
173n/a Look through the list of headers and find all lines matching a given
174n/a header name (and their continuation lines). A list of the lines is
175n/a returned, without interpretation. If the header does not occur, an
176n/a empty list is returned. If the header occurs multiple times, all
177n/a occurrences are returned. Case is not important in the header name.
178n/a
179n/a """
180n/a name = name.lower() + ':'
181n/a n = len(name)
182n/a lst = []
183n/a hit = 0
184n/a for line in self.keys():
185n/a if line[:n].lower() == name:
186n/a hit = 1
187n/a elif not line[:1].isspace():
188n/a hit = 0
189n/a if hit:
190n/a lst.append(line)
191n/a return lst
192n/a
193n/adef parse_headers(fp, _class=HTTPMessage):
194n/a """Parses only RFC2822 headers from a file pointer.
195n/a
196n/a email Parser wants to see strings rather than bytes.
197n/a But a TextIOWrapper around self.rfile would buffer too many bytes
198n/a from the stream, bytes which we later need to read as bytes.
199n/a So we read the correct bytes here, as bytes, for email Parser
200n/a to parse.
201n/a
202n/a """
203n/a headers = []
204n/a while True:
205n/a line = fp.readline(_MAXLINE + 1)
206n/a if len(line) > _MAXLINE:
207n/a raise LineTooLong("header line")
208n/a headers.append(line)
209n/a if len(headers) > _MAXHEADERS:
210n/a raise HTTPException("got more than %d headers" % _MAXHEADERS)
211n/a if line in (b'\r\n', b'\n', b''):
212n/a break
213n/a hstring = b''.join(headers).decode('iso-8859-1')
214n/a return email.parser.Parser(_class=_class).parsestr(hstring)
215n/a
216n/a
217n/aclass HTTPResponse(io.BufferedIOBase):
218n/a
219n/a # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
220n/a
221n/a # The bytes from the socket object are iso-8859-1 strings.
222n/a # See RFC 2616 sec 2.2 which notes an exception for MIME-encoded
223n/a # text following RFC 2047. The basic status line parsing only
224n/a # accepts iso-8859-1.
225n/a
226n/a def __init__(self, sock, debuglevel=0, method=None, url=None):
227n/a # If the response includes a content-length header, we need to
228n/a # make sure that the client doesn't read more than the
229n/a # specified number of bytes. If it does, it will block until
230n/a # the server times out and closes the connection. This will
231n/a # happen if a self.fp.read() is done (without a size) whether
232n/a # self.fp is buffered or not. So, no self.fp.read() by
233n/a # clients unless they know what they are doing.
234n/a self.fp = sock.makefile("rb")
235n/a self.debuglevel = debuglevel
236n/a self._method = method
237n/a
238n/a # The HTTPResponse object is returned via urllib. The clients
239n/a # of http and urllib expect different attributes for the
240n/a # headers. headers is used here and supports urllib. msg is
241n/a # provided as a backwards compatibility layer for http
242n/a # clients.
243n/a
244n/a self.headers = self.msg = None
245n/a
246n/a # from the Status-Line of the response
247n/a self.version = _UNKNOWN # HTTP-Version
248n/a self.status = _UNKNOWN # Status-Code
249n/a self.reason = _UNKNOWN # Reason-Phrase
250n/a
251n/a self.chunked = _UNKNOWN # is "chunked" being used?
252n/a self.chunk_left = _UNKNOWN # bytes left to read in current chunk
253n/a self.length = _UNKNOWN # number of bytes left in response
254n/a self.will_close = _UNKNOWN # conn will close at end of response
255n/a
256n/a def _read_status(self):
257n/a line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
258n/a if len(line) > _MAXLINE:
259n/a raise LineTooLong("status line")
260n/a if self.debuglevel > 0:
261n/a print("reply:", repr(line))
262n/a if not line:
263n/a # Presumably, the server closed the connection before
264n/a # sending a valid response.
265n/a raise RemoteDisconnected("Remote end closed connection without"
266n/a " response")
267n/a try:
268n/a version, status, reason = line.split(None, 2)
269n/a except ValueError:
270n/a try:
271n/a version, status = line.split(None, 1)
272n/a reason = ""
273n/a except ValueError:
274n/a # empty version will cause next test to fail.
275n/a version = ""
276n/a if not version.startswith("HTTP/"):
277n/a self._close_conn()
278n/a raise BadStatusLine(line)
279n/a
280n/a # The status code is a three-digit number
281n/a try:
282n/a status = int(status)
283n/a if status < 100 or status > 999:
284n/a raise BadStatusLine(line)
285n/a except ValueError:
286n/a raise BadStatusLine(line)
287n/a return version, status, reason
288n/a
289n/a def begin(self):
290n/a if self.headers is not None:
291n/a # we've already started reading the response
292n/a return
293n/a
294n/a # read until we get a non-100 response
295n/a while True:
296n/a version, status, reason = self._read_status()
297n/a if status != CONTINUE:
298n/a break
299n/a # skip the header from the 100 response
300n/a while True:
301n/a skip = self.fp.readline(_MAXLINE + 1)
302n/a if len(skip) > _MAXLINE:
303n/a raise LineTooLong("header line")
304n/a skip = skip.strip()
305n/a if not skip:
306n/a break
307n/a if self.debuglevel > 0:
308n/a print("header:", skip)
309n/a
310n/a self.code = self.status = status
311n/a self.reason = reason.strip()
312n/a if version in ("HTTP/1.0", "HTTP/0.9"):
313n/a # Some servers might still return "0.9", treat it as 1.0 anyway
314n/a self.version = 10
315n/a elif version.startswith("HTTP/1."):
316n/a self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
317n/a else:
318n/a raise UnknownProtocol(version)
319n/a
320n/a self.headers = self.msg = parse_headers(self.fp)
321n/a
322n/a if self.debuglevel > 0:
323n/a for hdr in self.headers:
324n/a print("header:", hdr, end=" ")
325n/a
326n/a # are we using the chunked-style of transfer encoding?
327n/a tr_enc = self.headers.get("transfer-encoding")
328n/a if tr_enc and tr_enc.lower() == "chunked":
329n/a self.chunked = True
330n/a self.chunk_left = None
331n/a else:
332n/a self.chunked = False
333n/a
334n/a # will the connection close at the end of the response?
335n/a self.will_close = self._check_close()
336n/a
337n/a # do we have a Content-Length?
338n/a # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
339n/a self.length = None
340n/a length = self.headers.get("content-length")
341n/a
342n/a # are we using the chunked-style of transfer encoding?
343n/a tr_enc = self.headers.get("transfer-encoding")
344n/a if length and not self.chunked:
345n/a try:
346n/a self.length = int(length)
347n/a except ValueError:
348n/a self.length = None
349n/a else:
350n/a if self.length < 0: # ignore nonsensical negative lengths
351n/a self.length = None
352n/a else:
353n/a self.length = None
354n/a
355n/a # does the body have a fixed length? (of zero)
356n/a if (status == NO_CONTENT or status == NOT_MODIFIED or
357n/a 100 <= status < 200 or # 1xx codes
358n/a self._method == "HEAD"):
359n/a self.length = 0
360n/a
361n/a # if the connection remains open, and we aren't using chunked, and
362n/a # a content-length was not provided, then assume that the connection
363n/a # WILL close.
364n/a if (not self.will_close and
365n/a not self.chunked and
366n/a self.length is None):
367n/a self.will_close = True
368n/a
369n/a def _check_close(self):
370n/a conn = self.headers.get("connection")
371n/a if self.version == 11:
372n/a # An HTTP/1.1 proxy is assumed to stay open unless
373n/a # explicitly closed.
374n/a conn = self.headers.get("connection")
375n/a if conn and "close" in conn.lower():
376n/a return True
377n/a return False
378n/a
379n/a # Some HTTP/1.0 implementations have support for persistent
380n/a # connections, using rules different than HTTP/1.1.
381n/a
382n/a # For older HTTP, Keep-Alive indicates persistent connection.
383n/a if self.headers.get("keep-alive"):
384n/a return False
385n/a
386n/a # At least Akamai returns a "Connection: Keep-Alive" header,
387n/a # which was supposed to be sent by the client.
388n/a if conn and "keep-alive" in conn.lower():
389n/a return False
390n/a
391n/a # Proxy-Connection is a netscape hack.
392n/a pconn = self.headers.get("proxy-connection")
393n/a if pconn and "keep-alive" in pconn.lower():
394n/a return False
395n/a
396n/a # otherwise, assume it will close
397n/a return True
398n/a
399n/a def _close_conn(self):
400n/a fp = self.fp
401n/a self.fp = None
402n/a fp.close()
403n/a
404n/a def close(self):
405n/a try:
406n/a super().close() # set "closed" flag
407n/a finally:
408n/a if self.fp:
409n/a self._close_conn()
410n/a
411n/a # These implementations are for the benefit of io.BufferedReader.
412n/a
413n/a # XXX This class should probably be revised to act more like
414n/a # the "raw stream" that BufferedReader expects.
415n/a
416n/a def flush(self):
417n/a super().flush()
418n/a if self.fp:
419n/a self.fp.flush()
420n/a
421n/a def readable(self):
422n/a """Always returns True"""
423n/a return True
424n/a
425n/a # End of "raw stream" methods
426n/a
427n/a def isclosed(self):
428n/a """True if the connection is closed."""
429n/a # NOTE: it is possible that we will not ever call self.close(). This
430n/a # case occurs when will_close is TRUE, length is None, and we
431n/a # read up to the last byte, but NOT past it.
432n/a #
433n/a # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
434n/a # called, meaning self.isclosed() is meaningful.
435n/a return self.fp is None
436n/a
437n/a def read(self, amt=None):
438n/a if self.fp is None:
439n/a return b""
440n/a
441n/a if self._method == "HEAD":
442n/a self._close_conn()
443n/a return b""
444n/a
445n/a if amt is not None:
446n/a # Amount is given, implement using readinto
447n/a b = bytearray(amt)
448n/a n = self.readinto(b)
449n/a return memoryview(b)[:n].tobytes()
450n/a else:
451n/a # Amount is not given (unbounded read) so we must check self.length
452n/a # and self.chunked
453n/a
454n/a if self.chunked:
455n/a return self._readall_chunked()
456n/a
457n/a if self.length is None:
458n/a s = self.fp.read()
459n/a else:
460n/a try:
461n/a s = self._safe_read(self.length)
462n/a except IncompleteRead:
463n/a self._close_conn()
464n/a raise
465n/a self.length = 0
466n/a self._close_conn() # we read everything
467n/a return s
468n/a
469n/a def readinto(self, b):
470n/a """Read up to len(b) bytes into bytearray b and return the number
471n/a of bytes read.
472n/a """
473n/a
474n/a if self.fp is None:
475n/a return 0
476n/a
477n/a if self._method == "HEAD":
478n/a self._close_conn()
479n/a return 0
480n/a
481n/a if self.chunked:
482n/a return self._readinto_chunked(b)
483n/a
484n/a if self.length is not None:
485n/a if len(b) > self.length:
486n/a # clip the read to the "end of response"
487n/a b = memoryview(b)[0:self.length]
488n/a
489n/a # we do not use _safe_read() here because this may be a .will_close
490n/a # connection, and the user is reading more bytes than will be provided
491n/a # (for example, reading in 1k chunks)
492n/a n = self.fp.readinto(b)
493n/a if not n and b:
494n/a # Ideally, we would raise IncompleteRead if the content-length
495n/a # wasn't satisfied, but it might break compatibility.
496n/a self._close_conn()
497n/a elif self.length is not None:
498n/a self.length -= n
499n/a if not self.length:
500n/a self._close_conn()
501n/a return n
502n/a
503n/a def _read_next_chunk_size(self):
504n/a # Read the next chunk size from the file
505n/a line = self.fp.readline(_MAXLINE + 1)
506n/a if len(line) > _MAXLINE:
507n/a raise LineTooLong("chunk size")
508n/a i = line.find(b";")
509n/a if i >= 0:
510n/a line = line[:i] # strip chunk-extensions
511n/a try:
512n/a return int(line, 16)
513n/a except ValueError:
514n/a # close the connection as protocol synchronisation is
515n/a # probably lost
516n/a self._close_conn()
517n/a raise
518n/a
519n/a def _read_and_discard_trailer(self):
520n/a # read and discard trailer up to the CRLF terminator
521n/a ### note: we shouldn't have any trailers!
522n/a while True:
523n/a line = self.fp.readline(_MAXLINE + 1)
524n/a if len(line) > _MAXLINE:
525n/a raise LineTooLong("trailer line")
526n/a if not line:
527n/a # a vanishingly small number of sites EOF without
528n/a # sending the trailer
529n/a break
530n/a if line in (b'\r\n', b'\n', b''):
531n/a break
532n/a
533n/a def _get_chunk_left(self):
534n/a # return self.chunk_left, reading a new chunk if necessary.
535n/a # chunk_left == 0: at the end of the current chunk, need to close it
536n/a # chunk_left == None: No current chunk, should read next.
537n/a # This function returns non-zero or None if the last chunk has
538n/a # been read.
539n/a chunk_left = self.chunk_left
540n/a if not chunk_left: # Can be 0 or None
541n/a if chunk_left is not None:
542n/a # We are at the end of chunk. dicard chunk end
543n/a self._safe_read(2) # toss the CRLF at the end of the chunk
544n/a try:
545n/a chunk_left = self._read_next_chunk_size()
546n/a except ValueError:
547n/a raise IncompleteRead(b'')
548n/a if chunk_left == 0:
549n/a # last chunk: 1*("0") [ chunk-extension ] CRLF
550n/a self._read_and_discard_trailer()
551n/a # we read everything; close the "file"
552n/a self._close_conn()
553n/a chunk_left = None
554n/a self.chunk_left = chunk_left
555n/a return chunk_left
556n/a
557n/a def _readall_chunked(self):
558n/a assert self.chunked != _UNKNOWN
559n/a value = []
560n/a try:
561n/a while True:
562n/a chunk_left = self._get_chunk_left()
563n/a if chunk_left is None:
564n/a break
565n/a value.append(self._safe_read(chunk_left))
566n/a self.chunk_left = 0
567n/a return b''.join(value)
568n/a except IncompleteRead:
569n/a raise IncompleteRead(b''.join(value))
570n/a
571n/a def _readinto_chunked(self, b):
572n/a assert self.chunked != _UNKNOWN
573n/a total_bytes = 0
574n/a mvb = memoryview(b)
575n/a try:
576n/a while True:
577n/a chunk_left = self._get_chunk_left()
578n/a if chunk_left is None:
579n/a return total_bytes
580n/a
581n/a if len(mvb) <= chunk_left:
582n/a n = self._safe_readinto(mvb)
583n/a self.chunk_left = chunk_left - n
584n/a return total_bytes + n
585n/a
586n/a temp_mvb = mvb[:chunk_left]
587n/a n = self._safe_readinto(temp_mvb)
588n/a mvb = mvb[n:]
589n/a total_bytes += n
590n/a self.chunk_left = 0
591n/a
592n/a except IncompleteRead:
593n/a raise IncompleteRead(bytes(b[0:total_bytes]))
594n/a
595n/a def _safe_read(self, amt):
596n/a """Read the number of bytes requested, compensating for partial reads.
597n/a
598n/a Normally, we have a blocking socket, but a read() can be interrupted
599n/a by a signal (resulting in a partial read).
600n/a
601n/a Note that we cannot distinguish between EOF and an interrupt when zero
602n/a bytes have been read. IncompleteRead() will be raised in this
603n/a situation.
604n/a
605n/a This function should be used when <amt> bytes "should" be present for
606n/a reading. If the bytes are truly not available (due to EOF), then the
607n/a IncompleteRead exception can be used to detect the problem.
608n/a """
609n/a s = []
610n/a while amt > 0:
611n/a chunk = self.fp.read(min(amt, MAXAMOUNT))
612n/a if not chunk:
613n/a raise IncompleteRead(b''.join(s), amt)
614n/a s.append(chunk)
615n/a amt -= len(chunk)
616n/a return b"".join(s)
617n/a
618n/a def _safe_readinto(self, b):
619n/a """Same as _safe_read, but for reading into a buffer."""
620n/a total_bytes = 0
621n/a mvb = memoryview(b)
622n/a while total_bytes < len(b):
623n/a if MAXAMOUNT < len(mvb):
624n/a temp_mvb = mvb[0:MAXAMOUNT]
625n/a n = self.fp.readinto(temp_mvb)
626n/a else:
627n/a n = self.fp.readinto(mvb)
628n/a if not n:
629n/a raise IncompleteRead(bytes(mvb[0:total_bytes]), len(b))
630n/a mvb = mvb[n:]
631n/a total_bytes += n
632n/a return total_bytes
633n/a
634n/a def read1(self, n=-1):
635n/a """Read with at most one underlying system call. If at least one
636n/a byte is buffered, return that instead.
637n/a """
638n/a if self.fp is None or self._method == "HEAD":
639n/a return b""
640n/a if self.chunked:
641n/a return self._read1_chunked(n)
642n/a if self.length is not None and (n < 0 or n > self.length):
643n/a n = self.length
644n/a result = self.fp.read1(n)
645n/a if not result and n:
646n/a self._close_conn()
647n/a elif self.length is not None:
648n/a self.length -= len(result)
649n/a return result
650n/a
651n/a def peek(self, n=-1):
652n/a # Having this enables IOBase.readline() to read more than one
653n/a # byte at a time
654n/a if self.fp is None or self._method == "HEAD":
655n/a return b""
656n/a if self.chunked:
657n/a return self._peek_chunked(n)
658n/a return self.fp.peek(n)
659n/a
660n/a def readline(self, limit=-1):
661n/a if self.fp is None or self._method == "HEAD":
662n/a return b""
663n/a if self.chunked:
664n/a # Fallback to IOBase readline which uses peek() and read()
665n/a return super().readline(limit)
666n/a if self.length is not None and (limit < 0 or limit > self.length):
667n/a limit = self.length
668n/a result = self.fp.readline(limit)
669n/a if not result and limit:
670n/a self._close_conn()
671n/a elif self.length is not None:
672n/a self.length -= len(result)
673n/a return result
674n/a
675n/a def _read1_chunked(self, n):
676n/a # Strictly speaking, _get_chunk_left() may cause more than one read,
677n/a # but that is ok, since that is to satisfy the chunked protocol.
678n/a chunk_left = self._get_chunk_left()
679n/a if chunk_left is None or n == 0:
680n/a return b''
681n/a if not (0 <= n <= chunk_left):
682n/a n = chunk_left # if n is negative or larger than chunk_left
683n/a read = self.fp.read1(n)
684n/a self.chunk_left -= len(read)
685n/a if not read:
686n/a raise IncompleteRead(b"")
687n/a return read
688n/a
689n/a def _peek_chunked(self, n):
690n/a # Strictly speaking, _get_chunk_left() may cause more than one read,
691n/a # but that is ok, since that is to satisfy the chunked protocol.
692n/a try:
693n/a chunk_left = self._get_chunk_left()
694n/a except IncompleteRead:
695n/a return b'' # peek doesn't worry about protocol
696n/a if chunk_left is None:
697n/a return b'' # eof
698n/a # peek is allowed to return more than requested. Just request the
699n/a # entire chunk, and truncate what we get.
700n/a return self.fp.peek(chunk_left)[:chunk_left]
701n/a
702n/a def fileno(self):
703n/a return self.fp.fileno()
704n/a
705n/a def getheader(self, name, default=None):
706n/a '''Returns the value of the header matching *name*.
707n/a
708n/a If there are multiple matching headers, the values are
709n/a combined into a single string separated by commas and spaces.
710n/a
711n/a If no matching header is found, returns *default* or None if
712n/a the *default* is not specified.
713n/a
714n/a If the headers are unknown, raises http.client.ResponseNotReady.
715n/a
716n/a '''
717n/a if self.headers is None:
718n/a raise ResponseNotReady()
719n/a headers = self.headers.get_all(name) or default
720n/a if isinstance(headers, str) or not hasattr(headers, '__iter__'):
721n/a return headers
722n/a else:
723n/a return ', '.join(headers)
724n/a
725n/a def getheaders(self):
726n/a """Return list of (header, value) tuples."""
727n/a if self.headers is None:
728n/a raise ResponseNotReady()
729n/a return list(self.headers.items())
730n/a
731n/a # We override IOBase.__iter__ so that it doesn't check for closed-ness
732n/a
733n/a def __iter__(self):
734n/a return self
735n/a
736n/a # For compatibility with old-style urllib responses.
737n/a
738n/a def info(self):
739n/a '''Returns an instance of the class mimetools.Message containing
740n/a meta-information associated with the URL.
741n/a
742n/a When the method is HTTP, these headers are those returned by
743n/a the server at the head of the retrieved HTML page (including
744n/a Content-Length and Content-Type).
745n/a
746n/a When the method is FTP, a Content-Length header will be
747n/a present if (as is now usual) the server passed back a file
748n/a length in response to the FTP retrieval request. A
749n/a Content-Type header will be present if the MIME type can be
750n/a guessed.
751n/a
752n/a When the method is local-file, returned headers will include
753n/a a Date representing the file's last-modified time, a
754n/a Content-Length giving file size, and a Content-Type
755n/a containing a guess at the file's type. See also the
756n/a description of the mimetools module.
757n/a
758n/a '''
759n/a return self.headers
760n/a
761n/a def geturl(self):
762n/a '''Return the real URL of the page.
763n/a
764n/a In some cases, the HTTP server redirects a client to another
765n/a URL. The urlopen() function handles this transparently, but in
766n/a some cases the caller needs to know which URL the client was
767n/a redirected to. The geturl() method can be used to get at this
768n/a redirected URL.
769n/a
770n/a '''
771n/a return self.url
772n/a
773n/a def getcode(self):
774n/a '''Return the HTTP status code that was sent with the response,
775n/a or None if the URL is not an HTTP URL.
776n/a
777n/a '''
778n/a return self.status
779n/a
780n/aclass HTTPConnection:
781n/a
782n/a _http_vsn = 11
783n/a _http_vsn_str = 'HTTP/1.1'
784n/a
785n/a response_class = HTTPResponse
786n/a default_port = HTTP_PORT
787n/a auto_open = 1
788n/a debuglevel = 0
789n/a
790n/a @staticmethod
791n/a def _is_textIO(stream):
792n/a """Test whether a file-like object is a text or a binary stream.
793n/a """
794n/a return isinstance(stream, io.TextIOBase)
795n/a
796n/a @staticmethod
797n/a def _get_content_length(body, method):
798n/a """Get the content-length based on the body.
799n/a
800n/a If the body is None, we set Content-Length: 0 for methods that expect
801n/a a body (RFC 7230, Section 3.3.2). We also set the Content-Length for
802n/a any method if the body is a str or bytes-like object and not a file.
803n/a """
804n/a if body is None:
805n/a # do an explicit check for not None here to distinguish
806n/a # between unset and set but empty
807n/a if method.upper() in _METHODS_EXPECTING_BODY:
808n/a return 0
809n/a else:
810n/a return None
811n/a
812n/a if hasattr(body, 'read'):
813n/a # file-like object.
814n/a return None
815n/a
816n/a try:
817n/a # does it implement the buffer protocol (bytes, bytearray, array)?
818n/a mv = memoryview(body)
819n/a return mv.nbytes
820n/a except TypeError:
821n/a pass
822n/a
823n/a if isinstance(body, str):
824n/a return len(body)
825n/a
826n/a return None
827n/a
828n/a def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
829n/a source_address=None):
830n/a self.timeout = timeout
831n/a self.source_address = source_address
832n/a self.sock = None
833n/a self._buffer = []
834n/a self.__response = None
835n/a self.__state = _CS_IDLE
836n/a self._method = None
837n/a self._tunnel_host = None
838n/a self._tunnel_port = None
839n/a self._tunnel_headers = {}
840n/a
841n/a (self.host, self.port) = self._get_hostport(host, port)
842n/a
843n/a # This is stored as an instance variable to allow unit
844n/a # tests to replace it with a suitable mockup
845n/a self._create_connection = socket.create_connection
846n/a
847n/a def set_tunnel(self, host, port=None, headers=None):
848n/a """Set up host and port for HTTP CONNECT tunnelling.
849n/a
850n/a In a connection that uses HTTP CONNECT tunneling, the host passed to the
851n/a constructor is used as a proxy server that relays all communication to
852n/a the endpoint passed to `set_tunnel`. This done by sending an HTTP
853n/a CONNECT request to the proxy server when the connection is established.
854n/a
855n/a This method must be called before the HTML connection has been
856n/a established.
857n/a
858n/a The headers argument should be a mapping of extra HTTP headers to send
859n/a with the CONNECT request.
860n/a """
861n/a
862n/a if self.sock:
863n/a raise RuntimeError("Can't set up tunnel for established connection")
864n/a
865n/a self._tunnel_host, self._tunnel_port = self._get_hostport(host, port)
866n/a if headers:
867n/a self._tunnel_headers = headers
868n/a else:
869n/a self._tunnel_headers.clear()
870n/a
871n/a def _get_hostport(self, host, port):
872n/a if port is None:
873n/a i = host.rfind(':')
874n/a j = host.rfind(']') # ipv6 addresses have [...]
875n/a if i > j:
876n/a try:
877n/a port = int(host[i+1:])
878n/a except ValueError:
879n/a if host[i+1:] == "": # http://foo.com:/ == http://foo.com/
880n/a port = self.default_port
881n/a else:
882n/a raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
883n/a host = host[:i]
884n/a else:
885n/a port = self.default_port
886n/a if host and host[0] == '[' and host[-1] == ']':
887n/a host = host[1:-1]
888n/a
889n/a return (host, port)
890n/a
891n/a def set_debuglevel(self, level):
892n/a self.debuglevel = level
893n/a
894n/a def _tunnel(self):
895n/a connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host,
896n/a self._tunnel_port)
897n/a connect_bytes = connect_str.encode("ascii")
898n/a self.send(connect_bytes)
899n/a for header, value in self._tunnel_headers.items():
900n/a header_str = "%s: %s\r\n" % (header, value)
901n/a header_bytes = header_str.encode("latin-1")
902n/a self.send(header_bytes)
903n/a self.send(b'\r\n')
904n/a
905n/a response = self.response_class(self.sock, method=self._method)
906n/a (version, code, message) = response._read_status()
907n/a
908n/a if code != http.HTTPStatus.OK:
909n/a self.close()
910n/a raise OSError("Tunnel connection failed: %d %s" % (code,
911n/a message.strip()))
912n/a while True:
913n/a line = response.fp.readline(_MAXLINE + 1)
914n/a if len(line) > _MAXLINE:
915n/a raise LineTooLong("header line")
916n/a if not line:
917n/a # for sites which EOF without sending a trailer
918n/a break
919n/a if line in (b'\r\n', b'\n', b''):
920n/a break
921n/a
922n/a if self.debuglevel > 0:
923n/a print('header:', line.decode())
924n/a
925n/a def connect(self):
926n/a """Connect to the host and port specified in __init__."""
927n/a self.sock = self._create_connection(
928n/a (self.host,self.port), self.timeout, self.source_address)
929n/a self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
930n/a
931n/a if self._tunnel_host:
932n/a self._tunnel()
933n/a
934n/a def close(self):
935n/a """Close the connection to the HTTP server."""
936n/a self.__state = _CS_IDLE
937n/a try:
938n/a sock = self.sock
939n/a if sock:
940n/a self.sock = None
941n/a sock.close() # close it manually... there may be other refs
942n/a finally:
943n/a response = self.__response
944n/a if response:
945n/a self.__response = None
946n/a response.close()
947n/a
948n/a def send(self, data):
949n/a """Send `data' to the server.
950n/a ``data`` can be a string object, a bytes object, an array object, a
951n/a file-like object that supports a .read() method, or an iterable object.
952n/a """
953n/a
954n/a if self.sock is None:
955n/a if self.auto_open:
956n/a self.connect()
957n/a else:
958n/a raise NotConnected()
959n/a
960n/a if self.debuglevel > 0:
961n/a print("send:", repr(data))
962n/a blocksize = 8192
963n/a if hasattr(data, "read") :
964n/a if self.debuglevel > 0:
965n/a print("sendIng a read()able")
966n/a encode = self._is_textIO(data)
967n/a if encode and self.debuglevel > 0:
968n/a print("encoding file using iso-8859-1")
969n/a while 1:
970n/a datablock = data.read(blocksize)
971n/a if not datablock:
972n/a break
973n/a if encode:
974n/a datablock = datablock.encode("iso-8859-1")
975n/a self.sock.sendall(datablock)
976n/a return
977n/a try:
978n/a self.sock.sendall(data)
979n/a except TypeError:
980n/a if isinstance(data, collections.Iterable):
981n/a for d in data:
982n/a self.sock.sendall(d)
983n/a else:
984n/a raise TypeError("data should be a bytes-like object "
985n/a "or an iterable, got %r" % type(data))
986n/a
987n/a def _output(self, s):
988n/a """Add a line of output to the current request buffer.
989n/a
990n/a Assumes that the line does *not* end with \\r\\n.
991n/a """
992n/a self._buffer.append(s)
993n/a
994n/a def _read_readable(self, readable):
995n/a blocksize = 8192
996n/a if self.debuglevel > 0:
997n/a print("sendIng a read()able")
998n/a encode = self._is_textIO(readable)
999n/a if encode and self.debuglevel > 0:
1000n/a print("encoding file using iso-8859-1")
1001n/a while True:
1002n/a datablock = readable.read(blocksize)
1003n/a if not datablock:
1004n/a break
1005n/a if encode:
1006n/a datablock = datablock.encode("iso-8859-1")
1007n/a yield datablock
1008n/a
1009n/a def _send_output(self, message_body=None, encode_chunked=False):
1010n/a """Send the currently buffered request and clear the buffer.
1011n/a
1012n/a Appends an extra \\r\\n to the buffer.
1013n/a A message_body may be specified, to be appended to the request.
1014n/a """
1015n/a self._buffer.extend((b"", b""))
1016n/a msg = b"\r\n".join(self._buffer)
1017n/a del self._buffer[:]
1018n/a self.send(msg)
1019n/a
1020n/a if message_body is not None:
1021n/a
1022n/a # create a consistent interface to message_body
1023n/a if hasattr(message_body, 'read'):
1024n/a # Let file-like take precedence over byte-like. This
1025n/a # is needed to allow the current position of mmap'ed
1026n/a # files to be taken into account.
1027n/a chunks = self._read_readable(message_body)
1028n/a else:
1029n/a try:
1030n/a # this is solely to check to see if message_body
1031n/a # implements the buffer API. it /would/ be easier
1032n/a # to capture if PyObject_CheckBuffer was exposed
1033n/a # to Python.
1034n/a memoryview(message_body)
1035n/a except TypeError:
1036n/a try:
1037n/a chunks = iter(message_body)
1038n/a except TypeError:
1039n/a raise TypeError("message_body should be a bytes-like "
1040n/a "object or an iterable, got %r"
1041n/a % type(message_body))
1042n/a else:
1043n/a # the object implements the buffer interface and
1044n/a # can be passed directly into socket methods
1045n/a chunks = (message_body,)
1046n/a
1047n/a for chunk in chunks:
1048n/a if not chunk:
1049n/a if self.debuglevel > 0:
1050n/a print('Zero length chunk ignored')
1051n/a continue
1052n/a
1053n/a if encode_chunked and self._http_vsn == 11:
1054n/a # chunked encoding
1055n/a chunk = f'{len(chunk):X}\r\n'.encode('ascii') + chunk \
1056n/a + b'\r\n'
1057n/a self.send(chunk)
1058n/a
1059n/a if encode_chunked and self._http_vsn == 11:
1060n/a # end chunked transfer
1061n/a self.send(b'0\r\n\r\n')
1062n/a
1063n/a def putrequest(self, method, url, skip_host=False,
1064n/a skip_accept_encoding=False):
1065n/a """Send a request to the server.
1066n/a
1067n/a `method' specifies an HTTP request method, e.g. 'GET'.
1068n/a `url' specifies the object being requested, e.g. '/index.html'.
1069n/a `skip_host' if True does not add automatically a 'Host:' header
1070n/a `skip_accept_encoding' if True does not add automatically an
1071n/a 'Accept-Encoding:' header
1072n/a """
1073n/a
1074n/a # if a prior response has been completed, then forget about it.
1075n/a if self.__response and self.__response.isclosed():
1076n/a self.__response = None
1077n/a
1078n/a
1079n/a # in certain cases, we cannot issue another request on this connection.
1080n/a # this occurs when:
1081n/a # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
1082n/a # 2) a response to a previous request has signalled that it is going
1083n/a # to close the connection upon completion.
1084n/a # 3) the headers for the previous response have not been read, thus
1085n/a # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
1086n/a #
1087n/a # if there is no prior response, then we can request at will.
1088n/a #
1089n/a # if point (2) is true, then we will have passed the socket to the
1090n/a # response (effectively meaning, "there is no prior response"), and
1091n/a # will open a new one when a new request is made.
1092n/a #
1093n/a # Note: if a prior response exists, then we *can* start a new request.
1094n/a # We are not allowed to begin fetching the response to this new
1095n/a # request, however, until that prior response is complete.
1096n/a #
1097n/a if self.__state == _CS_IDLE:
1098n/a self.__state = _CS_REQ_STARTED
1099n/a else:
1100n/a raise CannotSendRequest(self.__state)
1101n/a
1102n/a # Save the method we use, we need it later in the response phase
1103n/a self._method = method
1104n/a if not url:
1105n/a url = '/'
1106n/a request = '%s %s %s' % (method, url, self._http_vsn_str)
1107n/a
1108n/a # Non-ASCII characters should have been eliminated earlier
1109n/a self._output(request.encode('ascii'))
1110n/a
1111n/a if self._http_vsn == 11:
1112n/a # Issue some standard headers for better HTTP/1.1 compliance
1113n/a
1114n/a if not skip_host:
1115n/a # this header is issued *only* for HTTP/1.1
1116n/a # connections. more specifically, this means it is
1117n/a # only issued when the client uses the new
1118n/a # HTTPConnection() class. backwards-compat clients
1119n/a # will be using HTTP/1.0 and those clients may be
1120n/a # issuing this header themselves. we should NOT issue
1121n/a # it twice; some web servers (such as Apache) barf
1122n/a # when they see two Host: headers
1123n/a
1124n/a # If we need a non-standard port,include it in the
1125n/a # header. If the request is going through a proxy,
1126n/a # but the host of the actual URL, not the host of the
1127n/a # proxy.
1128n/a
1129n/a netloc = ''
1130n/a if url.startswith('http'):
1131n/a nil, netloc, nil, nil, nil = urlsplit(url)
1132n/a
1133n/a if netloc:
1134n/a try:
1135n/a netloc_enc = netloc.encode("ascii")
1136n/a except UnicodeEncodeError:
1137n/a netloc_enc = netloc.encode("idna")
1138n/a self.putheader('Host', netloc_enc)
1139n/a else:
1140n/a if self._tunnel_host:
1141n/a host = self._tunnel_host
1142n/a port = self._tunnel_port
1143n/a else:
1144n/a host = self.host
1145n/a port = self.port
1146n/a
1147n/a try:
1148n/a host_enc = host.encode("ascii")
1149n/a except UnicodeEncodeError:
1150n/a host_enc = host.encode("idna")
1151n/a
1152n/a # As per RFC 273, IPv6 address should be wrapped with []
1153n/a # when used as Host header
1154n/a
1155n/a if host.find(':') >= 0:
1156n/a host_enc = b'[' + host_enc + b']'
1157n/a
1158n/a if port == self.default_port:
1159n/a self.putheader('Host', host_enc)
1160n/a else:
1161n/a host_enc = host_enc.decode("ascii")
1162n/a self.putheader('Host', "%s:%s" % (host_enc, port))
1163n/a
1164n/a # note: we are assuming that clients will not attempt to set these
1165n/a # headers since *this* library must deal with the
1166n/a # consequences. this also means that when the supporting
1167n/a # libraries are updated to recognize other forms, then this
1168n/a # code should be changed (removed or updated).
1169n/a
1170n/a # we only want a Content-Encoding of "identity" since we don't
1171n/a # support encodings such as x-gzip or x-deflate.
1172n/a if not skip_accept_encoding:
1173n/a self.putheader('Accept-Encoding', 'identity')
1174n/a
1175n/a # we can accept "chunked" Transfer-Encodings, but no others
1176n/a # NOTE: no TE header implies *only* "chunked"
1177n/a #self.putheader('TE', 'chunked')
1178n/a
1179n/a # if TE is supplied in the header, then it must appear in a
1180n/a # Connection header.
1181n/a #self.putheader('Connection', 'TE')
1182n/a
1183n/a else:
1184n/a # For HTTP/1.0, the server will assume "not chunked"
1185n/a pass
1186n/a
1187n/a def putheader(self, header, *values):
1188n/a """Send a request header line to the server.
1189n/a
1190n/a For example: h.putheader('Accept', 'text/html')
1191n/a """
1192n/a if self.__state != _CS_REQ_STARTED:
1193n/a raise CannotSendHeader()
1194n/a
1195n/a if hasattr(header, 'encode'):
1196n/a header = header.encode('ascii')
1197n/a
1198n/a if not _is_legal_header_name(header):
1199n/a raise ValueError('Invalid header name %r' % (header,))
1200n/a
1201n/a values = list(values)
1202n/a for i, one_value in enumerate(values):
1203n/a if hasattr(one_value, 'encode'):
1204n/a values[i] = one_value.encode('latin-1')
1205n/a elif isinstance(one_value, int):
1206n/a values[i] = str(one_value).encode('ascii')
1207n/a
1208n/a if _is_illegal_header_value(values[i]):
1209n/a raise ValueError('Invalid header value %r' % (values[i],))
1210n/a
1211n/a value = b'\r\n\t'.join(values)
1212n/a header = header + b': ' + value
1213n/a self._output(header)
1214n/a
1215n/a def endheaders(self, message_body=None, *, encode_chunked=False):
1216n/a """Indicate that the last header line has been sent to the server.
1217n/a
1218n/a This method sends the request to the server. The optional message_body
1219n/a argument can be used to pass a message body associated with the
1220n/a request.
1221n/a """
1222n/a if self.__state == _CS_REQ_STARTED:
1223n/a self.__state = _CS_REQ_SENT
1224n/a else:
1225n/a raise CannotSendHeader()
1226n/a self._send_output(message_body, encode_chunked=encode_chunked)
1227n/a
1228n/a def request(self, method, url, body=None, headers={}, *,
1229n/a encode_chunked=False):
1230n/a """Send a complete request to the server."""
1231n/a self._send_request(method, url, body, headers, encode_chunked)
1232n/a
1233n/a def _send_request(self, method, url, body, headers, encode_chunked):
1234n/a # Honor explicitly requested Host: and Accept-Encoding: headers.
1235n/a header_names = frozenset(k.lower() for k in headers)
1236n/a skips = {}
1237n/a if 'host' in header_names:
1238n/a skips['skip_host'] = 1
1239n/a if 'accept-encoding' in header_names:
1240n/a skips['skip_accept_encoding'] = 1
1241n/a
1242n/a self.putrequest(method, url, **skips)
1243n/a
1244n/a # chunked encoding will happen if HTTP/1.1 is used and either
1245n/a # the caller passes encode_chunked=True or the following
1246n/a # conditions hold:
1247n/a # 1. content-length has not been explicitly set
1248n/a # 2. the body is a file or iterable, but not a str or bytes-like
1249n/a # 3. Transfer-Encoding has NOT been explicitly set by the caller
1250n/a
1251n/a if 'content-length' not in header_names:
1252n/a # only chunk body if not explicitly set for backwards
1253n/a # compatibility, assuming the client code is already handling the
1254n/a # chunking
1255n/a if 'transfer-encoding' not in header_names:
1256n/a # if content-length cannot be automatically determined, fall
1257n/a # back to chunked encoding
1258n/a encode_chunked = False
1259n/a content_length = self._get_content_length(body, method)
1260n/a if content_length is None:
1261n/a if body is not None:
1262n/a if self.debuglevel > 0:
1263n/a print('Unable to determine size of %r' % body)
1264n/a encode_chunked = True
1265n/a self.putheader('Transfer-Encoding', 'chunked')
1266n/a else:
1267n/a self.putheader('Content-Length', str(content_length))
1268n/a else:
1269n/a encode_chunked = False
1270n/a
1271n/a for hdr, value in headers.items():
1272n/a self.putheader(hdr, value)
1273n/a if isinstance(body, str):
1274n/a # RFC 2616 Section 3.7.1 says that text default has a
1275n/a # default charset of iso-8859-1.
1276n/a body = _encode(body, 'body')
1277n/a self.endheaders(body, encode_chunked=encode_chunked)
1278n/a
1279n/a def getresponse(self):
1280n/a """Get the response from the server.
1281n/a
1282n/a If the HTTPConnection is in the correct state, returns an
1283n/a instance of HTTPResponse or of whatever object is returned by
1284n/a the response_class variable.
1285n/a
1286n/a If a request has not been sent or if a previous response has
1287n/a not be handled, ResponseNotReady is raised. If the HTTP
1288n/a response indicates that the connection should be closed, then
1289n/a it will be closed before the response is returned. When the
1290n/a connection is closed, the underlying socket is closed.
1291n/a """
1292n/a
1293n/a # if a prior response has been completed, then forget about it.
1294n/a if self.__response and self.__response.isclosed():
1295n/a self.__response = None
1296n/a
1297n/a # if a prior response exists, then it must be completed (otherwise, we
1298n/a # cannot read this response's header to determine the connection-close
1299n/a # behavior)
1300n/a #
1301n/a # note: if a prior response existed, but was connection-close, then the
1302n/a # socket and response were made independent of this HTTPConnection
1303n/a # object since a new request requires that we open a whole new
1304n/a # connection
1305n/a #
1306n/a # this means the prior response had one of two states:
1307n/a # 1) will_close: this connection was reset and the prior socket and
1308n/a # response operate independently
1309n/a # 2) persistent: the response was retained and we await its
1310n/a # isclosed() status to become true.
1311n/a #
1312n/a if self.__state != _CS_REQ_SENT or self.__response:
1313n/a raise ResponseNotReady(self.__state)
1314n/a
1315n/a if self.debuglevel > 0:
1316n/a response = self.response_class(self.sock, self.debuglevel,
1317n/a method=self._method)
1318n/a else:
1319n/a response = self.response_class(self.sock, method=self._method)
1320n/a
1321n/a try:
1322n/a try:
1323n/a response.begin()
1324n/a except ConnectionError:
1325n/a self.close()
1326n/a raise
1327n/a assert response.will_close != _UNKNOWN
1328n/a self.__state = _CS_IDLE
1329n/a
1330n/a if response.will_close:
1331n/a # this effectively passes the connection to the response
1332n/a self.close()
1333n/a else:
1334n/a # remember this, so we can tell when it is complete
1335n/a self.__response = response
1336n/a
1337n/a return response
1338n/a except:
1339n/a response.close()
1340n/a raise
1341n/a
1342n/atry:
1343n/a import ssl
1344n/aexcept ImportError:
1345n/a pass
1346n/aelse:
1347n/a class HTTPSConnection(HTTPConnection):
1348n/a "This class allows communication via SSL."
1349n/a
1350n/a default_port = HTTPS_PORT
1351n/a
1352n/a # XXX Should key_file and cert_file be deprecated in favour of context?
1353n/a
1354n/a def __init__(self, host, port=None, key_file=None, cert_file=None,
1355n/a timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
1356n/a source_address=None, *, context=None,
1357n/a check_hostname=None):
1358n/a super(HTTPSConnection, self).__init__(host, port, timeout,
1359n/a source_address)
1360n/a if (key_file is not None or cert_file is not None or
1361n/a check_hostname is not None):
1362n/a import warnings
1363n/a warnings.warn("key_file, cert_file and check_hostname are "
1364n/a "deprecated, use a custom context instead.",
1365n/a DeprecationWarning, 2)
1366n/a self.key_file = key_file
1367n/a self.cert_file = cert_file
1368n/a if context is None:
1369n/a context = ssl._create_default_https_context()
1370n/a will_verify = context.verify_mode != ssl.CERT_NONE
1371n/a if check_hostname is None:
1372n/a check_hostname = context.check_hostname
1373n/a if check_hostname and not will_verify:
1374n/a raise ValueError("check_hostname needs a SSL context with "
1375n/a "either CERT_OPTIONAL or CERT_REQUIRED")
1376n/a if key_file or cert_file:
1377n/a context.load_cert_chain(cert_file, key_file)
1378n/a self._context = context
1379n/a self._check_hostname = check_hostname
1380n/a
1381n/a def connect(self):
1382n/a "Connect to a host on a given (SSL) port."
1383n/a
1384n/a super().connect()
1385n/a
1386n/a if self._tunnel_host:
1387n/a server_hostname = self._tunnel_host
1388n/a else:
1389n/a server_hostname = self.host
1390n/a
1391n/a self.sock = self._context.wrap_socket(self.sock,
1392n/a server_hostname=server_hostname)
1393n/a if not self._context.check_hostname and self._check_hostname:
1394n/a try:
1395n/a ssl.match_hostname(self.sock.getpeercert(), server_hostname)
1396n/a except Exception:
1397n/a self.sock.shutdown(socket.SHUT_RDWR)
1398n/a self.sock.close()
1399n/a raise
1400n/a
1401n/a __all__.append("HTTPSConnection")
1402n/a
1403n/aclass HTTPException(Exception):
1404n/a # Subclasses that define an __init__ must call Exception.__init__
1405n/a # or define self.args. Otherwise, str() will fail.
1406n/a pass
1407n/a
1408n/aclass NotConnected(HTTPException):
1409n/a pass
1410n/a
1411n/aclass InvalidURL(HTTPException):
1412n/a pass
1413n/a
1414n/aclass UnknownProtocol(HTTPException):
1415n/a def __init__(self, version):
1416n/a self.args = version,
1417n/a self.version = version
1418n/a
1419n/aclass UnknownTransferEncoding(HTTPException):
1420n/a pass
1421n/a
1422n/aclass UnimplementedFileMode(HTTPException):
1423n/a pass
1424n/a
1425n/aclass IncompleteRead(HTTPException):
1426n/a def __init__(self, partial, expected=None):
1427n/a self.args = partial,
1428n/a self.partial = partial
1429n/a self.expected = expected
1430n/a def __repr__(self):
1431n/a if self.expected is not None:
1432n/a e = ', %i more expected' % self.expected
1433n/a else:
1434n/a e = ''
1435n/a return '%s(%i bytes read%s)' % (self.__class__.__name__,
1436n/a len(self.partial), e)
1437n/a def __str__(self):
1438n/a return repr(self)
1439n/a
1440n/aclass ImproperConnectionState(HTTPException):
1441n/a pass
1442n/a
1443n/aclass CannotSendRequest(ImproperConnectionState):
1444n/a pass
1445n/a
1446n/aclass CannotSendHeader(ImproperConnectionState):
1447n/a pass
1448n/a
1449n/aclass ResponseNotReady(ImproperConnectionState):
1450n/a pass
1451n/a
1452n/aclass BadStatusLine(HTTPException):
1453n/a def __init__(self, line):
1454n/a if not line:
1455n/a line = repr(line)
1456n/a self.args = line,
1457n/a self.line = line
1458n/a
1459n/aclass LineTooLong(HTTPException):
1460n/a def __init__(self, line_type):
1461n/a HTTPException.__init__(self, "got more than %d bytes when reading %s"
1462n/a % (_MAXLINE, line_type))
1463n/a
1464n/aclass RemoteDisconnected(ConnectionResetError, BadStatusLine):
1465n/a def __init__(self, *pos, **kw):
1466n/a BadStatusLine.__init__(self, "")
1467n/a ConnectionResetError.__init__(self, *pos, **kw)
1468n/a
1469n/a# for backwards compatibility
1470n/aerror = HTTPException