Skip to content

Commit 2db8f6a

Browse files
Azd325beniwohli
authored andcommitted
Catch TypeError if port is not set (#567)
If the port not found in the parse result the instrumentation will fail with `int() argument must be a string, a bytes-like object or a number, not 'NoneType'` closes #567
1 parent a55ec2c commit 2db8f6a

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* fixed an issue with empty responses from APM Server's config endpoint (#562, #563)
88
* fixed Windows tests by avoiding time.sleep in breakdown metrics tests (#537, #550)
99
* fixed container ID matching to match CloudFoundry Garden container IDs (#523, #564)
10+
* fixed an issue in the urllib instrumentation if no port is set (#567)
1011

1112
### Other
1213
* Added Python 3.8 RC to the test matrix (#565)

elasticapm/instrumentation/packages/urllib.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ def request_host(request):
4949
scheme, host, port = parse_result.scheme, parse_result.hostname, parse_result.port
5050
try:
5151
port = int(port)
52-
except ValueError:
52+
except (ValueError, TypeError):
5353
pass
5454
if host == "":
5555
host = request.get_header("Host", "")
5656

57-
if port != default_ports.get(scheme):
57+
if port and port != default_ports.get(scheme):
5858
host = "%s:%s" % (host, port)
5959
return host
6060

tests/instrumentation/urllib_tests.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2929
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030

31+
import mock
3132
import pytest
3233

3334
from elasticapm.conf import constants
@@ -39,10 +40,16 @@
3940
try:
4041
from urllib.request import urlopen
4142
from urllib.error import URLError
43+
44+
request_method = "http.client.HTTPConnection.request"
45+
getresponse_method = "http.client.HTTPConnection.getresponse"
4246
except ImportError:
4347
from urllib2 import urlopen
4448
from urllib2 import URLError
4549

50+
request_method = "httplib.HTTPConnection.request"
51+
getresponse_method = "httplib.HTTPConnection.getresponse"
52+
4653

4754
def test_urllib(instrument, elasticapm_client, waiting_httpserver):
4855
waiting_httpserver.serve_content("")
@@ -77,6 +84,30 @@ def test_urllib(instrument, elasticapm_client, waiting_httpserver):
7784
assert spans[1]["parent_id"] == transactions[0]["id"]
7885

7986

87+
@mock.patch(request_method)
88+
@mock.patch(getresponse_method)
89+
def test_urllib_standard_port(mock_getresponse, mock_request, instrument, elasticapm_client):
90+
# "code" is needed for Python 3, "status" for Python 2
91+
mock_getresponse.return_value = mock.Mock(code=200, status=200)
92+
93+
url = "http://example.com/"
94+
parsed_url = urlparse.urlparse(url)
95+
elasticapm_client.begin_transaction("transaction")
96+
expected_sig = "GET {0}".format(parsed_url.netloc)
97+
r = urlopen(url)
98+
99+
elasticapm_client.end_transaction("MyView")
100+
101+
transactions = elasticapm_client.events[TRANSACTION]
102+
spans = elasticapm_client.spans_for_transaction(transactions[0])
103+
104+
assert spans[0]["name"] == expected_sig
105+
assert spans[0]["type"] == "external"
106+
assert spans[0]["subtype"] == "http"
107+
assert spans[0]["context"]["http"]["url"] == url
108+
assert spans[0]["parent_id"] == transactions[0]["id"]
109+
110+
80111
def test_trace_parent_propagation_sampled(instrument, elasticapm_client, waiting_httpserver):
81112
waiting_httpserver.serve_content("")
82113
url = waiting_httpserver.url + "/hello_world"

0 commit comments

Comments
 (0)