コード例 #1
0
    def test_HTTP11_pipelining(self):
        self.httpserver.protocol = "HTTP/1.1"
        self.PROTOCOL = "HTTP/1.1"

        # Test pipelining. httplib doesn't support this directly.
        self.persistent = True
        conn = self.HTTP_CONN

        # Put request 1
        conn.putrequest("GET", "/hello", skip_host=True)
        conn.putheader("Host", self.HOST)
        conn.endheaders()

        for trial in range(5):
            # Put next request
            conn._output(ntob('GET /hello?%s HTTP/1.1' % trial))
            conn._output(ntob("Host: %s" % self.HOST, 'ascii'))
            conn._send_output()

            # Retrieve previous response
            response = conn.response_class(conn.sock, method="GET")
            response.begin()
            body = response.read(13)
            self.assertEqual(response.status, 200)
            self.assertEqual(body, b"Hello, world!")

        # Retrieve final response
        response = conn.response_class(conn.sock, method="GET")
        response.begin()
        body = response.read()
        self.assertEqual(response.status, 200)
        self.assertEqual(body, b"Hello, world!")

        conn.close()
コード例 #2
0
ファイル: helper.py プロジェクト: simudream/cheroot
 def output(self):
     if self.body is None:
         return []
     elif isinstance(self.body, (tuple, list)):
         return [ntob(x) for x in self.body]
     elif isinstance(self.body, basestring):
         return [ntob(self.body)]
     else:
         return self.body
コード例 #3
0
ファイル: wsgi.py プロジェクト: simudream/cheroot
    def start_response(self, status, headers, exc_info=None):
        """WSGI callable to begin the HTTP response."""
        # "The application may call start_response more than once,
        # if and only if the exc_info argument is provided."
        if self.started_response and not exc_info:
            raise AssertionError("WSGI start_response called a second "
                                 "time with no exc_info.")
        self.started_response = True

        # "if exc_info is provided, and the HTTP headers have already been
        # sent, start_response must raise an error, and should raise the
        # exc_info tuple."
        if (exc_info is not None) and self.req.sent_headers:
            try:
                if py3k:
                    raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
                else:
                    raise (exc_info[0], exc_info[1], exc_info[2])
            finally:
                exc_info = None

        # According to PEP 3333, when using Python 3, the response status
        # and headers must be bytes masquerading as unicode; that is, they
        # must be of type "str" but are restricted to code points in the
        # "latin-1" set.
        if not isinstance(status, str):
            raise TypeError("WSGI response status is not of type str.")
        self.req.status = ntob(status)

        for k, v in headers:
            if not isinstance(k, str):
                raise TypeError(
                    "WSGI response header key %s is not of type str." %
                    repr(k))
            if not isinstance(v, str):
                raise TypeError(
                    "WSGI response header value %s is not of type str." %
                    repr(v))
            if k.lower() == 'content-length':
                self.remaining_bytes_out = int(v)
            self.req.outheaders.append((ntob(k), ntob(v)))

        return self.write
コード例 #4
0
ファイル: test_wsgiapps.py プロジェクト: simudream/cheroot
 def test_app(environ, start_response):
     status = '200 OK'
     response_headers = [('Content-type', 'text/plain')]
     start_response(status, response_headers)
     output = [
         'Hello, world!\n',
         'This is a wsgi app running within Cheroot!\n\n'
     ]
     keys = list(environ.keys())
     keys.sort()
     for k in keys:
         output.append('%s: %s\n' % (k, environ[k]))
     return [ntob(x, 'utf-8') for x in output]
コード例 #5
0
def openURL(url,
            headers=None,
            method="GET",
            body=None,
            host="127.0.0.1",
            port=8000,
            http_conn=HTTPConnection,
            protocol="HTTP/1.1"):
    """Open the given HTTP resource and return status, headers, and body."""

    headers = cleanHeaders(headers, method, body, host, port)

    # Trying 10 times is simply in case of socket errors.
    # Normal case--it should run once.
    for trial in range(10):
        try:
            # Allow http_conn to be a class or an instance
            if hasattr(http_conn, "host"):
                conn = http_conn
            else:
                conn = http_conn(interface(host), port)

            conn._http_vsn_str = protocol
            conn._http_vsn = int("".join([x for x in protocol if x.isdigit()]))

            if not py3k:
                conn.putrequest(method.upper(),
                                url,
                                skip_host=True,
                                skip_accept_encoding=True)
            else:
                import http.client

                # Replace the stdlib method, which only accepts ASCII url's

                def putrequest(self, method, url):
                    if (self._HTTPConnection__response
                            and self._HTTPConnection__response.isclosed()):
                        self._HTTPConnection__response = None

                    if self._HTTPConnection__state == http.client._CS_IDLE:
                        self._HTTPConnection__state = (
                            http.client._CS_REQ_STARTED)
                    else:
                        raise http.client.CannotSendRequest()

                    self._method = method
                    if not url:
                        url = b'/'
                    request = b' '.join((method.encode("ASCII"), url,
                                         self._http_vsn_str.encode("ASCII")))
                    self._output(request)

                import types
                conn.putrequest = types.MethodType(putrequest, conn)

                conn.putrequest(method.upper(), url)

            for key, value in headers:
                conn.putheader(key, ntob(value, "Latin-1"))
            conn.endheaders()

            if body is not None:
                conn.send(body)

            # Handle response
            response = conn.getresponse()

            s, h, b = shb(response)

            if not hasattr(http_conn, "host"):
                # We made our own conn instance. Close it.
                conn.close()

            return s, h, b
        except socket.error:
            time.sleep(0.5)
            if trial == 9:
                raise
