|
1 | 1 | import os |
2 | 2 | import datetime |
| 3 | +import socket |
3 | 4 | from http.client import HTTPConnection, HTTPSConnection |
| 5 | +from http.server import BaseHTTPRequestHandler, HTTPServer |
4 | 6 | from socket import SocketIO |
| 7 | +from threading import Thread |
5 | 8 | from urllib.error import HTTPError |
6 | 9 | from urllib.request import urlopen |
7 | 10 | from unittest import mock |
|
12 | 15 | from sentry_sdk.consts import MATCH_ALL, SPANDATA |
13 | 16 | from sentry_sdk.integrations.stdlib import StdlibIntegration |
14 | 17 |
|
15 | | -from tests.conftest import ApproxDict, create_mock_http_server |
| 18 | +from tests.conftest import ApproxDict, create_mock_http_server, get_free_port |
16 | 19 |
|
17 | 20 | PORT = create_mock_http_server() |
18 | 21 |
|
19 | 22 |
|
| 23 | +class MockProxyRequestHandler(BaseHTTPRequestHandler): |
| 24 | + def do_CONNECT(self): |
| 25 | + self.send_response(200, "Connection Established") |
| 26 | + self.end_headers() |
| 27 | + |
| 28 | + self.rfile.readline() |
| 29 | + |
| 30 | + response = b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n" |
| 31 | + self.wfile.write(response) |
| 32 | + self.wfile.flush() |
| 33 | + |
| 34 | + |
| 35 | +def create_mock_proxy_server(): |
| 36 | + proxy_port = get_free_port() |
| 37 | + proxy_server = HTTPServer(("localhost", proxy_port), MockProxyRequestHandler) |
| 38 | + proxy_thread = Thread(target=proxy_server.serve_forever) |
| 39 | + proxy_thread.daemon = True |
| 40 | + proxy_thread.start() |
| 41 | + return proxy_port |
| 42 | + |
| 43 | + |
| 44 | +PROXY_PORT = create_mock_proxy_server() |
| 45 | + |
| 46 | + |
20 | 47 | def test_crumb_capture(sentry_init, capture_events): |
21 | 48 | sentry_init(integrations=[StdlibIntegration()]) |
22 | 49 | events = capture_events() |
@@ -642,3 +669,23 @@ def test_http_timeout(monkeypatch, sentry_init, capture_envelopes): |
642 | 669 | span = transaction["spans"][0] |
643 | 670 | assert span["op"] == "http.client" |
644 | 671 | assert span["description"] == f"GET http://localhost:{PORT}/bla" # noqa: E231 |
| 672 | + |
| 673 | + |
| 674 | +def test_proxy_https_tunnel(sentry_init, capture_events): |
| 675 | + sentry_init(traces_sample_rate=1.0) |
| 676 | + events = capture_events() |
| 677 | + |
| 678 | + with start_transaction(name="test_transaction"): |
| 679 | + conn = HTTPConnection("localhost", PROXY_PORT) |
| 680 | + conn.set_tunnel("api.example.com", 443) |
| 681 | + conn.request("GET", "/foo") |
| 682 | + conn.getresponse() |
| 683 | + |
| 684 | + (event,) = events |
| 685 | + (span,) = event["spans"] |
| 686 | + |
| 687 | + assert span["description"] == "GET https://api.example.com/foo" |
| 688 | + assert span["data"]["url"] == "https://api.example.com/foo" |
| 689 | + assert span["data"][SPANDATA.HTTP_METHOD] == "GET" |
| 690 | + assert span["data"][SPANDATA.NETWORK_PEER_ADDRESS] == "localhost" |
| 691 | + assert span["data"][SPANDATA.NETWORK_PEER_PORT] == PROXY_PORT |
0 commit comments