10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport httplib
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport array
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport httplib
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport StringIO
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport socket
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport errno
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
90a8c90248264a8b26970b4473770bcc3df8515fJosh GaoTestCase = unittest.TestCase
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
130a8c90248264a8b26970b4473770bcc3df8515fJosh GaoHOST = test_support.HOST
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FakeSocket:
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, text, fileclass=StringIO.StringIO):
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.text = text
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.fileclass = fileclass
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.data = ''
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def sendall(self, data):
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.data += ''.join(data)
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def makefile(self, mode, bufsize=None):
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if mode != 'r' and mode != 'rb':
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise httplib.UnimplementedFileMode()
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.fileclass(self.text)
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass EPipeSocket(FakeSocket):
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, text, pipe_trigger):
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # When sendall() is called with pipe_trigger, raise EPIPE.
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        FakeSocket.__init__(self, text)
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.pipe_trigger = pipe_trigger
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def sendall(self, data):
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.pipe_trigger in data:
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise socket.error(errno.EPIPE, "gotcha")
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.data += data
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def close(self):
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pass
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass NoEOFStringIO(StringIO.StringIO):
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Like StringIO, but raises AssertionError on EOF.
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This is used below to test that httplib doesn't try to read
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    more from the underlying file than it should.
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def read(self, n=-1):
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data = StringIO.StringIO.read(self, n)
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if data == '':
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise AssertionError('caller tried to read past EOF')
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return data
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def readline(self, length=None):
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        data = StringIO.StringIO.readline(self, length)
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if data == '':
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise AssertionError('caller tried to read past EOF')
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return data
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass HeaderTests(TestCase):
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_auto_headers(self):
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Some headers are added automatically, but should not be added by
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # .request() if they are explicitly set.
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class HeaderCountingBuffer(list):
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self):
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.count = {}
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def append(self, item):
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                kv = item.split(':')
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if len(kv) > 1:
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # item is a 'Key: Value' header string
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    lcKey = kv[0].lower()
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.count.setdefault(lcKey, 0)
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.count[lcKey] += 1
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                list.append(self, item)
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for explicit_header in True, False:
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for header in 'Content-length', 'Host', 'Accept-encoding':
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                conn = httplib.HTTPConnection('example.com')
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                conn.sock = FakeSocket('blahblahblah')
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                conn._buffer = HeaderCountingBuffer()
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                body = 'spamspamspam'
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                headers = {}
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if explicit_header:
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    headers[header] = str(len(body))
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                conn.request('POST', '/', body, headers)
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(conn._buffer.count[header.lower()], 1)
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_content_length_0(self):
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class ContentLengthChecker(list):
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __init__(self):
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                list.__init__(self)
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.content_length = None
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def append(self, item):
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                kv = item.split(':', 1)
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if len(kv) > 1 and kv[0].lower() == 'content-length':
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.content_length = kv[1].strip()
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                list.append(self, item)
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # POST with empty body
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('example.com')
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = FakeSocket(None)
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn._buffer = ContentLengthChecker()
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.request('POST', '/', '')
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(conn._buffer.content_length, '0',
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        'Header Content-Length not set')
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # PUT request with empty body
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('example.com')
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = FakeSocket(None)
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn._buffer = ContentLengthChecker()
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.request('PUT', '/', '')
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(conn._buffer.content_length, '0',
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        'Header Content-Length not set')
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_putheader(self):
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('example.com')
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = FakeSocket(None)
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.putrequest('GET','/')
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.putheader('Content-length',42)
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue('Content-length: 42' in conn._buffer)
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_ipv6host_header(self):
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Default host header on IPv6 transaction should wrapped by [] if
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # its actual IPv6 address
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = 'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n' \
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   'Accept-Encoding: identity\r\n\r\n'
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('[2001::]:81')
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket('')
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = sock
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.request('GET', '/foo')
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(sock.data.startswith(expected))
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = 'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   'Accept-Encoding: identity\r\n\r\n'
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('[2001:102A::]')
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket('')
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = sock
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.request('GET', '/foo')
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(sock.data.startswith(expected))
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass BasicTest(TestCase):
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_status_lines(self):
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test HTTP status lines
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok\r\n\r\nText"
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(), 'Text')
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(httplib.BadStatusLine, resp.begin)
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_bad_status_repr(self):
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        exc = httplib.BadStatusLine('')
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_partial_reads(self):
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # if we have a length, the system knows when to close itself
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # same behaviour than when we read the whole thing with read()
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'Te')
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(resp.isclosed())
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'xt')
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_partial_reads_no_content_length(self):
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # when no length is present, the socket should be gracefully closed when
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # all data was read
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok\r\n\r\nText"
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'Te')
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(resp.isclosed())
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'xt')
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(1), '')
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_partial_reads_incomplete_body(self):
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # if the server shuts down the connection before the whole
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # content-length is delivered, the socket is gracefully closed
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText"
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'Te')
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(resp.isclosed())
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(2), 'xt')
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(1), '')
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_host_port(self):
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check invalid host_port
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Note that httplib does not accept user:password@ in the host-port.
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for hp in ("www.python.org:abc", "user:password@www.python.org"):
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          8000),
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("www.python.org:80", "www.python.org", 80),
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("www.python.org", "www.python.org", 80),
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("www.python.org:", "www.python.org", 80),
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            http = httplib.HTTP(hp)
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            c = http._conn
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if h != c.host:
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if p != c.port:
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_response_headers(self):
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # test response with multiple message headers with the same field name.
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        text = ('HTTP/1.1 200 OK\r\n'
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                'Set-Cookie: Customer="WILE_E_COYOTE";'
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ' Version="1"; Path="/acme"\r\n'
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ' Path="/acme"\r\n'
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                '\r\n'
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                'No body\r\n')
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao               ', '
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao               'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = FakeSocket(text)
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        r = httplib.HTTPResponse(s)
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        r.begin()
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        cookies = r.getheader("Set-Cookie")
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if cookies != hdr:
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail("multiple headers not combined properly")
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_read_head(self):
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test that the library doesn't attempt to read any data
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # from a HEAD request.  (Tickles SF bug #622042.)
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'HTTP/1.1 200 OK\r\n'
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'Content-Length: 14432\r\n'
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            '\r\n',
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            NoEOFStringIO)
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock, method="HEAD")
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if resp.read() != "":
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail("Did not expect response from HEAD request")
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_send_file(self):
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   'Accept-Encoding: identity\r\nContent-Length:'
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = open(__file__, 'rb')
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('example.com')
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = sock
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.request('GET', '/foo', body)
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(sock.data.startswith(expected))
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_send(self):
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = 'this is a test this is only a test'
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection('example.com')
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(None)
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = sock
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.send(expected)
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, sock.data)
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock.data = ''
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.send(array.array('c', expected))
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, sock.data)
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock.data = ''
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.send(StringIO.StringIO(expected))
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, sock.data)
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_chunked(self):
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        chunked_start = (
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'HTTP/1.1 200 OK\r\n'
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'Transfer-Encoding: chunked\r\n\r\n'
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'a\r\n'
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'hello worl\r\n'
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            '1\r\n'
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'd\r\n'
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(chunked_start + '0\r\n')
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock, method="GET")
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(), 'hello world')
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.close()
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for x in ('', 'foo\r\n'):
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sock = FakeSocket(chunked_start + x)
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            resp = httplib.HTTPResponse(sock, method="GET")
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            resp.begin()
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                resp.read()
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except httplib.IncompleteRead, i:
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(i.partial, 'hello world')
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail('IncompleteRead expected')
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            finally:
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                resp.close()
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_chunked_head(self):
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        chunked_start = (
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'HTTP/1.1 200 OK\r\n'
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'Transfer-Encoding: chunked\r\n\r\n'
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'a\r\n'
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'hello world\r\n'
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            '1\r\n'
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'd\r\n'
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(chunked_start + '0\r\n')
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock, method="HEAD")
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(), '')
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.status, 200)
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.reason, 'OK')
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_negative_content_length(self):
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket('HTTP/1.1 200 OK\r\n'
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          'Content-Length: -1\r\n\r\nHello\r\n')
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock, method="GET")
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(), 'Hello\r\n')
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_incomplete_read(self):
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello\r\n')
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock, method="GET")
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            resp.read()
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except httplib.IncompleteRead as i:
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(i.partial, 'Hello\r\n')
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(repr(i),
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             "IncompleteRead(7 bytes read, 3 more expected)")
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(str(i),
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             "IncompleteRead(7 bytes read, 3 more expected)")
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertTrue(resp.isclosed())
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('IncompleteRead expected')
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_epipe(self):
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = EPipeSocket(
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "HTTP/1.0 401 Authorization Required\r\n"
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "Content-type: text/html\r\n"
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            "WWW-Authenticate: Basic realm=\"example\"\r\n",
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            b"Content-Length")
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn = httplib.HTTPConnection("example.com")
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        conn.sock = sock
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(socket.error,
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          lambda: conn.request("PUT", "/url", "body"))
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = conn.getresponse()
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(401, resp.status)
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual("Basic realm=\"example\"",
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         resp.getheader("www-authenticate"))
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_filenoattr(self):
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Just test the fileno attribute in the HTTPResponse Object.
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok\r\n\r\nText"
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(hasattr(resp,'fileno'),
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                'HTTPResponse should expose a fileno attribute')
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Test lines overflowing the max line size (_MAXLINE in http.client)
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_overflowing_status_line(self):
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.skipTest("disabled for HTTP 0.9 support")
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(FakeSocket(body))
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises((httplib.LineTooLong, httplib.BadStatusLine), resp.begin)
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_overflowing_header_line(self):
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = (
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'HTTP/1.1 200 OK\r\n'
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(FakeSocket(body))
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(httplib.LineTooLong, resp.begin)
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_overflowing_chunked_line(self):
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = (
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'HTTP/1.1 200 OK\r\n'
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'Transfer-Encoding: chunked\r\n\r\n'
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            + '0' * 65536 + 'a\r\n'
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            'hello world\r\n'
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            '0\r\n'
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        )
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(FakeSocket(body))
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(httplib.LineTooLong, resp.read)
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_early_eof(self):
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test httpresponse with no \r\n termination,
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        body = "HTTP/1.1 200 Ok"
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sock = FakeSocket(body)
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp = httplib.HTTPResponse(sock)
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        resp.begin()
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(resp.read(), '')
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(resp.isclosed())
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass OfflineTest(TestCase):
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_responses(self):
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass SourceAddressTest(TestCase):
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setUp(self):
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.port = test_support.bind_port(self.serv)
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.source_port = test_support.find_unused_port()
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv.listen(5)
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.conn = None
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tearDown(self):
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.conn:
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.conn.close()
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.conn = None
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv.close()
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv = None
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testHTTPConnectionSourceAddress(self):
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.conn = httplib.HTTPConnection(HOST, self.port,
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                source_address=('', self.source_port))
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.conn.connect()
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(not hasattr(httplib, 'HTTPSConnection'),
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     'httplib.HTTPSConnection not defined')
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testHTTPSConnectionSourceAddress(self):
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.conn = httplib.HTTPSConnection(HOST, self.port,
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                source_address=('', self.source_port))
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # We don't test anything here other the constructor not barfing as
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # this code doesn't deal with setting up an active running SSL server
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # for an ssl_wrapped connect() to actually return from.
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TimeoutTest(TestCase):
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    PORT = None
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setUp(self):
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TimeoutTest.PORT = test_support.bind_port(self.serv)
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv.listen(5)
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tearDown(self):
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv.close()
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.serv = None
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testTimeoutAttribute(self):
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        '''This will prove that the timeout gets through
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        HTTPConnection and into the socket.
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        '''
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # default -- use global socket timeout
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(socket.getdefaulttimeout() is None)
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        socket.setdefaulttimeout(30)
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            httpConn.connect()
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            socket.setdefaulttimeout(None)
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(httpConn.sock.gettimeout(), 30)
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        httpConn.close()
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # no timeout -- do not use global socket default
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(socket.getdefaulttimeout() is None)
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        socket.setdefaulttimeout(30)
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                              timeout=None)
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            httpConn.connect()
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            socket.setdefaulttimeout(None)
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(httpConn.sock.gettimeout(), None)
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        httpConn.close()
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # a value
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        httpConn.connect()
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(httpConn.sock.gettimeout(), 30)
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        httpConn.close()
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass HTTPSTimeoutTest(TestCase):
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# XXX Here should be tests for HTTPS, there isn't any right now!
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_attributes(self):
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # simple test to check it's storing it
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if hasattr(httplib, 'HTTPSConnection'):
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            h = httplib.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30)
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(h.timeout, 30)
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(not hasattr(httplib, 'HTTPS'), 'httplib.HTTPS not available')
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_host_port(self):
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check invalid host_port
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Note that httplib does not accept user:password@ in the host-port.
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for hp in ("www.python.org:abc", "user:password@www.python.org"):
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          8000),
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("pypi.python.org:443", "pypi.python.org", 443),
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("pypi.python.org", "pypi.python.org", 443),
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("pypi.python.org:", "pypi.python.org", 443),
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443)):
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            http = httplib.HTTPS(hp)
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            c = http._conn
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if h != c.host:
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if p != c.port:
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main(verbose=None):
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              HTTPSTimeoutTest, SourceAddressTest)
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
533