# HG changeset patch # User Augie Fackler # Date 1337438065 18000 # Node ID e6af8676302fef4af6b2bf104998c6a00668da29 # Parent 69af967b6d6f81b62a024ad9a98f4174bc1f18de httpclient: omit tests for the client since we don't run them anyway diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/__init__.py --- a/mercurial/httpclient/tests/__init__.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/simple_http_test.py --- a/mercurial/httpclient/tests/simple_http_test.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,508 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import socket -import unittest - -import httpplus - -# relative import to ease embedding the library -import util - - -class SimpleHttpTest(util.HttpTestBase, unittest.TestCase): - - def _run_simple_test(self, host, server_data, expected_req, expected_data): - con = httpplus.HTTPConnection(host) - con._connect() - con.sock.data = server_data - con.request('GET', '/') - - self.assertStringEqual(expected_req, con.sock.sent) - self.assertEqual(expected_data, con.getresponse().read()) - - def test_broken_data_obj(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - self.assertRaises(httpplus.BadRequestData, - con.request, 'POST', '/', body=1) - - def test_no_keepalive_http_1_0(self): - expected_request_one = """GET /remote/.hg/requires HTTP/1.1 -Host: localhost:9999 -range: bytes=0- -accept-encoding: identity -accept: application/mercurial-0.1 -user-agent: mercurial/proto-1.0 - -""".replace('\n', '\r\n') - expected_response_headers = """HTTP/1.0 200 OK -Server: SimpleHTTP/0.6 Python/2.6.1 -Date: Sun, 01 May 2011 13:56:57 GMT -Content-type: application/octet-stream -Content-Length: 33 -Last-Modified: Sun, 01 May 2011 13:56:56 GMT - -""".replace('\n', '\r\n') - expected_response_body = """revlogv1 -store -fncache -dotencode -""" - con = httpplus.HTTPConnection('localhost:9999') - con._connect() - con.sock.data = [expected_response_headers, expected_response_body] - con.request('GET', '/remote/.hg/requires', - headers={'accept-encoding': 'identity', - 'range': 'bytes=0-', - 'accept': 'application/mercurial-0.1', - 'user-agent': 'mercurial/proto-1.0', - }) - self.assertStringEqual(expected_request_one, con.sock.sent) - self.assertEqual(con.sock.closed, False) - self.assertNotEqual(con.sock.data, []) - self.assert_(con.busy()) - resp = con.getresponse() - self.assertStringEqual(resp.read(), expected_response_body) - self.failIf(con.busy()) - self.assertEqual(con.sock, None) - self.assertEqual(resp.sock.data, []) - self.assert_(resp.sock.closed) - - def test_multiline_header(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Multiline: Value\r\n', - ' Rest of value\r\n', - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - resp = con.getresponse() - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['Value\n Rest of value'], - resp.headers.getheaders('multiline')) - # Socket should not be closed - self.assertEqual(resp.sock.closed, False) - self.assertEqual(con.sock.closed, False) - - def testSimpleRequest(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'MultiHeader: Value\r\n' - 'MultiHeader: Other Value\r\n' - 'MultiHeader: One More!\r\n' - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - resp = con.getresponse() - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['Value', 'Other Value', 'One More!'], - resp.headers.getheaders('multiheader')) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) - - def testHeaderlessResponse(self): - con = httpplus.HTTPConnection('1.2.3.4', use_ssl=False) - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - '\r\n' - '1234567890' - ] - con.sock.close_on_empty = True - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - resp = con.getresponse() - self.assertEqual('1234567890', resp.read()) - self.assertEqual({}, dict(resp.headers)) - self.assertEqual(resp.status, 200) - - def testReadline(self): - con = httpplus.HTTPConnection('1.2.3.4') - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Connection: Close\r\n', - '\r\n' - '1\n2\nabcdefg\n4\n5'] - con.sock.close_on_empty = True - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - con.request('GET', '/') - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - r = con.getresponse() - for expected in ['1\n', '2\n', 'abcdefg\n', '4\n', '5']: - actual = r.readline() - self.assertEqual(expected, actual, - 'Expected %r, got %r' % (expected, actual)) - - def testReadlineTrickle(self): - con = httpplus.HTTPConnection('1.2.3.4') - con._connect() - # make sure it trickles in one byte at a time - # so that we touch all the cases in readline - con.sock.data = list(''.join( - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Connection: Close\r\n', - '\r\n' - '1\n2\nabcdefg\n4\n5'])) - con.sock.close_on_empty = True - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - con.request('GET', '/') - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - r = con.getresponse() - for expected in ['1\n', '2\n', 'abcdefg\n', '4\n', '5']: - actual = r.readline() - self.assertEqual(expected, actual, - 'Expected %r, got %r' % (expected, actual)) - - def testVariousReads(self): - con = httpplus.HTTPConnection('1.2.3.4') - con._connect() - # make sure it trickles in one byte at a time - # so that we touch all the cases in readline - con.sock.data = list(''.join( - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Connection: Close\r\n', - '\r\n' - '1\n2', - '\na', 'bc', - 'defg\n4\n5'])) - con.sock.close_on_empty = True - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - con.request('GET', '/') - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - r = con.getresponse() - for read_amt, expect in [(1, '1'), (1, '\n'), - (4, '2\nab'), - ('line', 'cdefg\n'), - (None, '4\n5')]: - if read_amt == 'line': - self.assertEqual(expect, r.readline()) - else: - self.assertEqual(expect, r.read(read_amt)) - - def testZeroLengthBody(self): - con = httpplus.HTTPConnection('1.2.3.4') - con._connect() - # make sure it trickles in one byte at a time - # so that we touch all the cases in readline - con.sock.data = list(''.join( - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-length: 0\r\n', - '\r\n'])) - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - con.request('GET', '/') - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - r = con.getresponse() - self.assertEqual('', r.read()) - - def testIPv6(self): - self._run_simple_test('[::1]:8221', - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10', - '\r\n\r\n' - '1234567890'], - ('GET / HTTP/1.1\r\n' - 'Host: [::1]:8221\r\n' - 'accept-encoding: identity\r\n\r\n'), - '1234567890') - self._run_simple_test('::2', - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10', - '\r\n\r\n' - '1234567890'], - ('GET / HTTP/1.1\r\n' - 'Host: ::2\r\n' - 'accept-encoding: identity\r\n\r\n'), - '1234567890') - self._run_simple_test('[::3]:443', - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10', - '\r\n\r\n' - '1234567890'], - ('GET / HTTP/1.1\r\n' - 'Host: ::3\r\n' - 'accept-encoding: identity\r\n\r\n'), - '1234567890') - - def testEarlyContinueResponse(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 403 Forbidden\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 18', - '\r\n\r\n' - "You can't do that."] - expected_req = self.doPost(con, expect_body=False) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertStringEqual(expected_req, sock.sent) - self.assertEqual("You can't do that.", con.getresponse().read()) - self.assertEqual(sock.closed, True) - - def testEarlyContinueResponseNoContentLength(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 403 Forbidden\r\n', - 'Server: BogusServer 1.0\r\n', - '\r\n' - "You can't do that."] - sock.close_on_empty = True - expected_req = self.doPost(con, expect_body=False) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertStringEqual(expected_req, sock.sent) - self.assertEqual("You can't do that.", con.getresponse().read()) - self.assertEqual(sock.closed, True) - - def testDeniedAfterContinueTimeoutExpires(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 403 Forbidden\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 18\r\n', - 'Connection: close', - '\r\n\r\n' - "You can't do that."] - sock.read_wait_sentinel = 'Dear server, send response!' - sock.close_on_empty = True - # send enough data out that we'll chunk it into multiple - # blocks and the socket will close before we can send the - # whole request. - post_body = ('This is some POST data\n' * 1024 * 32 + - 'Dear server, send response!\n' + - 'This is some POST data\n' * 1024 * 32) - expected_req = self.doPost(con, expect_body=False, - body_to_send=post_body) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assert_('POST data\n' in sock.sent) - self.assert_('Dear server, send response!\n' in sock.sent) - # We expect not all of our data was sent. - self.assertNotEqual(sock.sent, expected_req) - self.assertEqual("You can't do that.", con.getresponse().read()) - self.assertEqual(sock.closed, True) - - def testPostData(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.read_wait_sentinel = 'POST data' - sock.early_data = ['HTTP/1.1 100 Co', 'ntinue\r\n\r\n'] - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 16', - '\r\n\r\n', - "You can do that."] - expected_req = self.doPost(con, expect_body=True) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertEqual(expected_req, sock.sent) - self.assertEqual("You can do that.", con.getresponse().read()) - self.assertEqual(sock.closed, False) - - def testServerWithoutContinue(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.read_wait_sentinel = 'POST data' - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 16', - '\r\n\r\n', - "You can do that."] - expected_req = self.doPost(con, expect_body=True) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertEqual(expected_req, sock.sent) - self.assertEqual("You can do that.", con.getresponse().read()) - self.assertEqual(sock.closed, False) - - def testServerWithSlowContinue(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.read_wait_sentinel = 'POST data' - sock.data = ['HTTP/1.1 100 ', 'Continue\r\n\r\n', - 'HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 16', - '\r\n\r\n', - "You can do that."] - expected_req = self.doPost(con, expect_body=True) - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertEqual(expected_req, sock.sent) - resp = con.getresponse() - self.assertEqual("You can do that.", resp.read()) - self.assertEqual(200, resp.status) - self.assertEqual(sock.closed, False) - - def testSlowConnection(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - # simulate one byte arriving at a time, to check for various - # corner cases - con.sock.data = list('HTTP/1.1 200 OK\r\n' - 'Server: BogusServer 1.0\r\n' - 'Content-Length: 10' - '\r\n\r\n' - '1234567890') - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - self.assertEqual('1234567890', con.getresponse().read()) - - def testCloseAfterNotAllOfHeaders(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: NO CARRIER'] - con.sock.close_on_empty = True - con.request('GET', '/') - self.assertRaises(httpplus.HTTPRemoteClosedError, - con.getresponse) - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - def testTimeout(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.sock.data = [] - con.request('GET', '/') - self.assertRaises(httpplus.HTTPTimeoutException, - con.getresponse) - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - - def test_conn_keep_alive_but_server_close_anyway(self): - sockets = [] - def closingsocket(*args, **kwargs): - s = util.MockSocket(*args, **kwargs) - sockets.append(s) - s.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Connection: Keep-Alive\r\n', - 'Content-Length: 16', - '\r\n\r\n', - 'You can do that.'] - s.close_on_empty = True - return s - - socket.socket = closingsocket - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.request('GET', '/') - r1 = con.getresponse() - r1.read() - self.assertFalse(con.sock.closed) - self.assert_(con.sock.remote_closed) - con.request('GET', '/') - self.assertEqual(2, len(sockets)) - - def test_server_closes_before_end_of_body(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - s = con.sock - s.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Connection: Keep-Alive\r\n', - 'Content-Length: 16', - '\r\n\r\n', - 'You can '] # Note: this is shorter than content-length - s.close_on_empty = True - con.request('GET', '/') - r1 = con.getresponse() - self.assertRaises(httpplus.HTTPRemoteClosedError, r1.read) - - def test_no_response_raises_response_not_ready(self): - con = httpplus.HTTPConnection('foo') - self.assertRaises(httpplus.httplib.ResponseNotReady, con.getresponse) -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/test_bogus_responses.py --- a/mercurial/httpclient/tests/test_bogus_responses.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Tests against malformed responses. - -Server implementations that respond with only LF instead of CRLF have -been observed. Checking against ones that use only CR is a hedge -against that potential insanit.y -""" -import unittest - -import httpplus - -# relative import to ease embedding the library -import util - - -class SimpleHttpTest(util.HttpTestBase, unittest.TestCase): - - def bogusEOL(self, eol): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - con.sock.data = ['HTTP/1.1 200 OK%s' % eol, - 'Server: BogusServer 1.0%s' % eol, - 'Content-Length: 10', - eol * 2, - '1234567890'] - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 80), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - self.assertEqual('1234567890', con.getresponse().read()) - - def testOnlyLinefeed(self): - self.bogusEOL('\n') - - def testOnlyCarriageReturn(self): - self.bogusEOL('\r') -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/test_chunked_transfer.py --- a/mercurial/httpclient/tests/test_chunked_transfer.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import cStringIO -import unittest - -import httpplus - -# relative import to ease embedding the library -import util - - -def chunkedblock(x, eol='\r\n'): - r"""Make a chunked transfer-encoding block. - - >>> chunkedblock('hi') - '2\r\nhi\r\n' - >>> chunkedblock('hi' * 10) - '14\r\nhihihihihihihihihihi\r\n' - >>> chunkedblock('hi', eol='\n') - '2\nhi\n' - """ - return ''.join((hex(len(x))[2:], eol, x, eol)) - - -class ChunkedTransferTest(util.HttpTestBase, unittest.TestCase): - def testChunkedUpload(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.read_wait_sentinel = '0\r\n\r\n' - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 6', - '\r\n\r\n', - "Thanks"] - - zz = 'zz\n' - con.request('POST', '/', body=cStringIO.StringIO( - (zz * (0x8010 / 3)) + 'end-of-body')) - expected_req = ('POST / HTTP/1.1\r\n' - 'transfer-encoding: chunked\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - expected_req += chunkedblock('zz\n' * (0x8000 / 3) + 'zz') - expected_req += chunkedblock( - '\n' + 'zz\n' * ((0x1b - len('end-of-body')) / 3) + 'end-of-body') - expected_req += '0\r\n\r\n' - self.assertEqual(('1.2.3.4', 80), sock.sa) - self.assertStringEqual(expected_req, sock.sent) - self.assertEqual("Thanks", con.getresponse().read()) - self.assertEqual(sock.closed, False) - - def testChunkedDownload(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'transfer-encoding: chunked', - '\r\n\r\n', - chunkedblock('hi '), - ] + list(chunkedblock('there')) + [ - chunkedblock(''), - ] - con.request('GET', '/') - self.assertStringEqual('hi there', con.getresponse().read()) - - def testChunkedDownloadOddReadBoundaries(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'transfer-encoding: chunked', - '\r\n\r\n', - chunkedblock('hi '), - ] + list(chunkedblock('there')) + [ - chunkedblock(''), - ] - con.request('GET', '/') - resp = con.getresponse() - for amt, expect in [(1, 'h'), (5, 'i the'), (100, 're')]: - self.assertEqual(expect, resp.read(amt)) - - def testChunkedDownloadBadEOL(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 200 OK\n', - 'Server: BogusServer 1.0\n', - 'transfer-encoding: chunked', - '\n\n', - chunkedblock('hi ', eol='\n'), - chunkedblock('there', eol='\n'), - chunkedblock('', eol='\n'), - ] - con.request('GET', '/') - self.assertStringEqual('hi there', con.getresponse().read()) - - def testChunkedDownloadPartialChunkBadEOL(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 200 OK\n', - 'Server: BogusServer 1.0\n', - 'transfer-encoding: chunked', - '\n\n', - chunkedblock('hi ', eol='\n'), - ] + list(chunkedblock('there\n' * 5, eol='\n')) + [ - chunkedblock('', eol='\n')] - con.request('GET', '/') - self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n', - con.getresponse().read()) - - def testChunkedDownloadPartialChunk(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'transfer-encoding: chunked', - '\r\n\r\n', - chunkedblock('hi '), - ] + list(chunkedblock('there\n' * 5)) + [chunkedblock('')] - con.request('GET', '/') - self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n', - con.getresponse().read()) - - def testChunkedDownloadEarlyHangup(self): - con = httpplus.HTTPConnection('1.2.3.4:80') - con._connect() - sock = con.sock - broken = chunkedblock('hi'*20)[:-1] - sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'transfer-encoding: chunked', - '\r\n\r\n', - broken, - ] - sock.close_on_empty = True - con.request('GET', '/') - resp = con.getresponse() - self.assertRaises(httpplus.HTTPRemoteClosedError, resp.read) -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/test_proxy_support.py --- a/mercurial/httpclient/tests/test_proxy_support.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import unittest -import socket - -import httpplus - -# relative import to ease embedding the library -import util - - -def make_preloaded_socket(data, close=False): - """Make a socket pre-loaded with data so it can be read during connect. - - Useful for https proxy tests because we have to read from the - socket during _connect rather than later on. - """ - def s(*args, **kwargs): - sock = util.MockSocket(*args, **kwargs) - sock.early_data = data[:] - sock.close_on_empty = close - return sock - return s - - -class ProxyHttpTest(util.HttpTestBase, unittest.TestCase): - - def _run_simple_test(self, host, server_data, expected_req, expected_data): - con = httpplus.HTTPConnection(host) - con._connect() - con.sock.data = server_data - con.request('GET', '/') - - self.assertEqual(expected_req, con.sock.sent) - self.assertEqual(expected_data, con.getresponse().read()) - - def testSimpleRequest(self): - con = httpplus.HTTPConnection('1.2.3.4:80', - proxy_hostport=('magicproxy', 4242)) - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'MultiHeader: Value\r\n' - 'MultiHeader: Other Value\r\n' - 'MultiHeader: One More!\r\n' - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - con.request('GET', '/') - - expected_req = ('GET http://1.2.3.4/ HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('127.0.0.42', 4242), con.sock.sa) - self.assertStringEqual(expected_req, con.sock.sent) - resp = con.getresponse() - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['Value', 'Other Value', 'One More!'], - resp.headers.getheaders('multiheader')) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) - - def testSSLRequest(self): - con = httpplus.HTTPConnection('1.2.3.4:443', - proxy_hostport=('magicproxy', 4242)) - socket.socket = make_preloaded_socket( - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10\r\n', - '\r\n' - '1234567890']) - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - connect_sent = con.sock.sent - con.sock.sent = '' - con.request('GET', '/') - - expected_connect = ('CONNECT 1.2.3.4:443 HTTP/1.0\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n' - '\r\n') - expected_request = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('127.0.0.42', 4242), con.sock.sa) - self.assertStringEqual(expected_connect, connect_sent) - self.assertStringEqual(expected_request, con.sock.sent) - resp = con.getresponse() - self.assertEqual(resp.status, 200) - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) - - def testSSLRequestNoConnectBody(self): - con = httpplus.HTTPConnection('1.2.3.4:443', - proxy_hostport=('magicproxy', 4242)) - socket.socket = make_preloaded_socket( - ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - '\r\n']) - con._connect() - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - connect_sent = con.sock.sent - con.sock.sent = '' - con.request('GET', '/') - - expected_connect = ('CONNECT 1.2.3.4:443 HTTP/1.0\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n' - '\r\n') - expected_request = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('127.0.0.42', 4242), con.sock.sa) - self.assertStringEqual(expected_connect, connect_sent) - self.assertStringEqual(expected_request, con.sock.sent) - resp = con.getresponse() - self.assertEqual(resp.status, 200) - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) - - def testSSLProxyFailure(self): - con = httpplus.HTTPConnection('1.2.3.4:443', - proxy_hostport=('magicproxy', 4242)) - socket.socket = make_preloaded_socket( - ['HTTP/1.1 407 Proxy Authentication Required\r\n\r\n'], close=True) - self.assertRaises(httpplus.HTTPProxyConnectFailedException, con._connect) - self.assertRaises(httpplus.HTTPProxyConnectFailedException, - con.request, 'GET', '/') -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/test_readers.py --- a/mercurial/httpclient/tests/test_readers.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import unittest - -from httpplus import _readers - -def chunkedblock(x, eol='\r\n'): - r"""Make a chunked transfer-encoding block. - - >>> chunkedblock('hi') - '2\r\nhi\r\n' - >>> chunkedblock('hi' * 10) - '14\r\nhihihihihihihihihihi\r\n' - >>> chunkedblock('hi', eol='\n') - '2\nhi\n' - """ - return ''.join((hex(len(x))[2:], eol, x, eol)) - -corpus = 'foo\r\nbar\r\nbaz\r\n' - - -class ChunkedReaderTest(unittest.TestCase): - def test_many_block_boundaries(self): - for step in xrange(1, len(corpus)): - data = ''.join(chunkedblock(corpus[start:start+step]) for - start in xrange(0, len(corpus), step)) - for istep in xrange(1, len(data)): - rdr = _readers.ChunkedReader('\r\n') - print 'step', step, 'load', istep - for start in xrange(0, len(data), istep): - rdr._load(data[start:start+istep]) - rdr._load(chunkedblock('')) - self.assertEqual(corpus, rdr.read(len(corpus) + 1)) - - def test_small_chunk_blocks_large_wire_blocks(self): - data = ''.join(map(chunkedblock, corpus)) + chunkedblock('') - rdr = _readers.ChunkedReader('\r\n') - for start in xrange(0, len(data), 4): - d = data[start:start + 4] - if d: - rdr._load(d) - self.assertEqual(corpus, rdr.read(len(corpus)+100)) -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/test_ssl.py --- a/mercurial/httpclient/tests/test_ssl.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -# Copyright 2011, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import unittest - -import httpplus - -# relative import to ease embedding the library -import util - - - -class HttpSslTest(util.HttpTestBase, unittest.TestCase): - def testSslRereadRequired(self): - con = httpplus.HTTPConnection('1.2.3.4:443') - con._connect() - # extend the list instead of assign because of how - # MockSSLSocket works. - con.sock.data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'MultiHeader: Value\r\n' - 'MultiHeader: Other Value\r\n' - 'MultiHeader: One More!\r\n' - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - con.request('GET', '/') - - expected_req = ('GET / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'accept-encoding: identity\r\n\r\n') - - self.assertEqual(('1.2.3.4', 443), con.sock.sa) - self.assertEqual(expected_req, con.sock.sent) - resp = con.getresponse() - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['Value', 'Other Value', 'One More!'], - resp.headers.getheaders('multiheader')) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) - - def testSslRereadInEarlyResponse(self): - con = httpplus.HTTPConnection('1.2.3.4:443') - con._connect() - con.sock.early_data = ['HTTP/1.1 200 OK\r\n', - 'Server: BogusServer 1.0\r\n', - 'MultiHeader: Value\r\n' - 'MultiHeader: Other Value\r\n' - 'MultiHeader: One More!\r\n' - 'Content-Length: 10\r\n', - '\r\n' - '1234567890' - ] - - expected_req = self.doPost(con, False) - self.assertEqual(None, con.sock, - 'Connection should have disowned socket') - - resp = con.getresponse() - self.assertEqual(('1.2.3.4', 443), resp.sock.sa) - self.assertEqual(expected_req, resp.sock.sent) - self.assertEqual('1234567890', resp.read()) - self.assertEqual(['Value', 'Other Value', 'One More!'], - resp.headers.getheaders('multiheader')) - self.assertEqual(['BogusServer 1.0'], - resp.headers.getheaders('server')) -# no-check-code diff -r 69af967b6d6f -r e6af8676302f mercurial/httpclient/tests/util.py --- a/mercurial/httpclient/tests/util.py Fri May 18 17:05:17 2012 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -# Copyright 2010, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import difflib -import socket - -import httpplus - - -class MockSocket(object): - """Mock non-blocking socket object. - - This is ONLY capable of mocking a nonblocking socket. - - Attributes: - early_data: data to always send as soon as end of headers is seen - data: a list of strings to return on recv(), with the - assumption that the socket would block between each - string in the list. - read_wait_sentinel: data that must be written to the socket before - beginning the response. - close_on_empty: If true, close the socket when it runs out of data - for the client. - """ - def __init__(self, af, socktype, proto): - self.af = af - self.socktype = socktype - self.proto = proto - - self.early_data = [] - self.data = [] - self.remote_closed = self.closed = False - self.close_on_empty = False - self.sent = '' - self.read_wait_sentinel = httpplus._END_HEADERS - self.blocking = True - - def close(self): - self.closed = True - - def connect(self, sa): - self.sa = sa - - def setblocking(self, timeout): - self.blocking = bool(timeout) - - def recv(self, amt=-1): - # we only properly emulate non-blocking sockets - assert not self.blocking - if self.early_data: - datalist = self.early_data - elif not self.data: - return '' - else: - datalist = self.data - if amt == -1: - return datalist.pop(0) - data = datalist.pop(0) - if len(data) > amt: - datalist.insert(0, data[amt:]) - if not self.data and not self.early_data and self.close_on_empty: - self.remote_closed = True - return data[:amt] - - @property - def ready_for_read(self): - return ((self.early_data and httpplus._END_HEADERS in self.sent) - or (self.read_wait_sentinel in self.sent and self.data) - or self.closed or self.remote_closed) - - def send(self, data): - # this is a horrible mock, but nothing needs us to raise the - # correct exception yet - assert not self.closed, 'attempted to write to a closed socket' - assert not self.remote_closed, ('attempted to write to a' - ' socket closed by the server') - if len(data) > 8192: - data = data[:8192] - self.sent += data - return len(data) - - -def mockselect(r, w, x, timeout=0): - """Simple mock for select() - """ - readable = filter(lambda s: s.ready_for_read, r) - return readable, w[:], [] - - -class MockSSLSocket(object): - def __init__(self, sock): - self._sock = sock - self._fail_recv = True - - def __getattr__(self, key): - return getattr(self._sock, key) - - def __setattr__(self, key, value): - if key not in ('_sock', '_fail_recv'): - return setattr(self._sock, key, value) - return object.__setattr__(self, key, value) - - def recv(self, amt=-1): - try: - if self._fail_recv: - raise socket.sslerror(socket.SSL_ERROR_WANT_READ) - return self._sock.recv(amt=amt) - finally: - self._fail_recv = not self._fail_recv - - -def mocksslwrap(sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=httpplus.socketutil.CERT_NONE, - ssl_version=None, ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True): - assert sock.blocking, ('wrapping a socket with ssl requires that ' - 'it be in blocking mode.') - return MockSSLSocket(sock) - - -def mockgetaddrinfo(host, port, unused, streamtype): - assert unused == 0 - assert streamtype == socket.SOCK_STREAM - if host.count('.') != 3: - host = '127.0.0.42' - return [(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, '', - (host, port))] - - -class HttpTestBase(object): - def setUp(self): - self.orig_socket = socket.socket - socket.socket = MockSocket - - self.orig_getaddrinfo = socket.getaddrinfo - socket.getaddrinfo = mockgetaddrinfo - - self.orig_select = httpplus.select.select - httpplus.select.select = mockselect - - self.orig_sslwrap = httpplus.socketutil.wrap_socket - httpplus.socketutil.wrap_socket = mocksslwrap - - def tearDown(self): - socket.socket = self.orig_socket - httpplus.select.select = self.orig_select - httpplus.socketutil.wrap_socket = self.orig_sslwrap - socket.getaddrinfo = self.orig_getaddrinfo - - def assertStringEqual(self, l, r): - try: - self.assertEqual(l, r, ('failed string equality check, ' - 'see stdout for details')) - except: - add_nl = lambda li: map(lambda x: x + '\n', li) - print 'failed expectation:' - print ''.join(difflib.unified_diff( - add_nl(l.splitlines()), add_nl(r.splitlines()), - fromfile='expected', tofile='got')) - raise - - def doPost(self, con, expect_body, body_to_send='This is some POST data'): - con.request('POST', '/', body=body_to_send, - expect_continue=True) - expected_req = ('POST / HTTP/1.1\r\n' - 'Host: 1.2.3.4\r\n' - 'content-length: %d\r\n' - 'Expect: 100-Continue\r\n' - 'accept-encoding: identity\r\n\r\n' % - len(body_to_send)) - if expect_body: - expected_req += body_to_send - return expected_req -# no-check-code diff -r 69af967b6d6f -r e6af8676302f setup.py --- a/setup.py Fri May 18 17:05:17 2012 -0500 +++ b/setup.py Sat May 19 09:34:25 2012 -0500 @@ -388,8 +388,7 @@ 'build_hgextindex': buildhgextindex, 'install_scripts': hginstallscripts} -packages = ['mercurial', 'mercurial.hgweb', - 'mercurial.httpclient', 'mercurial.httpclient.tests', +packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient', 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.zeroconf', 'hgext.largefiles']