183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""Unittests for the various HTTPServer modules.
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehWritten by Cody A.W. Somerville <cody-somerville@ubuntu.com>,
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehJosip Dzolonga, and Michael Otteneder for the 2007/08 GHOP contest.
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport re
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport base64
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport shutil
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport urllib
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport httplib
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport tempfile
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport CGIHTTPServer
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom SimpleHTTPServer import SimpleHTTPRequestHandler
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom CGIHTTPServer import CGIHTTPRequestHandler
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom StringIO import StringIO
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test import test_support
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehthreading = test_support.import_module('threading')
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass NoLogRequestHandler:
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def log_message(self, *args):
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # don't write log messages to stderr
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass SocketlessRequestHandler(SimpleHTTPRequestHandler):
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self):
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.get_called = False
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.protocol_version = "HTTP/1.1"
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def do_GET(self):
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.get_called = True
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.send_response(200)
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.send_header('Content-Type', 'text/html')
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.end_headers()
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.wfile.write(b'<html><body>Data</body></html>\r\n')
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def log_message(self, fmt, *args):
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestServerThread(threading.Thread):
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def __init__(self, test_object, request_handler):
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        threading.Thread.__init__(self)
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.request_handler = request_handler
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_object = test_object
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def run(self):
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.server = HTTPServer(('', 0), self.request_handler)
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_object.PORT = self.server.socket.getsockname()[1]
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_object.server_started.set()
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_object = None
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.server.serve_forever(0.05)
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.server.server_close()
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def stop(self):
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.server.shutdown()
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BaseTestCase(unittest.TestCase):
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._threads = test_support.threading_setup()
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.environ = test_support.EnvironmentVarGuard()
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.server_started = threading.Event()
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.thread = TestServerThread(self, self.request_handler)
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.thread.start()
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.server_started.wait()
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.thread.stop()
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.environ.__exit__()
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_support.threading_cleanup(*self._threads)
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def request(self, uri, method='GET', body=None, headers={}):
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.connection = httplib.HTTPConnection('localhost', self.PORT)
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.connection.request(method, uri, body, headers)
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return self.connection.getresponse()
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BaseHTTPRequestHandlerTestCase(unittest.TestCase):
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """Test the functionality of the BaseHTTPServer focussing on
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    BaseHTTPRequestHandler.
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    HTTPResponseMatch = re.compile('HTTP/1.[0-9]+ 200 OK')
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp (self):
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.handler = SocketlessRequestHandler()
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def send_typical_request(self, message):
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        input_msg = StringIO(message)
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        output = StringIO()
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.handler.rfile = input_msg
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.handler.wfile = output
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.handler.handle_one_request()
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        output.seek(0)
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return output.readlines()
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def verify_get_called(self):
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(self.handler.get_called)
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def verify_expected_headers(self, headers):
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for fieldName in 'Server: ', 'Date: ', 'Content-Type: ':
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(sum(h.startswith(fieldName) for h in headers), 1)
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def verify_http_server_response(self, response):
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        match = self.HTTPResponseMatch.search(response)
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(match is not None)
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_http_1_1(self):
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = self.send_typical_request('GET / HTTP/1.1\r\n\r\n')
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_http_server_response(result[0])
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_expected_headers(result[1:-1])
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_get_called()
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result[-1], '<html><body>Data</body></html>\r\n')
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_http_1_0(self):
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = self.send_typical_request('GET / HTTP/1.0\r\n\r\n')
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_http_server_response(result[0])
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_expected_headers(result[1:-1])
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_get_called()
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result[-1], '<html><body>Data</body></html>\r\n')
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_http_0_9(self):
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = self.send_typical_request('GET / HTTP/0.9\r\n\r\n')
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(len(result), 1)
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result[0], '<html><body>Data</body></html>\r\n')
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_get_called()
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_with_continue_1_0(self):
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = self.send_typical_request('GET / HTTP/1.0\r\nExpect: 100-continue\r\n\r\n')
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_http_server_response(result[0])
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_expected_headers(result[1:-1])
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.verify_get_called()
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result[-1], '<html><body>Data</body></html>\r\n')
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_request_length(self):
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue #10714: huge request lines are discarded, to avoid Denial
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # of Service attacks.
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = self.send_typical_request(b'GET ' + b'x' * 65537)
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result[0], b'HTTP/1.1 414 Request-URI Too Long\r\n')
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertFalse(self.handler.get_called)
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass BaseHTTPServerTestCase(BaseTestCase):
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    class request_handler(NoLogRequestHandler, BaseHTTPRequestHandler):
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        protocol_version = 'HTTP/1.1'
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        default_request_version = 'HTTP/1.1'
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def do_TEST(self):
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_response(204)
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Content-Type', 'text/html')
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Connection', 'close')
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.end_headers()
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def do_KEEP(self):
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_response(204)
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Content-Type', 'text/html')
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Connection', 'keep-alive')
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.end_headers()
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def do_KEYERROR(self):
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_error(999)
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def do_CUSTOM(self):
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_response(999)
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Content-Type', 'text/html')
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.send_header('Connection', 'close')
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.end_headers()
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        BaseTestCase.setUp(self)
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con = httplib.HTTPConnection('localhost', self.PORT)
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.connect()
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_command(self):
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('GET', '/')
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 501)
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_request_line_trimming(self):
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = 'HTTP/1.1\n'
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 501)
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_version_bogus(self):
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = 'FUBAR'
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 400)
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_version_digits(self):
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = 'HTTP/9.9.9'
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 400)
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_version_none_get(self):
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = ''
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 501)
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_version_none(self):
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = ''
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('PUT', '/')
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 400)
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_version_invalid(self):
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn = 99
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = 'HTTP/9.9'
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 505)
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_send_blank(self):
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = ''
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('', '')
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 400)
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_header_close(self):
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putheader('Connection', 'close')
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 501)
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_head_keep_alive(self):
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con._http_vsn_str = 'HTTP/1.1'
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putrequest('GET', '/')
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.putheader('Connection', 'keep-alive')
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.endheaders()
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 501)
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_handler(self):
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('TEST', '/')
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 204)
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_return_header_keep_alive(self):
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('KEEP', '/')
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.getheader('Connection'), 'keep-alive')
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('TEST', '/')
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.addCleanup(self.con.close)
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_internal_key_error(self):
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('KEYERROR', '/')
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 999)
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_return_custom_status(self):
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.con.request('CUSTOM', '/')
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.con.getresponse()
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 999)
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass SimpleHTTPServerTestCase(BaseTestCase):
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    class request_handler(NoLogRequestHandler, SimpleHTTPRequestHandler):
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        BaseTestCase.setUp(self)
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.cwd = os.getcwd()
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        basetempdir = tempfile.gettempdir()
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.chdir(basetempdir)
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.data = 'We are the knights who say Ni!'
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.tempdir = tempfile.mkdtemp(dir=basetempdir)
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.tempdir_name = os.path.basename(self.tempdir)
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        temp = open(os.path.join(self.tempdir, 'test'), 'wb')
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        temp.write(self.data)
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        temp.close()
29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.chdir(self.cwd)
29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                shutil.rmtree(self.tempdir)
29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except OSError:
30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            BaseTestCase.tearDown(self)
30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def check_status_and_reason(self, response, status, data=None):
30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        body = response.read()
30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(response)
30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(response.status, status)
30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertIsNotNone(response.reason)
30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if data:
31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(data, body)
31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_get(self):
31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #constructs the path relative to the root directory of the HTTPServer
31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request(self.tempdir_name + '/test')
31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 200, data=self.data)
31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request(self.tempdir_name + '/')
31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 200)
31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request(self.tempdir_name)
31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 301)
32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/ThisDoesNotExist')
32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 404)
32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/' + 'ThisDoesNotExist' + '/')
32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 404)
32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(os.path.join(self.tempdir_name, 'index.html'), 'w')
32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/' + self.tempdir_name + '/')
32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 200)
32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # chmod() doesn't work as expected on Windows, and filesystem
32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # permissions are ignored by root on Unix.
33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if os.name == 'posix' and os.geteuid() != 0:
33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.chmod(self.tempdir, 0)
33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            response = self.request(self.tempdir_name + '/')
33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.check_status_and_reason(response, 404)
33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.chmod(self.tempdir, 0755)
33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_head(self):
33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request(
33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.tempdir_name + '/test', method='HEAD')
33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 200)
34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(response.getheader('content-length'),
34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         str(len(self.data)))
34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(response.getheader('content-type'),
34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         'application/octet-stream')
34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_invalid_requests(self):
34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/', method='FOO')
34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 501)
34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # requests must be case sensitive,so this should fail too
34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/', method='get')
35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 501)
35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        response = self.request('/', method='GETs')
35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.check_status_and_reason(response, 501)
35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehcgi_file1 = """\
35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#!%s
35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint "Content-type: text/html"
35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint
36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint "Hello World"
36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehcgi_file2 = """\
36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#!%s
36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport cgi
36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint "Content-type: text/html"
36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint
36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehform = cgi.FieldStorage()
37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehprint "%%s, %%s, %%s" %% (form.getfirst("spam"), form.getfirst("eggs"),
37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          form.getfirst("bacon"))
37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        "This test can't be run reliably as root (issue #13308).")
37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass CGIHTTPServerTestCase(BaseTestCase):
37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        pass
38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        BaseTestCase.setUp(self)
38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.parent_dir = tempfile.mkdtemp()
38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin')
38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.mkdir(self.cgi_dir)
38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # The shebang line should be pure ASCII: use symlink if possible.
38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # See issue #7668.
39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if hasattr(os, 'symlink'):
39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.pythonexe = os.path.join(self.parent_dir, 'python')
39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.symlink(sys.executable, self.pythonexe)
39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.pythonexe = sys.executable
39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.file1_path = os.path.join(self.cgi_dir, 'file1.py')
39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(self.file1_path, 'w') as file1:
39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            file1.write(cgi_file1 % self.pythonexe)
39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.chmod(self.file1_path, 0777)
40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.file2_path = os.path.join(self.cgi_dir, 'file2.py')
40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(self.file2_path, 'w') as file2:
40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            file2.write(cgi_file2 % self.pythonexe)
40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.chmod(self.file2_path, 0777)
40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.cwd = os.getcwd()
40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.chdir(self.parent_dir)
40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.chdir(self.cwd)
41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if self.pythonexe != sys.executable:
41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                os.remove(self.pythonexe)
41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.remove(self.file1_path)
41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.remove(self.file2_path)
41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.rmdir(self.cgi_dir)
41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.rmdir(self.parent_dir)
41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            BaseTestCase.tearDown(self)
42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_url_collapse_path(self):
42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify tail is the last portion and head is the rest on proper urls
42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_vectors = {
42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '': '//',
42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '..': IndexError,
42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/.//..': IndexError,
42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/': '//',
42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '//': '//',
42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/\\': '//\\',
43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/.//': '//',
43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            'cgi-bin/file1.py': '/cgi-bin/file1.py',
43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/cgi-bin/file1.py': '/cgi-bin/file1.py',
43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            'a': '//a',
43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a': '//a',
43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '//a': '//a',
43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            './a': '//a',
43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            './C:/': '/C:/',
43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b': '/a/b',
43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/': '/a/b/',
44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/.': '/a/b/',
44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/..': '/a/b/',
44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d': '/a/b/d',
44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../f': '/a/b/d/f',
44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../f': '/a/b/f',
44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/.././././..//f': '/a/b/f',
44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '../a/b/c/../d/e/.././././..//f': IndexError,
44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../../f': '/a/f',
44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../../../f': '//f',
44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../../../../f': IndexError,
45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../../../f/..': '//',
45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '/a/b/c/../d/e/../../../../f/../.': '//',
45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        }
45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for path, expected in test_vectors.iteritems():
45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if isinstance(expected, type) and issubclass(expected, Exception):
45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(expected,
45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  CGIHTTPServer._url_collapse_path, path)
45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                actual = CGIHTTPServer._url_collapse_path(path)
45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(expected, actual,
46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 msg='path = %r\nGot:    %r\nWanted: %r' %
46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 (path, actual, expected))
46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_headers_and_content(self):
46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('/cgi-bin/file1.py')
46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(('Hello World\n', 'text/html', 200),
46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            (res.read(), res.getheader('Content-type'), res.status))
46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_post(self):
46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        params = urllib.urlencode({'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        headers = {'Content-type' : 'application/x-www-form-urlencoded'}
47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('/cgi-bin/file2.py', 'POST', params, headers)
47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.read(), '1, python, 123456\n')
47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_invaliduri(self):
47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('/cgi-bin/invalid')
47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res.read()
47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(res.status, 404)
47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_authorization(self):
48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        headers = {'Authorization' : 'Basic %s' %
48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   base64.b64encode('username:pass')}
48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('/cgi-bin/file1.py', 'GET', headers=headers)
48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(('Hello World\n', 'text/html', 200),
48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                (res.read(), res.getheader('Content-type'), res.status))
48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_no_leading_slash(self):
48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # http://bugs.python.org/issue2254
48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('cgi-bin/file1.py')
49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(('Hello World\n', 'text/html', 200),
49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             (res.read(), res.getheader('Content-type'), res.status))
49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_os_environ_is_not_altered(self):
49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        signature = "Test CGI Server"
49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.environ['SERVER_SOFTWARE'] = signature
49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        res = self.request('/cgi-bin/file1.py')
49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual((b'Hello World\n', 'text/html', 200),
49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                (res.read(), res.getheader('Content-type'), res.status))
49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(os.environ['SERVER_SOFTWARE'], signature)
50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass SimpleHTTPRequestHandlerTestCase(unittest.TestCase):
50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """ Test url parsing """
50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.translated = os.getcwd()
50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.translated = os.path.join(self.translated, 'filename')
50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.handler = SocketlessRequestHandler()
50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_query_arguments(self):
51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        path = self.handler.translate_path('/filename')
51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(path, self.translated)
51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        path = self.handler.translate_path('/filename?foo=bar')
51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(path, self.translated)
51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        path = self.handler.translate_path('/filename?a=b&spam=eggs#zot')
51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(path, self.translated)
51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_start_with_double_slash(self):
51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        path = self.handler.translate_path('//filename')
51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(path, self.translated)
52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        path = self.handler.translate_path('//filename?foo=bar')
52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(path, self.translated)
52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main(verbose=None):
52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        cwd = os.getcwd()
52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_support.run_unittest(BaseHTTPRequestHandlerTestCase,
52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  SimpleHTTPRequestHandlerTestCase,
52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  BaseHTTPServerTestCase,
53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  SimpleHTTPServerTestCase,
53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                  CGIHTTPServerTestCase
53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                 )
53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    finally:
53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.chdir(cwd)
53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
538