[Python-modules-commits] [pytest-httpbin] 01/14: Import pytest-httpbin_0.2.0.orig.tar.xz

Daniel Stender danstender-guest at moszumanska.debian.org
Fri Mar 18 08:16:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

danstender-guest pushed a commit to branch master
in repository pytest-httpbin.

commit 3dadf8e2bea17bf5a7f01c51a2aa5ac413c304ad
Author: Daniel Stender <stender at debian.org>
Date:   Thu Mar 17 20:31:57 2016 +0100

    Import pytest-httpbin_0.2.0.orig.tar.xz
---
 MANIFEST.in               |  1 +
 README.md                 |  5 +++
 pytest_httpbin/serve.py   | 88 ++++++++++++++++++++++++++++++-----------------
 pytest_httpbin/version.py |  2 +-
 tests/test_server.py      | 22 ++++--------
 5 files changed, 69 insertions(+), 49 deletions(-)

diff --git a/MANIFEST.in b/MANIFEST.in
index 68a01e1..4104865 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,4 @@
 # If using Python 2.6 or less, then have to include package data, even though
 # it's already declared in setup.py
 include pytest_httpbin/certs/*
+include DESCRIPTION.rst
diff --git a/README.md b/README.md
index 03c4adb..c09c2ef 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,11 @@ tox
 
 ## Changelog
 
+* 0.2.0:
+  * Remove threaded HTTP server.  I built it for Requests, but they deleted
+    their threaded test since it didn't really work very well.  The threaded
+    server seems to cause some strange problems with HTTP chunking, so I'll
+    just remove it since nobody is using it (I hope)
 * 0.1.1:
   * Fix weird hang with SSL on pypy (again)
 * 0.1.0:
diff --git a/pytest_httpbin/serve.py b/pytest_httpbin/serve.py
index 59a8c17..043e082 100644
--- a/pytest_httpbin/serve.py
+++ b/pytest_httpbin/serve.py
@@ -1,71 +1,94 @@
 import os
-import pytest_httpbin
 import threading
 import ssl
-from werkzeug.serving import ThreadedWSGIServer, load_ssl_context, WSGIRequestHandler
+from wsgiref.simple_server import WSGIServer, make_server, WSGIRequestHandler
+from wsgiref.handlers import SimpleHandler
 from six.moves.urllib.parse import urljoin
 
+
 CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs')
 
+
+class ServerHandler(SimpleHandler):
+
+    server_software = 'Pytest-HTTPBIN/0.1.0'
+    http_version = '1.1'
+
+    def cleanup_headers(self):
+        SimpleHandler.cleanup_headers(self)
+        self.headers['Connection'] = 'Close'
+
+    def close(self):
+        try:
+            self.request_handler.log_request(
+                self.status.split(' ', 1)[0], self.bytes_sent
+            )
+        finally:
+            SimpleHandler.close(self)
+
+
 class Handler(WSGIRequestHandler):
-    server_version = 'pytest-httpbin/' + pytest_httpbin.__version__
 
-    def make_environ(self):
+    def handle(self):
+        """Handle a single HTTP request"""
+
+        self.raw_requestline = self.rfile.readline()
+        if not self.parse_request():  # An error code has been sent, just exit
+            return
+
+        handler = ServerHandler(
+            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
+        )
+        handler.request_handler = self      # backpointer for logging
+        handler.run(self.server.get_app())
+
+    def get_environ(self):
         """
-        werkzeug server adds content-type text/plain to everything, this
+        wsgiref simple server adds content-type text/plain to everything, this
         removes it if it's not actually in the headers.
         """
         # Note: Can't use super since this is an oldstyle class in python 2.x
-        environ = super(Handler, self).make_environ().copy()
+        environ = WSGIRequestHandler.get_environ(self).copy()
         if self.headers.get('content-type') is None:
             del environ['CONTENT_TYPE']
         return environ
 
-class ThreadedWSGIServerWithSSLTimeout(ThreadedWSGIServer):
-    """
-    This whole subclass exists just to set the ssl timeout before wrapping the
-    socket.  That's because on pypy, if there's an SSL failure opening the
-    connection, it will hang forever.
-    """
 
-    def __init__(self, *args, **kwargs):
-        self.protocol = kwargs.pop('protocol')
-        super(ThreadedWSGIServerWithSSLTimeout, self).__init__(*args, **kwargs)
+class SecureWSGIServer(WSGIServer):
 
     def finish_request(self, request, client_address):
         """
         Negotiates SSL and then mimics BaseServer behavior.
         """
-        if self.protocol == 'https':
-            request.settimeout(1.0)
-            ssock = ssl.wrap_socket(
-                request,
-                keyfile=os.path.join(CERT_DIR, 'key.pem'),
-                certfile=os.path.join(CERT_DIR, 'cert.pem'),
-                server_side=True
-            )
-            self.RequestHandlerClass(ssock, client_address, self)
-        else:
-            self.RequestHandlerClass(request, client_address, self)
+        request.settimeout(1.0)
+        ssock = ssl.wrap_socket(
+            request,
+            keyfile=os.path.join(CERT_DIR, 'key.pem'),
+            certfile=os.path.join(CERT_DIR, 'cert.pem'),
+            server_side=True
+        )
+        self.RequestHandlerClass(ssock, client_address, self)
+        # WSGIRequestHandler seems to close the socket for us.
+        # Thanks, WSGIRequestHandler!!
+
 
 class Server(threading.Thread):
     """
     HTTP server running a WSGI application in its own thread.
     """
 
-    def __init__(self, host='127.0.0.1', port=0, application=None, protocol='http', **kwargs):
+    def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
         self.app = application
-        self._server = ThreadedWSGIServerWithSSLTimeout(
+        self._server = make_server(
             host,
             port,
             self.app,
-            handler=Handler,
-            protocol=protocol,
+            handler_class=Handler,
             **kwargs
         )
         self.host = self._server.server_address[0]
         self.port = self._server.server_address[1]
-        self.protocol = protocol
+        self.protocol = 'http'
 
         super(Server, self).__init__(
             name=self.__class__,
@@ -91,5 +114,6 @@ class Server(threading.Thread):
 
 class SecureServer(Server):
     def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
-        super(SecureServer, self).__init__(host, port, application, protocol='https', **kwargs)
+        kwargs['server_class'] = SecureWSGIServer
+        super(SecureServer, self).__init__(host, port, application, **kwargs)
         self.protocol = 'https'
diff --git a/pytest_httpbin/version.py b/pytest_httpbin/version.py
index df9144c..7fd229a 100644
--- a/pytest_httpbin/version.py
+++ b/pytest_httpbin/version.py
@@ -1 +1 @@
-__version__ = '0.1.1'
+__version__ = '0.2.0'
diff --git a/tests/test_server.py b/tests/test_server.py
index 38d5c65..9e27685 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -6,11 +6,6 @@ import requests
 import pytest
 from util import get_raw_http_response
 
-try:
-    from multiprocessing.pool import ThreadPool
-except ImportError:
-    ThreadPool = None
-
 
 def test_content_type_header_not_automatically_added(httpbin):
     """
@@ -35,17 +30,12 @@ def test_unicode_data(httpbin):
     assert resp.json()['data'] == u'оживлённым'
 
 
-
-def test_server_should_handle_concurrent_connections(httpbin):
-    url = httpbin + '/get'
-    session = requests.Session()
-
-    def do_request(i):
-        r = session.get(url)
-    if ThreadPool is not None:
-        pool = ThreadPool(processes=50)
-        pool.map(do_request, range(100))
-
+def test_server_should_be_http_1_1(httpbin):
+    """
+    The server should speak HTTP/1.1 since we live in the future, see issue #6
+    """
+    resp = get_raw_http_response(httpbin.host, httpbin.port, '/get')
+    assert resp.startswith(b'HTTP/1.1')
 
 def test_dont_crash_on_certificate_problems(httpbin_secure):
     with pytest.raises(Exception):

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pytest-httpbin.git



More information about the Python-modules-commits mailing list