{"action":"created","comment":{"url":"https://api.github.com/repos/shazow/urllib3/pulls/comments/56576879","id":56576879,"diff_hunk":"@@ -0,0 +1,49 @@\n+import unittest\n+\n+import mock\n+\n+from urllib3.connection import (\n+    CertificateError,\n+    VerifiedHTTPSConnection,\n+    _match_hostname,\n+)\n+\n+\n+class TestConnection(unittest.TestCase):\n+    \"\"\"\n+    Tests in this suite should not make any network requests or connections.\n+    \"\"\"\n+    def test_match_hostname_no_cert(self):\n+        cert = None\n+        asserted_hostname = 'foo'\n+        self.assertRaises(ValueError, _match_hostname, cert, asserted_hostname)\n+\n+    def test_match_hostname_empty_cert(self):\n+        cert = {}\n+        asserted_hostname = 'foo'\n+        self.assertRaises(ValueError, _match_hostname, cert, asserted_hostname)\n+\n+    def test_match_hostname_match(self):\n+        cert = {'subjectAltName': [('DNS', 'foo')]}\n+        asserted_hostname = 'foo'\n+        _match_hostname(cert, asserted_hostname)\n+\n+    def test_match_hostname_mismatch(self):\n+        cert = {'subjectAltName': [('DNS', 'foo')]}\n+        asserted_hostname = 'bar'\n+        try:\n+            with mock.patch('urllib3.connection.log.error') as mock_log:\n+                _match_hostname(cert, asserted_hostname)\n+        except CertificateError as e:\n+            # import pdb; pdb.set_trace()","path":"test/test_connection.py","position":38,"original_position":38,"commit_id":"f40a1b258527ede74f40d6e7ed49ca0ca8711df1","original_commit_id":"f40a1b258527ede74f40d6e7ed49ca0ca8711df1","user":{"login":"msabramo","id":305268,"avatar_url":"https://avatars.githubusercontent.com/u/305268?v=3","gravatar_id":"","url":"https://api.github.com/users/msabramo","html_url":"https://github.com/msabramo","followers_url":"https://api.github.com/users/msabramo/followers","following_url":"https://api.github.com/users/msabramo/following{/other_user}","gists_url":"https://api.github.com/users/msabramo/gists{/gist_id}","starred_url":"https://api.github.com/users/msabramo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msabramo/subscriptions","organizations_url":"https://api.github.com/users/msabramo/orgs","repos_url":"https://api.github.com/users/msabramo/repos","events_url":"https://api.github.com/users/msabramo/events{/privacy}","received_events_url":"https://api.github.com/users/msabramo/received_events","type":"User","site_admin":false},"body":"Probably? :smile: ","created_at":"2016-03-17T21:01:06Z","updated_at":"2016-03-17T21:01:06Z","html_url":"https://github.com/shazow/urllib3/pull/820#discussion_r56576879","pull_request_url":"https://api.github.com/repos/shazow/urllib3/pulls/820","_links":{"self":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/comments/56576879"},"html":{"href":"https://github.com/shazow/urllib3/pull/820#discussion_r56576879"},"pull_request":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/820"}}},"pull_request":{"url":"https://api.github.com/repos/shazow/urllib3/pulls/820","id":63243705,"html_url":"https://github.com/shazow/urllib3/pull/820","diff_url":"https://github.com/shazow/urllib3/pull/820.diff","patch_url":"https://github.com/shazow/urllib3/pull/820.patch","issue_url":"https://api.github.com/repos/shazow/urllib3/issues/820","number":820,"state":"open","locked":false,"title":"Show certificate when there is a hostname mismatch","user":{"login":"msabramo","id":305268,"avatar_url":"https://avatars.githubusercontent.com/u/305268?v=3","gravatar_id":"","url":"https://api.github.com/users/msabramo","html_url":"https://github.com/msabramo","followers_url":"https://api.github.com/users/msabramo/followers","following_url":"https://api.github.com/users/msabramo/following{/other_user}","gists_url":"https://api.github.com/users/msabramo/gists{/gist_id}","starred_url":"https://api.github.com/users/msabramo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msabramo/subscriptions","organizations_url":"https://api.github.com/users/msabramo/orgs","repos_url":"https://api.github.com/users/msabramo/repos","events_url":"https://api.github.com/users/msabramo/events{/privacy}","received_events_url":"https://api.github.com/users/msabramo/received_events","type":"User","site_admin":false},"body":"I am getting a hostname mismatch error for one of three servers in a pool so I am suspecting that one server has an invalid certificate.\r\n\r\n    requests.exceptions.SSLError: hostname '10.10.194.37' doesn't match u'vault.service.trouper'\r\n\r\nby itself is not much info to go on. It would be nice to see the server certificate that was presented.\r\n\r\nI found that it was surprisingly difficult to see the server certificate, so I decided to see if urllib3 could show the certificate.\r\n\r\nWith this, urllib3 logs an error with the certificate just before raising the exception:\r\n\r\n```\r\nERROR:requests.packages.urllib3.connection:Certificate did not match expected hostname: 10.10.194.38.\r\nCertificate: {'subjectAltName': (('IP Address', '127.0.0.1'), ('IP Address', '10.10.194.36'), ('IP Address', '10.10.194.37'), ('IP Address', '10.10.194.38')),\r\n'notBefore': u'Mar 17 01:18:27 2016 GMT', 'serialNumber': u'9BFDB58B08E7DCCA', 'notAfter': 'Mar 15 01:18:27 2026 GMT', 'version': 3L,\r\n'subject': ((('countryName', u'US'),), (('stateOrProvinceName', u'California'),), (('localityName', u'Palo Alto'),), (('organizationName', u'DevOps'),), (('commonName', u'vault\r\n```\r\n\r\nwhich allows me to check whether the server is presenting the correct certificate.\r\n\r\nI also add the certificate to the exception that is raised so that client code can inspect it.","created_at":"2016-03-17T15:41:24Z","updated_at":"2016-03-17T21:01:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7296d19d2d705f00a247da540f1bb4dc583b3fd0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/shazow/urllib3/pulls/820/commits","review_comments_url":"https://api.github.com/repos/shazow/urllib3/pulls/820/comments","review_comment_url":"https://api.github.com/repos/shazow/urllib3/pulls/comments{/number}","comments_url":"https://api.github.com/repos/shazow/urllib3/issues/820/comments","statuses_url":"https://api.github.com/repos/shazow/urllib3/statuses/f40a1b258527ede74f40d6e7ed49ca0ca8711df1","head":{"label":"msabramo:show_cert_on_hostname_mismatch","ref":"show_cert_on_hostname_mismatch","sha":"f40a1b258527ede74f40d6e7ed49ca0ca8711df1","user":{"login":"msabramo","id":305268,"avatar_url":"https://avatars.githubusercontent.com/u/305268?v=3","gravatar_id":"","url":"https://api.github.com/users/msabramo","html_url":"https://github.com/msabramo","followers_url":"https://api.github.com/users/msabramo/followers","following_url":"https://api.github.com/users/msabramo/following{/other_user}","gists_url":"https://api.github.com/users/msabramo/gists{/gist_id}","starred_url":"https://api.github.com/users/msabramo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msabramo/subscriptions","organizations_url":"https://api.github.com/users/msabramo/orgs","repos_url":"https://api.github.com/users/msabramo/repos","events_url":"https://api.github.com/users/msabramo/events{/privacy}","received_events_url":"https://api.github.com/users/msabramo/received_events","type":"User","site_admin":false},"repo":{"id":42484205,"name":"urllib3","full_name":"msabramo/urllib3","owner":{"login":"msabramo","id":305268,"avatar_url":"https://avatars.githubusercontent.com/u/305268?v=3","gravatar_id":"","url":"https://api.github.com/users/msabramo","html_url":"https://github.com/msabramo","followers_url":"https://api.github.com/users/msabramo/followers","following_url":"https://api.github.com/users/msabramo/following{/other_user}","gists_url":"https://api.github.com/users/msabramo/gists{/gist_id}","starred_url":"https://api.github.com/users/msabramo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msabramo/subscriptions","organizations_url":"https://api.github.com/users/msabramo/orgs","repos_url":"https://api.github.com/users/msabramo/repos","events_url":"https://api.github.com/users/msabramo/events{/privacy}","received_events_url":"https://api.github.com/users/msabramo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/msabramo/urllib3","description":"Python HTTP library with thread-safe connection pooling, file post support, sanity friendly, and more.","fork":true,"url":"https://api.github.com/repos/msabramo/urllib3","forks_url":"https://api.github.com/repos/msabramo/urllib3/forks","keys_url":"https://api.github.com/repos/msabramo/urllib3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/msabramo/urllib3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/msabramo/urllib3/teams","hooks_url":"https://api.github.com/repos/msabramo/urllib3/hooks","issue_events_url":"https://api.github.com/repos/msabramo/urllib3/issues/events{/number}","events_url":"https://api.github.com/repos/msabramo/urllib3/events","assignees_url":"https://api.github.com/repos/msabramo/urllib3/assignees{/user}","branches_url":"https://api.github.com/repos/msabramo/urllib3/branches{/branch}","tags_url":"https://api.github.com/repos/msabramo/urllib3/tags","blobs_url":"https://api.github.com/repos/msabramo/urllib3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/msabramo/urllib3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/msabramo/urllib3/git/refs{/sha}","trees_url":"https://api.github.com/repos/msabramo/urllib3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/msabramo/urllib3/statuses/{sha}","languages_url":"https://api.github.com/repos/msabramo/urllib3/languages","stargazers_url":"https://api.github.com/repos/msabramo/urllib3/stargazers","contributors_url":"https://api.github.com/repos/msabramo/urllib3/contributors","subscribers_url":"https://api.github.com/repos/msabramo/urllib3/subscribers","subscription_url":"https://api.github.com/repos/msabramo/urllib3/subscription","commits_url":"https://api.github.com/repos/msabramo/urllib3/commits{/sha}","git_commits_url":"https://api.github.com/repos/msabramo/urllib3/git/commits{/sha}","comments_url":"https://api.github.com/repos/msabramo/urllib3/comments{/number}","issue_comment_url":"https://api.github.com/repos/msabramo/urllib3/issues/comments{/number}","contents_url":"https://api.github.com/repos/msabramo/urllib3/contents/{+path}","compare_url":"https://api.github.com/repos/msabramo/urllib3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/msabramo/urllib3/merges","archive_url":"https://api.github.com/repos/msabramo/urllib3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/msabramo/urllib3/downloads","issues_url":"https://api.github.com/repos/msabramo/urllib3/issues{/number}","pulls_url":"https://api.github.com/repos/msabramo/urllib3/pulls{/number}","milestones_url":"https://api.github.com/repos/msabramo/urllib3/milestones{/number}","notifications_url":"https://api.github.com/repos/msabramo/urllib3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/msabramo/urllib3/labels{/name}","releases_url":"https://api.github.com/repos/msabramo/urllib3/releases{/id}","deployments_url":"https://api.github.com/repos/msabramo/urllib3/deployments","created_at":"2015-09-15T00:07:04Z","updated_at":"2015-09-15T00:07:05Z","pushed_at":"2016-03-17T20:46:19Z","git_url":"git://github.com/msabramo/urllib3.git","ssh_url":"git@github.com:msabramo/urllib3.git","clone_url":"https://github.com/msabramo/urllib3.git","svn_url":"https://github.com/msabramo/urllib3","homepage":"http://urllib3.readthedocs.org/","size":2669,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"shazow:master","ref":"master","sha":"81e31c9af6ad401e68ffd36f79d7f8b756b76a29","user":{"login":"shazow","id":6292,"avatar_url":"https://avatars.githubusercontent.com/u/6292?v=3","gravatar_id":"","url":"https://api.github.com/users/shazow","html_url":"https://github.com/shazow","followers_url":"https://api.github.com/users/shazow/followers","following_url":"https://api.github.com/users/shazow/following{/other_user}","gists_url":"https://api.github.com/users/shazow/gists{/gist_id}","starred_url":"https://api.github.com/users/shazow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shazow/subscriptions","organizations_url":"https://api.github.com/users/shazow/orgs","repos_url":"https://api.github.com/users/shazow/repos","events_url":"https://api.github.com/users/shazow/events{/privacy}","received_events_url":"https://api.github.com/users/shazow/received_events","type":"User","site_admin":false},"repo":{"id":2410676,"name":"urllib3","full_name":"shazow/urllib3","owner":{"login":"shazow","id":6292,"avatar_url":"https://avatars.githubusercontent.com/u/6292?v=3","gravatar_id":"","url":"https://api.github.com/users/shazow","html_url":"https://github.com/shazow","followers_url":"https://api.github.com/users/shazow/followers","following_url":"https://api.github.com/users/shazow/following{/other_user}","gists_url":"https://api.github.com/users/shazow/gists{/gist_id}","starred_url":"https://api.github.com/users/shazow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shazow/subscriptions","organizations_url":"https://api.github.com/users/shazow/orgs","repos_url":"https://api.github.com/users/shazow/repos","events_url":"https://api.github.com/users/shazow/events{/privacy}","received_events_url":"https://api.github.com/users/shazow/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/shazow/urllib3","description":"Python HTTP library with thread-safe connection pooling, file post support, sanity friendly, and more.","fork":false,"url":"https://api.github.com/repos/shazow/urllib3","forks_url":"https://api.github.com/repos/shazow/urllib3/forks","keys_url":"https://api.github.com/repos/shazow/urllib3/keys{/key_id}","collaborators_url":"https://api.github.com/repos/shazow/urllib3/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/shazow/urllib3/teams","hooks_url":"https://api.github.com/repos/shazow/urllib3/hooks","issue_events_url":"https://api.github.com/repos/shazow/urllib3/issues/events{/number}","events_url":"https://api.github.com/repos/shazow/urllib3/events","assignees_url":"https://api.github.com/repos/shazow/urllib3/assignees{/user}","branches_url":"https://api.github.com/repos/shazow/urllib3/branches{/branch}","tags_url":"https://api.github.com/repos/shazow/urllib3/tags","blobs_url":"https://api.github.com/repos/shazow/urllib3/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/shazow/urllib3/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/shazow/urllib3/git/refs{/sha}","trees_url":"https://api.github.com/repos/shazow/urllib3/git/trees{/sha}","statuses_url":"https://api.github.com/repos/shazow/urllib3/statuses/{sha}","languages_url":"https://api.github.com/repos/shazow/urllib3/languages","stargazers_url":"https://api.github.com/repos/shazow/urllib3/stargazers","contributors_url":"https://api.github.com/repos/shazow/urllib3/contributors","subscribers_url":"https://api.github.com/repos/shazow/urllib3/subscribers","subscription_url":"https://api.github.com/repos/shazow/urllib3/subscription","commits_url":"https://api.github.com/repos/shazow/urllib3/commits{/sha}","git_commits_url":"https://api.github.com/repos/shazow/urllib3/git/commits{/sha}","comments_url":"https://api.github.com/repos/shazow/urllib3/comments{/number}","issue_comment_url":"https://api.github.com/repos/shazow/urllib3/issues/comments{/number}","contents_url":"https://api.github.com/repos/shazow/urllib3/contents/{+path}","compare_url":"https://api.github.com/repos/shazow/urllib3/compare/{base}...{head}","merges_url":"https://api.github.com/repos/shazow/urllib3/merges","archive_url":"https://api.github.com/repos/shazow/urllib3/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/shazow/urllib3/downloads","issues_url":"https://api.github.com/repos/shazow/urllib3/issues{/number}","pulls_url":"https://api.github.com/repos/shazow/urllib3/pulls{/number}","milestones_url":"https://api.github.com/repos/shazow/urllib3/milestones{/number}","notifications_url":"https://api.github.com/repos/shazow/urllib3/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/shazow/urllib3/labels{/name}","releases_url":"https://api.github.com/repos/shazow/urllib3/releases{/id}","deployments_url":"https://api.github.com/repos/shazow/urllib3/deployments","created_at":"2011-09-18T18:08:28Z","updated_at":"2016-03-17T20:36:36Z","pushed_at":"2016-03-17T20:46:21Z","git_url":"git://github.com/shazow/urllib3.git","ssh_url":"git@github.com:shazow/urllib3.git","clone_url":"https://github.com/shazow/urllib3.git","svn_url":"https://github.com/shazow/urllib3","homepage":"http://urllib3.readthedocs.org/","size":4631,"stargazers_count":998,"watchers_count":998,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":320,"mirror_url":null,"open_issues_count":93,"forks":320,"open_issues":93,"watchers":998,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/820"},"html":{"href":"https://github.com/shazow/urllib3/pull/820"},"issue":{"href":"https://api.github.com/repos/shazow/urllib3/issues/820"},"comments":{"href":"https://api.github.com/repos/shazow/urllib3/issues/820/comments"},"review_comments":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/820/comments"},"review_comment":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/shazow/urllib3/pulls/820/commits"},"statuses":{"href":"https://api.github.com/repos/shazow/urllib3/statuses/f40a1b258527ede74f40d6e7ed49ca0ca8711df1"}}}}