예제 #1
0
    def test_pipelining(self):
        s = ("GET / HTTP/1.0\r\n"
             "Connection: %s\r\n"
             "Content-Length: %d\r\n"
             "\r\n"
             "%s")
        to_send = b''
        count = 25
        for n in range(count):
            body = "Response #%d\r\n" % (n + 1)
            if n + 1 < count:
                conn = 'keep-alive'
            else:
                conn = 'close'
            to_send += tobytes(s % (conn, len(body), body))

        self.sock.connect((self.host, self.port))
        self.sock.send(to_send)
        fp = self.sock.makefile('rb', 0)
        for n in range(count):
            expect_body = tobytes("Response #%d\r\n" % (n + 1))
            line = fp.readline() # status line
            version, status, reason = (x.strip() for x in line.split(None, 2))
            headers = parse_headers(fp)
            length = int(headers.get('content-length')) or None
            response_body = fp.read(length)
            self.assertEqual(int(status), 200)
            self.assertEqual(length, len(response_body))
            self.assertEqual(response_body, expect_body)
예제 #2
0
 def test_short_body(self):
     # check to see if server closes connection when body is too short
     # for cl header
     to_send = tobytes(
         "GET /short_body HTTP/1.0\n"
          "Connection: Keep-Alive\n"
          "Content-Length: 0\n"
          "\n"
          )
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline() # status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     headers = parse_headers(fp)
     content_length = int(headers.get('content-length'))
     response_body = fp.read(content_length)
     self.assertEqual(int(status), 200)
     self.assertNotEqual(content_length, len(response_body))
     self.assertEqual(len(response_body), content_length-1)
     self.assertEqual(response_body, tobytes('abcdefghi'))
     # remote closed connection (despite keepalive header); not sure why
     # first send succeeds
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #3
0
 def test_expect_continue(self):
     # specifying Connection: close explicitly
     data = "I have expectations"
     to_send = tobytes(
         "GET / HTTP/1.1\n"
          "Connection: close\n"
          "Content-Length: %d\n"
          "Expect: 100-continue\n"
          "\n"
          "%s" % (len(data), data)
          )
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline() # continue status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     self.assertEqual(int(status), 100)
     self.assertEqual(reason, b'Continue')
     self.assertEqual(version, b'HTTP/1.1')
     fp.readline() # blank line
     line = fp.readline() # next status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     headers = parse_headers(fp)
     length = int(headers.get('content-length')) or None
     response_body = fp.read(length)
     self.assertEqual(int(status), 200)
     self.assertEqual(length, len(response_body))
     self.assertEqual(response_body, tobytes(data))
예제 #4
0
 def test_long_body(self):
     # check server doesnt close connection when body is too short
     # for cl header
     to_send = tobytes(
         "GET /long_body HTTP/1.0\n"
          "Connection: Keep-Alive\n"
          "Content-Length: 0\n"
          "\n"
          )
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline() # status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     headers = parse_headers(fp)
     content_length = int(headers.get('content-length')) or None
     response_body = fp.read(content_length)
     self.assertEqual(int(status), 200)
     self.assertEqual(content_length, len(response_body))
     self.assertEqual(response_body, tobytes('abcdefgh'))
     # remote does not close connection (keepalive header)
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline() # status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     headers = parse_headers(fp)
     content_length = int(headers.get('content-length')) or None
     response_body = fp.read(content_length)
     self.assertEqual(int(status), 200)
