[Python-checkins] cpython (3.4): add context parameter to HTTPHandler (closes #22788)

benjamin.peterson python-checkins at python.org
Mon Nov 24 03:38:29 CET 2014


https://hg.python.org/cpython/rev/5864ec6ba484
changeset:   93566:5864ec6ba484
branch:      3.4
parent:      93564:060fd5d09063
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun Nov 23 20:36:44 2014 -0600
summary:
  add context parameter to HTTPHandler (closes #22788)

files:
  Doc/library/logging.handlers.rst |  15 ++++++++++-----
  Lib/logging/handlers.py          |   9 +++++++--
  Lib/test/test_logging.py         |  19 +++++--------------
  Misc/NEWS                        |   2 ++
  4 files changed, 24 insertions(+), 21 deletions(-)


diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -839,17 +839,22 @@
 ``POST`` semantics.
 
 
-.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None)
+.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None)
 
    Returns a new instance of the :class:`HTTPHandler` class. The *host* can be
-   of the form ``host:port``, should you need to use a specific port number.
-   If no *method* is specified, ``GET`` is used. If *secure* is true, an HTTPS
-   connection will be used. If *credentials* is specified, it should be a
-   2-tuple consisting of userid and password, which will be placed in an HTTP
+   of the form ``host:port``, should you need to use a specific port number.  If
+   no *method* is specified, ``GET`` is used. If *secure* is true, a HTTPS
+   connection will be used. The *context* parameter may be set to a
+   :class:`ssl.SSLContext` instance to configure the SSL settings used for the
+   HTTPS connection. If *credentials* is specified, it should be a 2-tuple
+   consisting of userid and password, which will be placed in a HTTP
    'Authorization' header using Basic authentication. If you specify
    credentials, you should also specify secure=True so that your userid and
    password are not passed in cleartext across the wire.
 
+   .. versionchanged:: 3.4.3
+      The *context* parameter was added.
+
    .. method:: mapLogRecord(record)
 
       Provides a dictionary, based on ``record``, which is to be URL-encoded
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1089,7 +1089,8 @@
     A class which sends records to a Web server, using either GET or
     POST semantics.
     """
-    def __init__(self, host, url, method="GET", secure=False, credentials=None):
+    def __init__(self, host, url, method="GET", secure=False, credentials=None,
+                 context=None):
         """
         Initialize the instance with the host, the request URL, and the method
         ("GET" or "POST")
@@ -1098,11 +1099,15 @@
         method = method.upper()
         if method not in ["GET", "POST"]:
             raise ValueError("method must be GET or POST")
+        if not secure and context is not None:
+            raise ValueError("context parameter only makes sense "
+                             "with secure=True")
         self.host = host
         self.url = url
         self.method = method
         self.secure = secure
         self.credentials = credentials
+        self.context = context
 
     def mapLogRecord(self, record):
         """
@@ -1122,7 +1127,7 @@
             import http.client, urllib.parse
             host = self.host
             if self.secure:
-                h = http.client.HTTPSConnection(host)
+                h = http.client.HTTPSConnection(host, context=self.context)
             else:
                 h = http.client.HTTPConnection(host)
             url = self.url
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -1667,21 +1667,11 @@
                     localhost_cert = os.path.join(here, "keycert.pem")
                     sslctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
                     sslctx.load_cert_chain(localhost_cert)
-                    # Unfortunately, HTTPHandler doesn't allow us to change the
-                    # SSLContext used by HTTPSConnection, so we have to
-                    # monkeypatch. This can be cleaned up if issue 22788 is
-                    # fixed.
-                    old = ssl._create_default_https_context
-                    def restore_handler():
-                        ssl._create_default_https_context = old
-                    self.addCleanup(restore_handler)
-                    def hack_create_ctx():
-                        ctx = old()
-                        ctx.load_verify_locations(localhost_cert)
-                        return ctx
-                    ssl._create_default_https_context = hack_create_ctx
+
+                    context = ssl.create_default_context(cafile=localhost_cert)
             else:
                 sslctx = None
+                context = None
             self.server = server = TestHTTPServer(addr, self.handle_request,
                                                     0.01, sslctx=sslctx)
             server.start()
@@ -1689,7 +1679,8 @@
             host = 'localhost:%d' % server.server_port
             secure_client = secure and sslctx
             self.h_hdlr = logging.handlers.HTTPHandler(host, '/frob',
-                                                       secure=secure_client)
+                                                       secure=secure_client,
+                                                       context=context)
             self.log_data = None
             root_logger.addHandler(self.h_hdlr)
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -36,6 +36,8 @@
 Library
 -------
 
+- Issue #22788: Add *context* parameter to logging.handlers.HTTPHandler.
+
 - Issue #22921: Allow SSLContext to take the *hostname* parameter even if
   OpenSSL doesn't support SNI.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list