コード例 #6
0
    def test_readall_or_close(self):
        self.httpserver.protocol = "HTTP/1.1"
        self.PROTOCOL = "HTTP/1.1"

        if self.scheme == "https":
            self.HTTP_CONN = HTTPSConnection
        else:
            self.HTTP_CONN = HTTPConnection

        # Test a max of 0 (the default) and then reset to what it was above.
        old_max = self.httpserver.max_request_body_size
        for new_max in (0, old_max):
            self.httpserver.max_request_body_size = new_max

            self.persistent = True
            conn = self.HTTP_CONN

            # Get a POST page with an error
            conn.putrequest("POST", "/err_before_read", skip_host=True)
            conn.putheader("Host", self.HOST)
            conn.putheader("Content-Type", "text/plain")
            conn.putheader("Content-Length", "1000")
            conn.putheader("Expect", "100-continue")
            conn.endheaders()
            response = conn.response_class(conn.sock, method="POST")

            # ...assert and then skip the 100 response
            version, status, reason = response._read_status()
            self.assertEqual(status, 100)
            while True:
                skip = response.fp.readline().strip()
                if not skip:
                    break

            # ...send the body
            conn.send(b"x" * 1000)

            # ...get the final response
            response.begin()
            self.status, self.headers, self.body = webtest.shb(response)
            self.assertStatus(500)

            # Now try a working page with an Expect header...
            conn._output(b'POST /upload HTTP/1.1')
            conn._output(ntob("Host: %s" % self.HOST, 'ascii'))
            conn._output(b"Content-Type: text/plain")
            conn._output(b"Content-Length: 17")
            conn._output(b"Expect: 100-continue")
            conn._send_output()
            response = conn.response_class(conn.sock, method="POST")

            # ...assert and then skip the 100 response
            version, status, reason = response._read_status()
            self.assertEqual(status, 100)
            while True:
                skip = response.fp.readline().strip()
                if not skip:
                    break

            # ...send the body
            body = b"I am a small file"
            conn.send(body)

            # ...get the final response
            response.begin()
            self.status, self.headers, self.body = webtest.shb(response)
            self.assertStatus(200)
            self.assertBody("thanks for '%s'" % body)
            conn.close()
コード例 #7
0
    def test_HTTP11_Timeout_after_request(self):
        # If we timeout after at least one request has succeeded,
        # the server will close the conn without 408.
        self.httpserver.protocol = "HTTP/1.1"
        self.PROTOCOL = "HTTP/1.1"

        # Make an initial request
        self.persistent = True
        conn = self.HTTP_CONN
        conn.putrequest("GET", "/timeout?t=%s" % timeout, skip_host=True)
        conn.putheader("Host", self.HOST)
        conn.endheaders()
        response = conn.response_class(conn.sock, method="GET")
        response.begin()
        self.assertEqual(response.status, 200)
        self.body = response.read()
        self.assertBody(str(timeout))

        # Make a second request on the same socket
        conn._output(b'GET /hello HTTP/1.1')
        conn._output(ntob("Host: %s" % self.HOST, 'ascii'))
        conn._send_output()
        response = conn.response_class(conn.sock, method="GET")
        response.begin()
        self.assertEqual(response.status, 200)
        self.body = response.read()
        self.assertBody("Hello, world!")

        # Wait for our socket timeout
        time.sleep(timeout * 2)

        # Make another request on the same socket, which should error
        conn._output(b'GET /hello HTTP/1.1')
        conn._output(ntob("Host: %s" % self.HOST, 'ascii'))
        conn._send_output()
        response = conn.response_class(conn.sock, method="GET")
        try:
            response.begin()
        except:
            if not isinstance(sys.exc_info()[1],
                              (socket.error, BadStatusLine)):
                self.fail("Writing to timed out socket didn't fail"
                          " as it should have: %s" % sys.exc_info()[1])
        else:
            if response.status != 408:
                self.fail("Writing to timed out socket didn't fail"
                          " as it should have: %s" % response.read())

        conn.close()

        # Make another request on a new socket, which should work
        self.persistent = True
        conn = self.HTTP_CONN
        conn.putrequest("GET", "/pov", skip_host=True)
        conn.putheader("Host", self.HOST)
        conn.endheaders()
        response = conn.response_class(conn.sock, method="GET")
        response.begin()
        self.assertEqual(response.status, 200)
        self.body = response.read()
        self.assertBody(pov)

        # Make another request on the same socket,
        # but timeout on the headers
        conn.send(b'GET /hello HTTP/1.1')
        # Wait for our socket timeout
        time.sleep(timeout * 2)
        response = conn.response_class(conn.sock, method="GET")
        try:
            response.begin()
        except:
            if not isinstance(sys.exc_info()[1],
                              (socket.error, BadStatusLine)):
                self.fail("Writing to timed out socket didn't fail"
                          " as it should have: %s" % sys.exc_info()[1])
        else:
            self.fail("Writing to timed out socket didn't fail"
                      " as it should have: %s" % response.read())

        conn.close()

        # Retry the request on a new connection, which should work
        self.persistent = True
        conn = self.HTTP_CONN
        conn.putrequest("GET", "/pov", skip_host=True)
        conn.putheader("Host", self.HOST)
        conn.endheaders()
        response = conn.response_class(conn.sock, method="GET")
        response.begin()
        self.assertEqual(response.status, 200)
        self.body = response.read()
        self.assertBody(pov)
        conn.close()