|
84 | 84 |
|
85 | 85 | from . import __version__, connections, errors |
86 | 86 | from ._compat import IS_PPC, bton |
87 | | -from .makefile import MakeFile, StreamWriter |
| 87 | +from .makefile import StreamReader, StreamWriter |
88 | 88 | from .workers import threadpool |
89 | 89 |
|
90 | 90 |
|
| 91 | +try: |
| 92 | + from OpenSSL import SSL |
| 93 | +except ImportError: |
| 94 | + SSL = None # OpenSSL not available |
| 95 | + |
| 96 | + |
91 | 97 | __all__ = ( |
92 | 98 | 'ChunkedRFile', |
93 | 99 | 'DropUnderscoreHeaderReader', |
@@ -1276,19 +1282,31 @@ class HTTPConnection: |
1276 | 1282 | # Fields set by ConnectionManager. |
1277 | 1283 | last_used = None |
1278 | 1284 |
|
1279 | | - def __init__(self, server, sock, makefile=MakeFile): |
| 1285 | + def __init__(self, server, sock, makefile=None): |
1280 | 1286 | """Initialize HTTPConnection instance. |
1281 | 1287 |
|
1282 | 1288 | Args: |
1283 | 1289 | server (HTTPServer): web server object receiving this request |
1284 | 1290 | sock (socket._socketobject): the raw socket object (usually |
1285 | 1291 | TCP) for this connection |
1286 | | - makefile (file): a fileobject class for reading from the socket |
| 1292 | + makefile (file): Now deprecated. |
| 1293 | + Used to be a fileobject class for reading from the socket. |
1287 | 1294 | """ |
1288 | 1295 | self.server = server |
1289 | 1296 | self.socket = sock |
1290 | | - self.rfile = makefile(sock, 'rb', self.rbufsize) |
1291 | | - self.wfile = makefile(sock, 'wb', self.wbufsize) |
| 1297 | + |
| 1298 | + if makefile is not None: |
| 1299 | + _warn( |
| 1300 | + 'The `makefile` parameter in creating an `HTTPConnection` ' |
| 1301 | + 'is deprecated and will be removed in a future version. ' |
| 1302 | + 'The connection socket should now be fully wrapped by the ' |
| 1303 | + 'adapter before being passed to this constructor.', |
| 1304 | + DeprecationWarning, |
| 1305 | + stacklevel=2, |
| 1306 | + ) |
| 1307 | + |
| 1308 | + self.rfile = StreamReader(sock, 'rb', self.rbufsize) |
| 1309 | + self.wfile = StreamWriter(sock, 'wb', self.wbufsize) |
1292 | 1310 | self.requests_seen = 0 |
1293 | 1311 |
|
1294 | 1312 | self.peercreds_enabled = self.server.peercreds_enabled |
@@ -1358,12 +1376,8 @@ def communicate(self): # noqa: C901 # FIXME |
1358 | 1376 | def _handle_no_ssl(self, req): |
1359 | 1377 | if not req or req.sent_headers: |
1360 | 1378 | return |
1361 | | - # Unwrap wfile |
1362 | | - try: |
1363 | | - resp_sock = self.socket._sock |
1364 | | - except AttributeError: |
1365 | | - # self.socket is of OpenSSL.SSL.Connection type |
1366 | | - resp_sock = self.socket._socket |
| 1379 | + # Unwrap to get raw TCP socket |
| 1380 | + resp_sock = self.socket._sock |
1367 | 1381 | self.wfile = StreamWriter(resp_sock, 'wb', self.wbufsize) |
1368 | 1382 | msg = ( |
1369 | 1383 | 'The client sent a plain HTTP request, but ' |
@@ -1507,20 +1521,23 @@ def peer_group(self): |
1507 | 1521 |
|
1508 | 1522 | def _close_kernel_socket(self): |
1509 | 1523 | """Terminate the connection at the transport level.""" |
1510 | | - # Honor ``sock_shutdown`` for PyOpenSSL connections. |
1511 | | - shutdown = getattr( |
1512 | | - self.socket, |
1513 | | - 'sock_shutdown', |
1514 | | - self.socket.shutdown, |
1515 | | - ) |
1516 | | - |
1517 | 1524 | try: |
1518 | | - shutdown(socket.SHUT_RDWR) # actually send a TCP FIN |
| 1525 | + self.socket.shutdown(socket.SHUT_RDWR) |
1519 | 1526 | except errors.acceptable_sock_shutdown_exceptions: |
1520 | 1527 | pass |
1521 | 1528 | except socket.error as e: |
1522 | 1529 | if e.errno not in errors.acceptable_sock_shutdown_error_codes: |
1523 | 1530 | raise |
| 1531 | + except Exception as exc: |
| 1532 | + # translate SSL exceptions to FatalSSLAlert |
| 1533 | + if SSL is not None and isinstance( |
| 1534 | + exc, |
| 1535 | + (SSL.Error, SSL.SysCallError), |
| 1536 | + ): |
| 1537 | + raise errors.FatalSSLAlert( |
| 1538 | + 'TLS/SSL connection failure', |
| 1539 | + ) from exc |
| 1540 | + raise # re-raise everything else |
1524 | 1541 |
|
1525 | 1542 |
|
1526 | 1543 | class HTTPServer: |
|
0 commit comments