예제 #5
0
 def test_without_crlf(self):
     data = "Echo\nthis\r\nplease"
     s = tobytes("GET / HTTP/1.0\n" "Connection: close\n" "Content-Length: %d\n" "\n" "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     headers["content-length"]
     self.assertEqual(len(response_body), len(data))
     self.assertEqual(response_body, tobytes(data))
예제 #6
0
 def test_large_body(self):
     # 1024 characters.
     body = "This string has 32 characters.\r\n" * 32
     s = tobytes("GET / HTTP/1.0\n" "Content-Length: %d\n" "\n" "%s" % (len(body), body))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     self.assertEqual(headers.get("content-length"), "1024")
     self.assertEqual(response_body, tobytes(body))
예제 #7
0
 def test_no_content_length(self):
     # wtf happens when there's no content-length
     to_send = tobytes("GET /no_content_length HTTP/1.0\n" "Connection: Keep-Alive\n" "Content-Length: 0\n" "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line = fp.readline()  # status line
     line, headers, response_body = read_http(fp)
     content_length = headers.get("content-length")
     self.assertEqual(content_length, None)
     self.assertEqual(response_body, tobytes("abcdefghi"))
     # remote closed connection (despite keepalive header)
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #8
0
 def test_request_body_too_large_with_no_cl_http11(self):
     body = 'a' * self.toobig
     to_send = "GET / HTTP/1.1\n\n"
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb')
     # server trusts the content-length header (assumed 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # server assumes pipelined requests due to http/1.1, and the first
     # request was assumed c-l 0 because it had no content-length header,
     # so entire body looks like the header of the subsequent request
     # second response is an error response
     line, headers, response_body = read_http(fp)
     self.assertline(line, '431', 'Request Header Fields Too Large', 
                          'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #9
0
 def write(self, data):
     if not self.complete:
         raise RuntimeError('start_response was not called before body '
                            'written')
     channel = self.channel
     if not self.wrote_header:
         rh = self.build_response_header()
         channel.write_soon(rh)
         self.wrote_header = True
     if data:
         towrite = data
         cl = self.content_length
         if self.chunked_response:
             # use chunked encoding response
             towrite = tobytes(hex(len(data))[2:].upper()) + b'\r\n'
             towrite += data + b'\r\n'
         elif cl is not None:
             towrite = data[:cl - self.content_bytes_written]
             self.content_bytes_written += len(towrite)
             if towrite != data and not self.logged_write_excess:
                 self.logger.warning(
                     'application-written content exceeded the number of '
                     'bytes specified by Content-Length header (%s)' % cl)
                 self.logged_write_excess = True
         if towrite:
             channel.write_soon(towrite)
예제 #10
0
 def test_large_body(self):
     # 1024 characters.
     body = 'This string has 32 characters.\r\n' * 32
     s = tobytes(
         "GET / HTTP/1.0\n"
         "Content-Length: %d\n"
         "\n"
         "%s" % (len(body), body)
         )
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('content-length'), '1024')
     self.assertEqual(response_body, tobytes(body))
예제 #11
0
 def test_request_body_too_large_with_no_cl_http11(self):
     body = 'a' * self.toobig
     to_send = "GET / HTTP/1.1\n\n"
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb')
     # server trusts the content-length header (assumed 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # server assumes pipelined requests due to http/1.1, and the first
     # request was assumed c-l 0 because it had no content-length header,
     # so entire body looks like the header of the subsequent request
     # second response is an error response
     line, headers, response_body = read_http(fp)
     self.assertline(line, '431', 'Request Header Fields Too Large',
                     'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #12
0
 def testComplexGET(self):
     data = (
         b"GET /foo/a+%2B%2F%C3%A4%3D%26a%3Aint?d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6 HTTP/8.4\r\n"
         b"FirstName: mickey\r\n"
         b"lastname: Mouse\r\n"
         b"content-length: 10\r\n"
         b"\r\n"
         b"Hello mickey.")
     parser = self.parser
     self.feed(data)
     self.assertEqual(parser.command, "GET")
     self.assertEqual(parser.version, "8.4")
     self.assertFalse(parser.empty)
     self.assertEqual(
         parser.headers,
         {
             "FIRSTNAME": "mickey",
             "LASTNAME": "Mouse",
             "CONTENT_LENGTH": "10"
         },
     )
     # path should be utf-8 encoded
     self.assertEqual(
         tobytes(parser.path).decode("utf-8"),
         text_(b"/foo/a++/\xc3\xa4=&a:int", "utf-8"),
     )
     self.assertEqual(parser.query,
                      "d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6")
     self.assertEqual(parser.get_body_stream().getvalue(), b"Hello mick")
예제 #13
0
파일: task.py 프로젝트: BenAllums/waitress
 def write(self, data):
     if not self.complete:
         raise RuntimeError('start_response was not called before body '
                            'written')
     channel = self.channel
     if not self.wrote_header:
         rh = self.build_response_header()
         channel.write_soon(rh)
         self.wrote_header = True
     if data:
         towrite = data
         cl = self.content_length
         if self.chunked_response:
             # use chunked encoding response
             towrite = tobytes(hex(len(data))[2:].upper()) + b'\r\n'
             towrite += data + b'\r\n'
         elif cl is not None:
             towrite = data[:cl - self.content_bytes_written]
             self.content_bytes_written += len(towrite)
             if towrite != data and not self.logged_write_excess:
                 self.logger.warning(
                     'application-written content exceeded the number of '
                     'bytes specified by Content-Length header (%s)' % cl)
                 self.logged_write_excess = True
         if towrite:
             channel.write_soon(towrite)
예제 #14
0
    def testComplexGET(self):
        data = b"""\
GET /foo/a+%2B%2F%C3%A4%3D%26a%3Aint?d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6 HTTP/8.4
FirstName: mickey
lastname: Mouse
content-length: 10

Hello mickey.
"""
        parser = self.parser
        self.feed(data)
        self.assertEqual(parser.command, 'GET')
        self.assertEqual(parser.version, '8.4')
        self.assertFalse(parser.empty)
        self.assertEqual(parser.headers,
                         {'FIRSTNAME': 'mickey',
                          'LASTNAME': 'Mouse',
                          'CONTENT_LENGTH': '10',
                          })
        # path should be utf-8 encoded
        self.assertEqual(tobytes(parser.path).decode('utf-8'),
                         text_(b'/foo/a++/\xc3\xa4=&a:int', 'utf-8'))
        self.assertEqual(parser.query,
                         'd=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6')
        self.assertEqual(parser.get_body_stream().getvalue(), b'Hello mick')
예제 #15
0
    def testComplexGET(self):
        data = b"""\
GET /foo/a+%2B%2F%C3%A4%3D%26a%3Aint?d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6 HTTP/8.4
FirstName: mickey
lastname: Mouse
content-length: 10

Hello mickey.
"""
        parser = self.parser
        self.feed(data)
        self.assertEqual(parser.command, 'GET')
        self.assertEqual(parser.version, '8.4')
        self.assertFalse(parser.empty)
        self.assertEqual(parser.headers, {
            'FIRSTNAME': 'mickey',
            'LASTNAME': 'Mouse',
            'CONTENT_LENGTH': '10',
        })
        # path should be utf-8 encoded
        self.assertEqual(
            tobytes(parser.path).decode('utf-8'),
            text_(b'/foo/a++/\xc3\xa4=&a:int', 'utf-8'))
        self.assertEqual(parser.query,
                         'd=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6')
        self.assertEqual(parser.get_body_stream().getvalue(), b'Hello mick')
예제 #16
0
 def test_http10_listlentwo(self):
     body = string.ascii_letters
     to_send = "GET /list_lentwo HTTP/1.0\n" "Connection: Keep-Alive\n" "Content-Length: %d\n\n" % len(body)
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     self.assertEqual(headers.get("content-length"), None)
     self.assertEqual(headers.get("connection"), "close")
     self.assertEqual(response_body, tobytes(body))
     # remote closed connection (despite keepalive header), because
     # lists of length > 1 cannot have their content length divined
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #17
0
 def test_http11_list(self):
     body = string.ascii_letters
     to_send = "GET /list HTTP/1.1\n" "Content-Length: %d\n\n" % len(body)
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.1")
     self.assertEqual(headers["content-length"], str(len(body)))
     self.assertEqual(response_body, tobytes(body))
     # remote keeps connection open because it divined the content length
     # from a length-1 list
     self.sock.send(to_send)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.1")
예제 #18
0
 def test_long_body(self):
     # check server doesnt close connection when body is too long
     # for cl header
     to_send = tobytes("GET /long_body HTTP/1.0\n" "Connection: Keep-Alive\n" "Content-Length: 0\n" "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     content_length = int(headers.get("content-length")) or None
     self.assertEqual(content_length, 9)
     self.assertEqual(content_length, len(response_body))
     self.assertEqual(response_body, tobytes("abcdefghi"))
     # remote does not close connection (keepalive header)
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
예제 #19
0
 def test_http11_list(self):
     body = string.ascii_letters
     to_send = ("GET /list HTTP/1.1\n" "Content-Length: %d\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     self.assertEqual(headers['content-length'], str(len(body)))
     self.assertEqual(response_body, tobytes(body))
     # remote keeps connection open because it divined the content length
     # from a length-1 list
     self.sock.send(to_send)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
예제 #20
0
 def test_no_content_length(self):
     # wtf happens when there's no content-length
     to_send = tobytes("GET /no_content_length HTTP/1.0\n"
                       "Connection: Keep-Alive\n"
                       "Content-Length: 0\n"
                       "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline()  # status line
     line, headers, response_body = read_http(fp)
     content_length = headers.get('content-length')
     self.assertEqual(content_length, None)
     self.assertEqual(response_body, tobytes('abcdefghi'))
     # remote closed connection (despite keepalive header)
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #21
0
 def test_http11_listlentwo(self):
     body = string.ascii_letters
     to_send = "GET /list_lentwo HTTP/1.1\n" "Content-Length: %s\n\n" % len(body)
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb")
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.1")
     expected = b""
     for chunk in (body[0], body[1:]):
         expected += tobytes("%s\r\n%s\r\n" % (str(hex(len(chunk))[2:].upper()), chunk))
     expected += b"0\r\n\r\n"
     self.assertEqual(response_body, expected)
     # connection is always closed at the end of a chunked response
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #22
0
 def test_chunking_request_without_content(self):
     header = tobytes("GET / HTTP/1.1\n" "Transfer-Encoding: chunked\n\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(header)
     self.sock.send(b"0\r\n\r\n")
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     self.assertEqual(response_body, b'')
예제 #23
0
 def test_chunking_request_without_content(self):
     header = tobytes("GET / HTTP/1.1\n" "Transfer-Encoding: chunked\n\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(header)
     self.sock.send(b"0\r\n\r\n")
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.1")
     self.assertEqual(response_body, b"")
예제 #24
0
 def test_short_body(self):
     # check to see if server closes connection when body is too short
     # for cl header
     to_send = tobytes("GET /short_body HTTP/1.0\n" "Connection: Keep-Alive\n" "Content-Length: 0\n" "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     # server trusts the content-length header (5)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     cl = int(headers["content-length"])
     self.assertEqual(cl, 9)
     self.assertNotEqual(cl, len(response_body))
     self.assertEqual(len(response_body), cl - 1)
     self.assertEqual(response_body, tobytes("abcdefgh"))
     # remote closed connection (despite keepalive header)
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #25
0
 def test_http10_generator(self):
     body = string.ascii_letters
     to_send = ("GET / HTTP/1.0\n"
                "Connection: Keep-Alive\n"
                "Content-Length: %d\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('content-length'), None)
     self.assertEqual(headers.get('connection'), 'close')
     self.assertEqual(response_body, tobytes(body))
     # remote closed connection (despite keepalive header), because
     # generators cannot have a content-length divined
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #26
0
 def test_keepalive_http11_explicit(self):
     # Explicitly set keep-alive
     data = "Default: Keep me alive"
     s = tobytes("GET / HTTP/1.1\n" "Connection: keep-alive\n" "Content-Length: %d\n" "\n" "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     self.assertTrue(response.getheader("connection") != "close")
예제 #27
0
 def test_keepalive_http11_connclose(self):
     # specifying Connection: close explicitly
     data = "Don't keep me alive"
     s = tobytes("GET / HTTP/1.1\n" "Connection: close\n" "Content-Length: %d\n" "\n" "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     self.assertEqual(response.getheader("connection"), "close")
예제 #28
0
 def test_date_and_server(self):
     to_send = "GET / HTTP/1.0\n" "Content-Length: 0\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     self.assertEqual(headers.get("server"), "waitress")
     self.assertTrue(headers.get("date"))
예제 #29
0
 def test_send_empty_body(self):
     to_send = ("GET / HTTP/1.0\n" "Content-Length: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('content-length'), '0')
     self.assertEqual(response_body, b'')
예제 #30
0
 def test_send_empty_body(self):
     to_send = "GET / HTTP/1.0\n" "Content-Length: 0\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.0")
     self.assertEqual(headers.get("content-length"), "0")
     self.assertEqual(response_body, b"")
예제 #31
0
 def test_date_and_server(self):
     to_send = ("GET / HTTP/1.0\n" "Content-Length: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('server'), 'waitress')
     self.assertTrue(headers.get('date'))
예제 #32
0
 def test_http11_generator(self):
     body = string.ascii_letters
     to_send = ("GET / HTTP/1.1\n" "Content-Length: %s\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb')
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     expected = b''
     for chunk in chunks(body, 10):
         expected += tobytes('%s\r\n%s\r\n' %
                             (str(hex(len(chunk))[2:].upper()), chunk))
     expected += b'0\r\n\r\n'
     self.assertEqual(response_body, expected)
     # connection is always closed at the end of a chunked response
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #33
0
 def test_http10_listlentwo(self):
     body = string.ascii_letters
     to_send = ("GET /list_lentwo HTTP/1.0\n"
                "Connection: Keep-Alive\n"
                "Content-Length: %d\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('content-length'), None)
     self.assertEqual(headers.get('connection'), 'close')
     self.assertEqual(response_body, tobytes(body))
     # remote closed connection (despite keepalive header), because
     # lists of length > 1 cannot have their content length divined
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #34
0
 def test_send_empty_body(self):
     to_send = ("GET / HTTP/1.0\n"
                "Content-Length: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('content-length'), '0')
     self.assertEqual(response_body, b'')
예제 #35
0
 def test_bad_host_header(self):
     # http://corte.si/posts/code/pathod/pythonservers/index.html
     to_send = "GET / HTTP/1.0\n" " Host: 0\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "400", "Bad Request", "HTTP/1.0")
     self.assertEqual(headers.get("server"), "waitress")
     self.assertTrue(headers.get("date"))
예제 #36
0
 def test_long_body(self):
     # check server doesnt close connection when body is too long
     # for cl header
     to_send = tobytes("GET /long_body HTTP/1.0\n"
                       "Connection: Keep-Alive\n"
                       "Content-Length: 0\n"
                       "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     content_length = int(headers.get('content-length')) or None
     self.assertEqual(content_length, 9)
     self.assertEqual(content_length, len(response_body))
     self.assertEqual(response_body, tobytes('abcdefghi'))
     # remote does not close connection (keepalive header)
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
    def _callFUT(self, app, **kw):
        response = DummyResponse()
        environ = DummyEnviron(**kw)

        def start_response(status, response_headers):
            response.status = status
            response.headers = response_headers

        response.steps = list(app(environ, start_response))
        response.body = b"".join(tobytes(s) for s in response.steps)
        return response
예제 #38
0
 def test_bad_host_header(self):
     # http://corte.si/posts/code/pathod/pythonservers/index.html
     to_send = ("GET / HTTP/1.0\n" " Host: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '400', 'Bad Request', 'HTTP/1.0')
     self.assertEqual(headers.get('server'), 'waitress')
     self.assertTrue(headers.get('date'))
예제 #39
0
 def test_date_and_server(self):
     to_send = ("GET / HTTP/1.0\n"
                "Content-Length: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers.get('server'), 'waitress')
     self.assertTrue(headers.get('date'))
예제 #40
0
 def test_http10_list(self):
     body = string.ascii_letters
     to_send = ("GET /list HTTP/1.0\n"
                "Connection: Keep-Alive\n"
                "Content-Length: %d\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     self.assertEqual(headers['content-length'], str(len(body)))
     self.assertEqual(headers.get('connection'), 'Keep-Alive')
     self.assertEqual(response_body, tobytes(body))
     # remote keeps connection open because it divined the content length
     # from a length-1 list
     self.sock.send(to_send)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
예제 #41
0
 def test_after_write_cb(self):
     to_send = "GET /after_write_cb HTTP/1.1\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile("rb", 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, "200", "OK", "HTTP/1.1")
     self.assertEqual(response_body, b"")
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #42
0
 def test_short_body(self):
     # check to see if server closes connection when body is too short
     # for cl header
     to_send = tobytes("GET /short_body HTTP/1.0\n"
                       "Connection: Keep-Alive\n"
                       "Content-Length: 0\n"
                       "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     # server trusts the content-length header (5)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, 9)
     self.assertNotEqual(cl, len(response_body))
     self.assertEqual(len(response_body), cl - 1)
     self.assertEqual(response_body, tobytes('abcdefgh'))
     # remote closed connection (despite keepalive header)
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #43
0
 def test_bad_host_header(self):
     # http://corte.si/posts/code/pathod/pythonservers/index.html
     to_send = ("GET / HTTP/1.0\n"
                " Host: 0\n\n")
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '400', 'Bad Request', 'HTTP/1.0')
     self.assertEqual(headers.get('server'), 'waitress')
     self.assertTrue(headers.get('date'))
예제 #44
0
 def test_in_generator(self):
     to_send = "GET /in_generator HTTP/1.1\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     self.assertEqual(response_body, b'')
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #45
0
 def test_in_generator(self):
     to_send = "GET /in_generator HTTP/1.1\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     self.assertEqual(response_body, b'')
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #46
0
 def test_http11_generator(self):
     body = string.ascii_letters
     to_send = ("GET / HTTP/1.1\n"
                "Content-Length: %s\n\n" % len(body))
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb')
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     expected = b''
     for chunk in chunks(body, 10):
         expected += tobytes(
             '%s\r\n%s\r\n' % (str(hex(len(chunk))[2:].upper()), chunk)
             )
     expected += b'0\r\n\r\n'
     self.assertEqual(response_body, expected)
     # connection is always closed at the end of a chunked response
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #47
0
 def execute(self):
     e = self.request.error
     body = '%s\r\n\r\n%s' % (e.reason, e.body)
     tag = '\r\n\r\n(generated by waitress)'
     body = body + tag
     self.status = '%s %s' % (e.code, e.reason)
     cl = len(body)
     self.content_length = cl
     self.response_headers.append(('Content-Length', str(cl)))
     self.response_headers.append(('Content-Type', 'text/plain'))
     self.response_headers.append(('Connection', 'close'))
     self.close_on_finish = True
     self.write(tobytes(body))
예제 #48
0
 def test_keepalive_http11_explicit(self):
     # Explicitly set keep-alive
     data = "Default: Keep me alive"
     s = tobytes("GET / HTTP/1.1\n"
                 "Connection: keep-alive\n"
                 "Content-Length: %d\n"
                 "\n"
                 "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     self.assertTrue(response.getheader('connection') != 'close')
예제 #49
0
 def test_keepalive_http11_connclose(self):
     # specifying Connection: close explicitly
     data = "Don't keep me alive"
     s = tobytes("GET / HTTP/1.1\n"
                 "Connection: close\n"
                 "Content-Length: %d\n"
                 "\n"
                 "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     self.assertEqual(response.getheader('connection'), 'close')
예제 #50
0
 def test_short_body(self):
     # check to see if server closes connection when body is too short
     # for cl header
     to_send = tobytes("GET /short_body HTTP/1.0\n"
                       "Connection: Keep-Alive\n"
                       "Content-Length: 0\n"
                       "\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line = fp.readline()  # status line
     version, status, reason = (x.strip() for x in line.split(None, 2))
     headers = parse_headers(fp)
     content_length = int(headers.get('content-length'))
     response_body = fp.read(content_length)
     self.assertEqual(int(status), 200)
     self.assertNotEqual(content_length, len(response_body))
     self.assertEqual(len(response_body), content_length - 1)
     self.assertEqual(response_body, tobytes('abcdefghi'))
     # remote closed connection (despite keepalive header); not sure why
     # first send succeeds
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #51
0
 def test_after_start_response(self):
     to_send = "GET /after_start_response HTTP/1.1\n\n"
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '500', 'Internal Server Error', 'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     self.assertTrue(response_body.startswith(b'Internal Server Error'))
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #52
0
 def test_chunking_request_with_content(self):
     control_line = b"20;\r\n"  # 20 hex = 32 dec
     s = b'This string has 32 characters.\r\n'
     expected = s * 12
     header = tobytes("GET / HTTP/1.1\n" "Transfer-Encoding: chunked\n\n")
     self.sock.connect((self.host, self.port))
     self.sock.send(header)
     fp = self.sock.makefile('rb', 0)
     for n in range(12):
         self.sock.send(control_line)
         self.sock.send(s)
     self.sock.send(b"0\r\n\r\n")
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     self.assertEqual(response_body, expected)
예제 #53
0
    def test_keepalive_http_11(self):
        # Handling of Keep-Alive within HTTP 1.1

        # All connections are kept alive, unless stated otherwise
        data = "Default: Keep me alive"
        s = tobytes("GET / HTTP/1.1\n"
                    "Content-Length: %d\n"
                    "\n"
                    "%s" % (len(data), data))
        self.sock.connect((self.host, self.port))
        self.sock.send(s)
        response = httplib.HTTPResponse(self.sock)
        response.begin()
        self.assertEqual(int(response.status), 200)
        self.assertTrue(response.getheader('connection') != 'close')
예제 #54
0
 def test_request_body_too_large_with_no_cl_http10(self):
     body = 'a' * self.toobig
     to_send = "GET / HTTP/1.0\n\n"
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # extra bytes are thrown away (no pipelining), connection closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #55
0
    def test_notfilelike_nocl_http10(self):
        to_send = "GET /notfilelike_nocl HTTP/1.0\n\n"
        to_send = tobytes(to_send)

        self.sock.connect((self.host, self.port))

        self.sock.send(to_send)
        fp = self.sock.makefile('rb', 0)
        line, headers, response_body = read_http(fp)
        self.assertline(line, '200', 'OK', 'HTTP/1.0')
        ct = headers['content-type']
        self.assertEqual(ct, 'image/jpeg')
        self.assertTrue(b'\377\330\377' in response_body)
        # connection has been closed (no content-length)
        self.sock.send(to_send)
        self.assertRaises(ConnectionClosed, read_http, fp)
예제 #56
0
    def test_filelike_longcl_http11(self):
        to_send = "GET /filelike_longcl HTTP/1.1\n\n"
        to_send = tobytes(to_send)

        self.sock.connect((self.host, self.port))

        for t in range(0, 2):
            self.sock.send(to_send)
            fp = self.sock.makefile('rb', 0)
            line, headers, response_body = read_http(fp)
            self.assertline(line, '200', 'OK', 'HTTP/1.1')
            cl = int(headers['content-length'])
            self.assertEqual(cl, len(response_body))
            ct = headers['content-type']
            self.assertEqual(ct, 'image/jpeg')
            self.assertTrue(b'\377\330\377' in response_body)
예제 #57
0
 def test_keepalive_http_10(self):
     # Handling of Keep-Alive within HTTP 1.0
     data = "Default: Don't keep me alive"
     s = tobytes("GET / HTTP/1.0\n"
                 "Content-Length: %d\n"
                 "\n"
                 "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     connection = response.getheader('Connection', '')
     # We sent no Connection: Keep-Alive header
     # Connection: close (or no header) is default.
     self.assertTrue(connection != 'Keep-Alive')
예제 #58
0
 def test_request_body_too_large_with_no_cl_http11_connclose(self):
     body = 'a' * self.toobig
     to_send = "GET / HTTP/1.1\nConnection: close\n\n"
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb', 0)
     line, headers, response_body = read_http(fp)
     # server trusts the content-length header (assumed 0)
     self.assertline(line, '200', 'OK', 'HTTP/1.1')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)
예제 #59
0
 def test_keepalive_http10_explicit(self):
     # If header Connection: Keep-Alive is explicitly sent,
     # we want to keept the connection open, we also need to return
     # the corresponding header
     data = "Keep me alive"
     s = tobytes("GET / HTTP/1.0\n"
                 "Connection: Keep-Alive\n"
                 "Content-Length: %d\n"
                 "\n"
                 "%s" % (len(data), data))
     self.sock.connect((self.host, self.port))
     self.sock.send(s)
     response = httplib.HTTPResponse(self.sock)
     response.begin()
     self.assertEqual(int(response.status), 200)
     connection = response.getheader('Connection', '')
     self.assertEqual(connection, 'Keep-Alive')
예제 #60
0
 def test_request_body_too_large_with_wrong_cl_http10(self):
     body = 'a' * self.toobig
     to_send = ("GET / HTTP/1.0\n" "Content-Length: 5\n\n")
     to_send += body
     to_send = tobytes(to_send)
     self.sock.connect((self.host, self.port))
     self.sock.send(to_send)
     fp = self.sock.makefile('rb')
     # first request succeeds (content-length 5)
     line, headers, response_body = read_http(fp)
     self.assertline(line, '200', 'OK', 'HTTP/1.0')
     cl = int(headers['content-length'])
     self.assertEqual(cl, len(response_body))
     # server trusts the content-length header; no pipelining,
     # so request fulfilled, extra bytes are thrown away
     # connection has been closed
     self.sock.send(to_send)
     self.assertRaises(ConnectionClosed, read_http, fp)