|
@@ -13,6 +13,8 @@
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
import logging
|
|
|
+import os
|
|
|
+from unittest.mock import patch
|
|
|
|
|
|
import treq
|
|
|
from netaddr import IPSet
|
|
@@ -100,22 +102,36 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
|
|
|
return http_protocol
|
|
|
|
|
|
- def test_http_request(self):
|
|
|
- agent = ProxyAgent(self.reactor)
|
|
|
+ def _test_request_direct_connection(self, agent, scheme, hostname, path):
|
|
|
+ """Runs a test case for a direct connection not going through a proxy.
|
|
|
|
|
|
- self.reactor.lookups["test.com"] = "1.2.3.4"
|
|
|
- d = agent.request(b"GET", b"http://test.com")
|
|
|
+ Args:
|
|
|
+ agent (ProxyAgent): the proxy agent being tested
|
|
|
+
|
|
|
+ scheme (bytes): expected to be either "http" or "https"
|
|
|
+
|
|
|
+ hostname (bytes): the hostname to connect to in the test
|
|
|
+
|
|
|
+ path (bytes): the path to connect to in the test
|
|
|
+ """
|
|
|
+ is_https = scheme == b"https"
|
|
|
+
|
|
|
+ self.reactor.lookups[hostname.decode()] = "1.2.3.4"
|
|
|
+ d = agent.request(b"GET", scheme + b"://" + hostname + b"/" + path)
|
|
|
|
|
|
# there should be a pending TCP connection
|
|
|
clients = self.reactor.tcpClients
|
|
|
self.assertEqual(len(clients), 1)
|
|
|
(host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
|
|
self.assertEqual(host, "1.2.3.4")
|
|
|
- self.assertEqual(port, 80)
|
|
|
+ self.assertEqual(port, 443 if is_https else 80)
|
|
|
|
|
|
# make a test server, and wire up the client
|
|
|
http_server = self._make_connection(
|
|
|
- client_factory, _get_test_protocol_factory()
|
|
|
+ client_factory,
|
|
|
+ _get_test_protocol_factory(),
|
|
|
+ ssl=is_https,
|
|
|
+ expected_sni=hostname if is_https else None,
|
|
|
)
|
|
|
|
|
|
# the FakeTransport is async, so we need to pump the reactor
|
|
@@ -126,8 +142,8 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
|
|
|
request = http_server.requests[0]
|
|
|
self.assertEqual(request.method, b"GET")
|
|
|
- self.assertEqual(request.path, b"/")
|
|
|
- self.assertEqual(request.requestHeaders.getRawHeaders(b"host"), [b"test.com"])
|
|
|
+ self.assertEqual(request.path, b"/" + path)
|
|
|
+ self.assertEqual(request.requestHeaders.getRawHeaders(b"host"), [hostname])
|
|
|
request.write(b"result")
|
|
|
request.finish()
|
|
|
|
|
@@ -137,48 +153,58 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
body = self.successResultOf(treq.content(resp))
|
|
|
self.assertEqual(body, b"result")
|
|
|
|
|
|
+ def test_http_request(self):
|
|
|
+ agent = ProxyAgent(self.reactor)
|
|
|
+ self._test_request_direct_connection(agent, b"http", b"test.com", b"")
|
|
|
+
|
|
|
def test_https_request(self):
|
|
|
agent = ProxyAgent(self.reactor, contextFactory=get_test_https_policy())
|
|
|
+ self._test_request_direct_connection(agent, b"https", b"test.com", b"abc")
|
|
|
|
|
|
- self.reactor.lookups["test.com"] = "1.2.3.4"
|
|
|
- d = agent.request(b"GET", b"https://test.com/abc")
|
|
|
+ def test_http_request_use_proxy_empty_environment(self):
|
|
|
+ agent = ProxyAgent(self.reactor, use_proxy=True)
|
|
|
+ self._test_request_direct_connection(agent, b"http", b"test.com", b"")
|
|
|
|
|
|
- # there should be a pending TCP connection
|
|
|
- clients = self.reactor.tcpClients
|
|
|
- self.assertEqual(len(clients), 1)
|
|
|
- (host, port, client_factory, _timeout, _bindAddress) = clients[0]
|
|
|
- self.assertEqual(host, "1.2.3.4")
|
|
|
- self.assertEqual(port, 443)
|
|
|
+ @patch.dict(os.environ, {"http_proxy": "proxy.com:8888", "NO_PROXY": "test.com"})
|
|
|
+ def test_http_request_via_uppercase_no_proxy(self):
|
|
|
+ agent = ProxyAgent(self.reactor, use_proxy=True)
|
|
|
+ self._test_request_direct_connection(agent, b"http", b"test.com", b"")
|
|
|
|
|
|
- # make a test server, and wire up the client
|
|
|
- http_server = self._make_connection(
|
|
|
- client_factory,
|
|
|
- _get_test_protocol_factory(),
|
|
|
- ssl=True,
|
|
|
- expected_sni=b"test.com",
|
|
|
- )
|
|
|
-
|
|
|
- # the FakeTransport is async, so we need to pump the reactor
|
|
|
- self.reactor.advance(0)
|
|
|
-
|
|
|
- # now there should be a pending request
|
|
|
- self.assertEqual(len(http_server.requests), 1)
|
|
|
+ @patch.dict(
|
|
|
+ os.environ, {"http_proxy": "proxy.com:8888", "no_proxy": "test.com,unused.com"}
|
|
|
+ )
|
|
|
+ def test_http_request_via_no_proxy(self):
|
|
|
+ agent = ProxyAgent(self.reactor, use_proxy=True)
|
|
|
+ self._test_request_direct_connection(agent, b"http", b"test.com", b"")
|
|
|
|
|
|
- request = http_server.requests[0]
|
|
|
- self.assertEqual(request.method, b"GET")
|
|
|
- self.assertEqual(request.path, b"/abc")
|
|
|
- self.assertEqual(request.requestHeaders.getRawHeaders(b"host"), [b"test.com"])
|
|
|
- request.write(b"result")
|
|
|
- request.finish()
|
|
|
+ @patch.dict(
|
|
|
+ os.environ, {"https_proxy": "proxy.com", "no_proxy": "test.com,unused.com"}
|
|
|
+ )
|
|
|
+ def test_https_request_via_no_proxy(self):
|
|
|
+ agent = ProxyAgent(
|
|
|
+ self.reactor,
|
|
|
+ contextFactory=get_test_https_policy(),
|
|
|
+ use_proxy=True,
|
|
|
+ )
|
|
|
+ self._test_request_direct_connection(agent, b"https", b"test.com", b"abc")
|
|
|
|
|
|
- self.reactor.advance(0)
|
|
|
+ @patch.dict(os.environ, {"http_proxy": "proxy.com:8888", "no_proxy": "*"})
|
|
|
+ def test_http_request_via_no_proxy_star(self):
|
|
|
+ agent = ProxyAgent(self.reactor, use_proxy=True)
|
|
|
+ self._test_request_direct_connection(agent, b"http", b"test.com", b"")
|
|
|
|
|
|
- resp = self.successResultOf(d)
|
|
|
- body = self.successResultOf(treq.content(resp))
|
|
|
- self.assertEqual(body, b"result")
|
|
|
+ @patch.dict(os.environ, {"https_proxy": "proxy.com", "no_proxy": "*"})
|
|
|
+ def test_https_request_via_no_proxy_star(self):
|
|
|
+ agent = ProxyAgent(
|
|
|
+ self.reactor,
|
|
|
+ contextFactory=get_test_https_policy(),
|
|
|
+ use_proxy=True,
|
|
|
+ )
|
|
|
+ self._test_request_direct_connection(agent, b"https", b"test.com", b"abc")
|
|
|
|
|
|
+ @patch.dict(os.environ, {"http_proxy": "proxy.com:8888", "no_proxy": "unused.com"})
|
|
|
def test_http_request_via_proxy(self):
|
|
|
- agent = ProxyAgent(self.reactor, http_proxy=b"proxy.com:8888")
|
|
|
+ agent = ProxyAgent(self.reactor, use_proxy=True)
|
|
|
|
|
|
self.reactor.lookups["proxy.com"] = "1.2.3.5"
|
|
|
d = agent.request(b"GET", b"http://test.com")
|
|
@@ -214,11 +240,12 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
body = self.successResultOf(treq.content(resp))
|
|
|
self.assertEqual(body, b"result")
|
|
|
|
|
|
+ @patch.dict(os.environ, {"https_proxy": "proxy.com", "no_proxy": "unused.com"})
|
|
|
def test_https_request_via_proxy(self):
|
|
|
agent = ProxyAgent(
|
|
|
self.reactor,
|
|
|
contextFactory=get_test_https_policy(),
|
|
|
- https_proxy=b"proxy.com",
|
|
|
+ use_proxy=True,
|
|
|
)
|
|
|
|
|
|
self.reactor.lookups["proxy.com"] = "1.2.3.5"
|
|
@@ -294,6 +321,7 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
body = self.successResultOf(treq.content(resp))
|
|
|
self.assertEqual(body, b"result")
|
|
|
|
|
|
+ @patch.dict(os.environ, {"http_proxy": "proxy.com:8888"})
|
|
|
def test_http_request_via_proxy_with_blacklist(self):
|
|
|
# The blacklist includes the configured proxy IP.
|
|
|
agent = ProxyAgent(
|
|
@@ -301,7 +329,7 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
self.reactor, ip_whitelist=None, ip_blacklist=IPSet(["1.0.0.0/8"])
|
|
|
),
|
|
|
self.reactor,
|
|
|
- http_proxy=b"proxy.com:8888",
|
|
|
+ use_proxy=True,
|
|
|
)
|
|
|
|
|
|
self.reactor.lookups["proxy.com"] = "1.2.3.5"
|
|
@@ -338,7 +366,8 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
body = self.successResultOf(treq.content(resp))
|
|
|
self.assertEqual(body, b"result")
|
|
|
|
|
|
- def test_https_request_via_proxy_with_blacklist(self):
|
|
|
+ @patch.dict(os.environ, {"HTTPS_PROXY": "proxy.com"})
|
|
|
+ def test_https_request_via_uppercase_proxy_with_blacklist(self):
|
|
|
# The blacklist includes the configured proxy IP.
|
|
|
agent = ProxyAgent(
|
|
|
BlacklistingReactorWrapper(
|
|
@@ -346,7 +375,7 @@ class MatrixFederationAgentTests(TestCase):
|
|
|
),
|
|
|
self.reactor,
|
|
|
contextFactory=get_test_https_policy(),
|
|
|
- https_proxy=b"proxy.com",
|
|
|
+ use_proxy=True,
|
|
|
)
|
|
|
|
|
|
self.reactor.lookups["proxy.com"] = "1.2.3.5"
|