1from __future__ import print_function
2import unittest
3import errno
4import os
5import signal
6import subprocess
7import tempfile
8
9import nose
10
11import httplib2
12from httplib2 import socks
13from httplib2.test import miniserver
14
15tinyproxy_cfg = """
16User "%(user)s"
17Port %(port)s
18Listen 127.0.0.1
19PidFile "%(pidfile)s"
20LogFile "%(logfile)s"
21MaxClients 2
22StartServers 1
23LogLevel Info
24"""
25
26
27class FunctionalProxyHttpTest(unittest.TestCase):
28    def setUp(self):
29        if not socks:
30            raise nose.SkipTest("socks module unavailable")
31        if not subprocess:
32            raise nose.SkipTest("subprocess module unavailable")
33
34        # start a short-lived miniserver so we can get a likely port
35        # for the proxy
36        self.httpd, self.proxyport = miniserver.start_server(miniserver.ThisDirHandler)
37        self.httpd.shutdown()
38        self.httpd, self.port = miniserver.start_server(miniserver.ThisDirHandler)
39
40        self.pidfile = tempfile.mktemp()
41        self.logfile = tempfile.mktemp()
42        fd, self.conffile = tempfile.mkstemp()
43        f = os.fdopen(fd, "w")
44        our_cfg = tinyproxy_cfg % {
45            "user": os.getlogin(),
46            "pidfile": self.pidfile,
47            "port": self.proxyport,
48            "logfile": self.logfile,
49        }
50        f.write(our_cfg)
51        f.close()
52        try:
53            # TODO use subprocess.check_call when 2.4 is dropped
54            ret = subprocess.call(["tinyproxy", "-c", self.conffile])
55            self.assertEqual(0, ret)
56        except OSError as e:
57            if e.errno == errno.ENOENT:
58                raise nose.SkipTest("tinyproxy not available")
59            raise
60
61    def tearDown(self):
62        self.httpd.shutdown()
63        try:
64            pid = int(open(self.pidfile).read())
65            os.kill(pid, signal.SIGTERM)
66        except OSError as e:
67            if e.errno == errno.ESRCH:
68                print("\n\n\nTinyProxy Failed to start, log follows:")
69                print(open(self.logfile).read())
70                print("end tinyproxy log\n\n\n")
71            raise
72        map(os.unlink, (self.pidfile, self.logfile, self.conffile))
73
74    def testSimpleProxy(self):
75        proxy_info = httplib2.ProxyInfo(
76            socks.PROXY_TYPE_HTTP, "localhost", self.proxyport
77        )
78        client = httplib2.Http(proxy_info=proxy_info)
79        src = "miniserver.py"
80        response, body = client.request("http://localhost:%d/%s" % (self.port, src))
81        self.assertEqual(response.status, 200)
82        self.assertEqual(body, open(os.path.join(miniserver.HERE, src)).read())
83        lf = open(self.logfile).read()
84        expect = 'Established connection to host "127.0.0.1" ' "using file descriptor"
85        self.assertTrue(
86            expect in lf, "tinyproxy did not proxy a request for miniserver"
87        )
88