Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/test/test_httplib.py

    r2 r391  
     1import httplib
    12import array
    23import httplib
    34import StringIO
    45import socket
    5 
    6 from unittest import TestCase
     6import errno
     7
     8import unittest
     9TestCase = unittest.TestCase
    710
    811from test import test_support
     
    2326            raise httplib.UnimplementedFileMode()
    2427        return self.fileclass(self.text)
     28
     29class EPipeSocket(FakeSocket):
     30
     31    def __init__(self, text, pipe_trigger):
     32        # When sendall() is called with pipe_trigger, raise EPIPE.
     33        FakeSocket.__init__(self, text)
     34        self.pipe_trigger = pipe_trigger
     35
     36    def sendall(self, data):
     37        if self.pipe_trigger in data:
     38            raise socket.error(errno.EPIPE, "gotcha")
     39        self.data += data
     40
     41    def close(self):
     42        pass
    2543
    2644class NoEOFStringIO(StringIO.StringIO):
     
    4765        # Some headers are added automatically, but should not be added by
    4866        # .request() if they are explicitly set.
    49 
    50         import httplib
    5167
    5268        class HeaderCountingBuffer(list):
     
    7591                self.assertEqual(conn._buffer.count[header.lower()], 1)
    7692
     93    def test_content_length_0(self):
     94
     95        class ContentLengthChecker(list):
     96            def __init__(self):
     97                list.__init__(self)
     98                self.content_length = None
     99            def append(self, item):
     100                kv = item.split(':', 1)
     101                if len(kv) > 1 and kv[0].lower() == 'content-length':
     102                    self.content_length = kv[1].strip()
     103                list.append(self, item)
     104
     105        # POST with empty body
     106        conn = httplib.HTTPConnection('example.com')
     107        conn.sock = FakeSocket(None)
     108        conn._buffer = ContentLengthChecker()
     109        conn.request('POST', '/', '')
     110        self.assertEqual(conn._buffer.content_length, '0',
     111                        'Header Content-Length not set')
     112
     113        # PUT request with empty body
     114        conn = httplib.HTTPConnection('example.com')
     115        conn.sock = FakeSocket(None)
     116        conn._buffer = ContentLengthChecker()
     117        conn.request('PUT', '/', '')
     118        self.assertEqual(conn._buffer.content_length, '0',
     119                        'Header Content-Length not set')
     120
     121    def test_putheader(self):
     122        conn = httplib.HTTPConnection('example.com')
     123        conn.sock = FakeSocket(None)
     124        conn.putrequest('GET','/')
     125        conn.putheader('Content-length',42)
     126        self.assertTrue('Content-length: 42' in conn._buffer)
     127
     128    def test_ipv6host_header(self):
     129        # Default host header on IPv6 transaction should wrapped by [] if
     130        # its actual IPv6 address
     131        expected = 'GET /foo HTTP/1.1\r\nHost: [2001::]:81\r\n' \
     132                   'Accept-Encoding: identity\r\n\r\n'
     133        conn = httplib.HTTPConnection('[2001::]:81')
     134        sock = FakeSocket('')
     135        conn.sock = sock
     136        conn.request('GET', '/foo')
     137        self.assertTrue(sock.data.startswith(expected))
     138
     139        expected = 'GET /foo HTTP/1.1\r\nHost: [2001:102A::]\r\n' \
     140                   'Accept-Encoding: identity\r\n\r\n'
     141        conn = httplib.HTTPConnection('[2001:102A::]')
     142        sock = FakeSocket('')
     143        conn.sock = sock
     144        conn.request('GET', '/foo')
     145        self.assertTrue(sock.data.startswith(expected))
     146
     147
    77148class BasicTest(TestCase):
    78149    def test_status_lines(self):
     
    91162        self.assertRaises(httplib.BadStatusLine, resp.begin)
    92163
     164    def test_bad_status_repr(self):
     165        exc = httplib.BadStatusLine('')
     166        self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
     167
    93168    def test_partial_reads(self):
    94         # if we have a lenght, the system knows when to close itself
     169        # if we have a length, the system knows when to close itself
    95170        # same behaviour than when we read the whole thing with read()
    96171        body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
     
    103178        self.assertTrue(resp.isclosed())
    104179
     180    def test_partial_reads_no_content_length(self):
     181        # when no length is present, the socket should be gracefully closed when
     182        # all data was read
     183        body = "HTTP/1.1 200 Ok\r\n\r\nText"
     184        sock = FakeSocket(body)
     185        resp = httplib.HTTPResponse(sock)
     186        resp.begin()
     187        self.assertEqual(resp.read(2), 'Te')
     188        self.assertFalse(resp.isclosed())
     189        self.assertEqual(resp.read(2), 'xt')
     190        self.assertEqual(resp.read(1), '')
     191        self.assertTrue(resp.isclosed())
     192
     193    def test_partial_reads_incomplete_body(self):
     194        # if the server shuts down the connection before the whole
     195        # content-length is delivered, the socket is gracefully closed
     196        body = "HTTP/1.1 200 Ok\r\nContent-Length: 10\r\n\r\nText"
     197        sock = FakeSocket(body)
     198        resp = httplib.HTTPResponse(sock)
     199        resp.begin()
     200        self.assertEqual(resp.read(2), 'Te')
     201        self.assertFalse(resp.isclosed())
     202        self.assertEqual(resp.read(2), 'xt')
     203        self.assertEqual(resp.read(1), '')
     204        self.assertTrue(resp.isclosed())
     205
    105206    def test_host_port(self):
    106207        # Check invalid host_port
    107208
    108         for hp in ("www.python.org:abc", "www.python.org:"):
     209        # Note that httplib does not accept user:password@ in the host-port.
     210        for hp in ("www.python.org:abc", "user:password@www.python.org"):
    109211            self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
    110212
     
    113215                         ("www.python.org:80", "www.python.org", 80),
    114216                         ("www.python.org", "www.python.org", 80),
     217                         ("www.python.org:", "www.python.org", 80),
    115218                         ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
    116219            http = httplib.HTTP(hp)
     
    170273        conn.sock = sock
    171274        conn.send(expected)
    172         self.assertEquals(expected, sock.data)
     275        self.assertEqual(expected, sock.data)
    173276        sock.data = ''
    174277        conn.send(array.array('c', expected))
    175         self.assertEquals(expected, sock.data)
     278        self.assertEqual(expected, sock.data)
    176279        sock.data = ''
    177280        conn.send(StringIO.StringIO(expected))
    178         self.assertEquals(expected, sock.data)
     281        self.assertEqual(expected, sock.data)
    179282
    180283    def test_chunked(self):
     
    190293        resp = httplib.HTTPResponse(sock, method="GET")
    191294        resp.begin()
    192         self.assertEquals(resp.read(), 'hello world')
     295        self.assertEqual(resp.read(), 'hello world')
    193296        resp.close()
    194297
     
    200303                resp.read()
    201304            except httplib.IncompleteRead, i:
    202                 self.assertEquals(i.partial, 'hello world')
     305                self.assertEqual(i.partial, 'hello world')
    203306                self.assertEqual(repr(i),'IncompleteRead(11 bytes read)')
    204307                self.assertEqual(str(i),'IncompleteRead(11 bytes read)')
     
    208311                resp.close()
    209312
     313    def test_chunked_head(self):
     314        chunked_start = (
     315            'HTTP/1.1 200 OK\r\n'
     316            'Transfer-Encoding: chunked\r\n\r\n'
     317            'a\r\n'
     318            'hello world\r\n'
     319            '1\r\n'
     320            'd\r\n'
     321        )
     322        sock = FakeSocket(chunked_start + '0\r\n')
     323        resp = httplib.HTTPResponse(sock, method="HEAD")
     324        resp.begin()
     325        self.assertEqual(resp.read(), '')
     326        self.assertEqual(resp.status, 200)
     327        self.assertEqual(resp.reason, 'OK')
     328        self.assertTrue(resp.isclosed())
     329
    210330    def test_negative_content_length(self):
    211331        sock = FakeSocket('HTTP/1.1 200 OK\r\n'
     
    213333        resp = httplib.HTTPResponse(sock, method="GET")
    214334        resp.begin()
    215         self.assertEquals(resp.read(), 'Hello\r\n')
    216         resp.close()
     335        self.assertEqual(resp.read(), 'Hello\r\n')
     336        self.assertTrue(resp.isclosed())
    217337
    218338    def test_incomplete_read(self):
     
    223343            resp.read()
    224344        except httplib.IncompleteRead as i:
    225             self.assertEquals(i.partial, 'Hello\r\n')
     345            self.assertEqual(i.partial, 'Hello\r\n')
    226346            self.assertEqual(repr(i),
    227347                             "IncompleteRead(7 bytes read, 3 more expected)")
    228348            self.assertEqual(str(i),
    229349                             "IncompleteRead(7 bytes read, 3 more expected)")
     350            self.assertTrue(resp.isclosed())
    230351        else:
    231352            self.fail('IncompleteRead expected')
    232         finally:
    233             resp.close()
    234 
     353
     354    def test_epipe(self):
     355        sock = EPipeSocket(
     356            "HTTP/1.0 401 Authorization Required\r\n"
     357            "Content-type: text/html\r\n"
     358            "WWW-Authenticate: Basic realm=\"example\"\r\n",
     359            b"Content-Length")
     360        conn = httplib.HTTPConnection("example.com")
     361        conn.sock = sock
     362        self.assertRaises(socket.error,
     363                          lambda: conn.request("PUT", "/url", "body"))
     364        resp = conn.getresponse()
     365        self.assertEqual(401, resp.status)
     366        self.assertEqual("Basic realm=\"example\"",
     367                         resp.getheader("www-authenticate"))
     368
     369    def test_filenoattr(self):
     370        # Just test the fileno attribute in the HTTPResponse Object.
     371        body = "HTTP/1.1 200 Ok\r\n\r\nText"
     372        sock = FakeSocket(body)
     373        resp = httplib.HTTPResponse(sock)
     374        self.assertTrue(hasattr(resp,'fileno'),
     375                'HTTPResponse should expose a fileno attribute')
     376
     377    # Test lines overflowing the max line size (_MAXLINE in http.client)
     378
     379    def test_overflowing_status_line(self):
     380        self.skipTest("disabled for HTTP 0.9 support")
     381        body = "HTTP/1.1 200 Ok" + "k" * 65536 + "\r\n"
     382        resp = httplib.HTTPResponse(FakeSocket(body))
     383        self.assertRaises((httplib.LineTooLong, httplib.BadStatusLine), resp.begin)
     384
     385    def test_overflowing_header_line(self):
     386        body = (
     387            'HTTP/1.1 200 OK\r\n'
     388            'X-Foo: bar' + 'r' * 65536 + '\r\n\r\n'
     389        )
     390        resp = httplib.HTTPResponse(FakeSocket(body))
     391        self.assertRaises(httplib.LineTooLong, resp.begin)
     392
     393    def test_overflowing_chunked_line(self):
     394        body = (
     395            'HTTP/1.1 200 OK\r\n'
     396            'Transfer-Encoding: chunked\r\n\r\n'
     397            + '0' * 65536 + 'a\r\n'
     398            'hello world\r\n'
     399            '0\r\n'
     400        )
     401        resp = httplib.HTTPResponse(FakeSocket(body))
     402        resp.begin()
     403        self.assertRaises(httplib.LineTooLong, resp.read)
     404
     405    def test_early_eof(self):
     406        # Test httpresponse with no \r\n termination,
     407        body = "HTTP/1.1 200 Ok"
     408        sock = FakeSocket(body)
     409        resp = httplib.HTTPResponse(sock)
     410        resp.begin()
     411        self.assertEqual(resp.read(), '')
     412        self.assertTrue(resp.isclosed())
    235413
    236414class OfflineTest(TestCase):
    237415    def test_responses(self):
    238         self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
     416        self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
     417
     418
     419class SourceAddressTest(TestCase):
     420    def setUp(self):
     421        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     422        self.port = test_support.bind_port(self.serv)
     423        self.source_port = test_support.find_unused_port()
     424        self.serv.listen(5)
     425        self.conn = None
     426
     427    def tearDown(self):
     428        if self.conn:
     429            self.conn.close()
     430            self.conn = None
     431        self.serv.close()
     432        self.serv = None
     433
     434    def testHTTPConnectionSourceAddress(self):
     435        self.conn = httplib.HTTPConnection(HOST, self.port,
     436                source_address=('', self.source_port))
     437        self.conn.connect()
     438        self.assertEqual(self.conn.sock.getsockname()[1], self.source_port)
     439
     440    @unittest.skipIf(not hasattr(httplib, 'HTTPSConnection'),
     441                     'httplib.HTTPSConnection not defined')
     442    def testHTTPSConnectionSourceAddress(self):
     443        self.conn = httplib.HTTPSConnection(HOST, self.port,
     444                source_address=('', self.source_port))
     445        # We don't test anything here other the constructor not barfing as
     446        # this code doesn't deal with setting up an active running SSL server
     447        # for an ssl_wrapped connect() to actually return from.
     448
    239449
    240450class TimeoutTest(TestCase):
     
    255465        '''
    256466        # default -- use global socket timeout
    257         self.assert_(socket.getdefaulttimeout() is None)
     467        self.assertTrue(socket.getdefaulttimeout() is None)
    258468        socket.setdefaulttimeout(30)
    259469        try:
     
    266476
    267477        # no timeout -- do not use global socket default
    268         self.assert_(socket.getdefaulttimeout() is None)
     478        self.assertTrue(socket.getdefaulttimeout() is None)
    269479        socket.setdefaulttimeout(30)
    270480        try:
     
    293503            self.assertEqual(h.timeout, 30)
    294504
     505    @unittest.skipIf(not hasattr(httplib, 'HTTPS'), 'httplib.HTTPS not available')
     506    def test_host_port(self):
     507        # Check invalid host_port
     508
     509        # Note that httplib does not accept user:password@ in the host-port.
     510        for hp in ("www.python.org:abc", "user:password@www.python.org"):
     511            self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
     512
     513        for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b",
     514                          8000),
     515                         ("pypi.python.org:443", "pypi.python.org", 443),
     516                         ("pypi.python.org", "pypi.python.org", 443),
     517                         ("pypi.python.org:", "pypi.python.org", 443),
     518                         ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 443)):
     519            http = httplib.HTTPS(hp)
     520            c = http._conn
     521            if h != c.host:
     522                self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
     523            if p != c.port:
     524                self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
     525
     526
    295527def test_main(verbose=None):
    296528    test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
    297                               HTTPSTimeoutTest)
     529                              HTTPSTimeoutTest, SourceAddressTest)
    298530
    299531if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.