Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged against master #5

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
443ae32
Speed up tests on Windows
schlamar Mar 1, 2013
61dda09
Merge pull request #155 from schlamar/speed-up-tests
shazow Mar 1, 2013
d299a66
We know best if we support SNI.
kirkeby Feb 26, 2013
953b5a4
Use pyOpenSSL if present.
kirkeby Feb 26, 2013
df1d950
Fix subjectAltName support.
kirkeby Feb 26, 2013
4efbf91
Remove URLLIB3_USE_PYOPENSSL env var.
kirkeby Mar 20, 2013
6f9d779
Remove network-dependent SNI-test.
kirkeby Mar 20, 2013
654020c
CamelCase for class name.
kirkeby Mar 20, 2013
c4b7b4e
Adding tox and travis.
shazow Mar 20, 2013
9a03df1
Add py3.3 and fix travis install command.
shazow Mar 20, 2013
6e351ac
test all the versions
t-8ch Mar 20, 2013
b4ff1f8
Merge pull request #161 from t-8ch/test_more_versions
shazow Mar 20, 2013
35485d8
Move PyOpenSSL-backed SSL into contrib.
kirkeby Mar 20, 2013
a105119
Tests for urllib3.contrib.pyopenssl.
kirkeby Mar 20, 2013
f41dccb
Documentation for the PyOpenSSL contrib module.
kirkeby Mar 20, 2013
823f8d5
Add inject_into_urllib3 code snippet.
kirkeby Mar 20, 2013
9471fe9
Merge pull request #156 from kirkeby/pyopenssl-for-sni
shazow Mar 20, 2013
e363eaf
CHANGES.rst += SNI support (#156)
shazow Mar 20, 2013
b18af9a
add fingerprint support to pyopenssl.py
t-8ch Mar 20, 2013
69823dc
Merge pull request #162 from t-8ch/pyopenssl_fingerprints
shazow Mar 20, 2013
ef27f10
enforce 100% coverage during tests
t-8ch Mar 21, 2013
0f880d5
forcefully break tests
t-8ch Mar 21, 2013
994cceb
Revert "forcefully break tests"
t-8ch Mar 21, 2013
384d142
Merge pull request #163 from t-8ch/testsuite_enforce_coverage
shazow Mar 21, 2013
2cc6045
Removing pypy from travis because it's being a butt on coverage.
shazow Mar 22, 2013
9eb5a64
Added Travis status to README.
schlamar Mar 25, 2013
2e30158
Merge pull request #165 from schlamar/patch-1
Mar 25, 2013
9570cd2
Prevent passing SSL keywoards to HTTP connection
schlamar Feb 27, 2013
cccae49
Merge pull request #154 from schlamar/issue-153
shazow Mar 25, 2013
fce075a
Added title, moved travis image.
shazow Mar 25, 2013
e6a71d9
Fix coverage for Windows.
schlamar Mar 25, 2013
2aa3e4a
Merge pull request #166 from schlamar/fix-coverage
shazow Mar 25, 2013
be10e16
manual specification of hostname to verify against
t-8ch Jan 22, 2013
60fedaa
certificate verification against known fingerprint
t-8ch Jan 22, 2013
10ee82d
fixed style issues
t-8ch Jan 22, 2013
8925368
more style fixes
t-8ch Jan 22, 2013
0caabd9
fix entry in CONTRIBUTORS.txt
t-8ch Jan 22, 2013
60f2199
fix coding style
t-8ch Feb 6, 2013
674ee62
add docs
t-8ch Feb 6, 2013
3d3e32d
fix typo
t-8ch Feb 6, 2013
866280e
test invalid certificate fingerprints
t-8ch Mar 25, 2013
7f9d8ee
Merge pull request #140 from t-8ch/ssl_verify_hostname
shazow Mar 25, 2013
0885df0
Update CHANGES.rst
shazow Mar 25, 2013
b08c501
Adding 'urllib3.contrib' to setup.py (#167)
shazow Mar 25, 2013
b196050
Tests for bad Content-Type type.
Lukasa Apr 2, 2013
d75a807
Return native strings for header-values.
Lukasa Apr 2, 2013
82cee12
Merge pull request #168 from Lukasa/content_type
shazow Apr 2, 2013
6115109
Merged upstream/master.
schlamar Apr 5, 2013
5d987ce
Fixed test coverage.
schlamar Apr 5, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
language: python
python:
- 2.6
- 2.7
- 3.2
- 3.3
script: nosetests
install:
- pip install -r test-requirements.txt --use-mirrors
notifications:
email: false
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Changes
dev (master branch)
+++++++++++++++++++

* Contrib: Optional SNI support for Py2 using PyOpenSSL. (Issue #156)

* ``ProxyManager`` automatically adds ``Host: ...`` header if not given.

* Improved SSL-related code. ``cert_req`` now optionally takes a string like
Expand Down Expand Up @@ -49,6 +51,10 @@ dev (master branch)

* Pass `strict` param down to ``httplib.HTTPConnection``. (Issue #122)

* Added mechanism to verify SSL certificates by fingerprint (md5, sha1) or
against an arbitrary hostname (when connecting by IP or for misconfigured
servers). (Issue #140)


1.5 (2012-08-02)
++++++++++++++++
Expand Down
11 changes: 10 additions & 1 deletion CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,16 @@ In chronological order:
* Support for explicitly closing pooled connections

* hartator <hartator@gmail.com>
* Corrected multipart behavior for params
* Corrected multipart behavior for params

* Thomas Weißschuh <thomas@t-8ch.de>
* Support for TLS SNI
* API unification of ssl_version/cert_reqs
* SSL fingerprint and alternative hostname verification
* Bugfixes in testsuite

* Sune Kirkeby <mig@ibofobi.dk>
* Optional SNI-support for Python 2 via PyOpenSSL.

* Stanislav Vitkovskiy <stas.vitkovsky@gmail.com>
* Added HTTPS (CONNECT) proxy support
Expand Down
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
=======
urllib3
=======

.. image:: https://travis-ci.org/shazow/urllib3.png?branch=master
:target: https://travis-ci.org/shazow/urllib3


Highlights
==========

Expand Down
10 changes: 10 additions & 0 deletions docs/contrib.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Contrib Modules
===============

These modules implement various extra features, that may not be ready for
prime time.

SNI-support for Python 2
------------------------

.. automodule:: urllib3.contrib.pyopenssl
10 changes: 10 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ urllib3 Documentation
managers
helpers
collections
contrib


Highlights
Expand Down Expand Up @@ -166,6 +167,15 @@ but can also be used independently.

helpers

Contrib Modules
---------------

These modules implement various extra features, that may not be ready for
prime time.

.. toctree::

contrib

Contributing
============
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
logging-clear-handlers=true
with-coverage=true
cover-package=urllib3
# no rounding problems here
cover-min-percentage=100
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@
author_email='andrey.petrov@shazow.net',
url='http://urllib3.readthedocs.org/',
license='MIT',
packages=['urllib3', 'dummyserver', 'urllib3.packages',
'urllib3.packages.ssl_match_hostname',
packages=['urllib3', 'dummyserver',
'urllib3.packages', 'urllib3.packages.ssl_match_hostname',
'urllib3.contrib',
],
requires=requirements,
tests_require=tests_requirements,
Expand Down
Empty file added test/contrib/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions test/contrib/test_pyopenssl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
try:
from urllib3.contrib.pyopenssl import (inject_into_urllib3,
extract_from_urllib3)
except ImportError as e:
from nose.plugins.skip import SkipTest
raise SkipTest('Could not import pyopenssl: %r' % e)

from ..with_dummyserver.test_https import TestHTTPS, TestHTTPS_TLSv1
from ..with_dummyserver.test_socketlevel import TestSNI, TestSocketClosing


def setup_module():
inject_into_urllib3()


def teardown_module():
extract_from_urllib3()
8 changes: 4 additions & 4 deletions test/test_filepost.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_field_encoding(self):
, fields)

self.assertEqual(content_type,
b'multipart/form-data; boundary=' + b(BOUNDARY))
'multipart/form-data; boundary=' + str(BOUNDARY))


def test_filename(self):
Expand All @@ -80,7 +80,7 @@ def test_filename(self):
)

self.assertEqual(content_type,
b'multipart/form-data; boundary=' + b(BOUNDARY))
'multipart/form-data; boundary=' + str(BOUNDARY))


def test_textplain(self):
Expand All @@ -98,7 +98,7 @@ def test_textplain(self):
)

self.assertEqual(content_type,
b'multipart/form-data; boundary=' + b(BOUNDARY))
'multipart/form-data; boundary=' + str(BOUNDARY))


def test_explicit(self):
Expand All @@ -116,4 +116,4 @@ def test_explicit(self):
)

self.assertEqual(content_type,
b'multipart/form-data; boundary=' + b(BOUNDARY))
'multipart/form-data; boundary=' + str(BOUNDARY))
49 changes: 49 additions & 0 deletions test/with_dummyserver/test_https.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,55 @@ def test_set_ssl_version_to_sslv3(self):
self._pool.ssl_version = ssl.PROTOCOL_SSLv3
self.assertRaises(SSLError, self._pool.request, 'GET', '/')

def test_assert_specific_hostname(self):
https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
cert_reqs='CERT_REQUIRED')

https_pool.ca_certs = DEFAULT_CA
https_pool.assert_hostname = 'localhost'
https_pool.request('GET', '/')

def test_assert_fingerprint_md5(self):
https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
cert_reqs='CERT_REQUIRED')

https_pool.ca_certs = DEFAULT_CA
https_pool.assert_fingerprint = 'CA:84:E1:AD0E5a:ef:2f:C3:09' \
':E7:30:F8:CD:C8:5B'
https_pool.request('GET', '/')

def test_assert_fingerprint_sha1(self):
https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
cert_reqs='CERT_REQUIRED')

https_pool.ca_certs = DEFAULT_CA
https_pool.assert_fingerprint = 'CC:45:6A:90:82:F7FF:C0:8218:8e:' \
'7A:F2:8A:D7:1E:07:33:67:DE'
https_pool.request('GET', '/')

def test_assert_invalid_fingerprint(self):
https_pool = HTTPSConnectionPool('127.0.0.1', self.port,
cert_reqs='CERT_REQUIRED')

https_pool.ca_certs = DEFAULT_CA
https_pool.assert_fingerprint = 'AA:AA:AA:AA:AA:AAAA:AA:AAAA:AA:' \
'AA:AA:AA:AA:AA:AA:AA:AA:AA'

self.assertRaises(SSLError,
https_pool.request, 'GET', '/')

# invalid length
https_pool.assert_fingerprint = 'AA'

self.assertRaises(SSLError,
https_pool.request, 'GET', '/')

# uneven length
https_pool.assert_fingerprint = 'AA:A'

self.assertRaises(SSLError,
https_pool.request, 'GET', '/')


if __name__ == '__main__':
unittest.main()
4 changes: 4 additions & 0 deletions test/with_dummyserver/test_poolmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ def test_headers(self):
self.assertEqual(returned_headers.get('Foo'), None)
self.assertEqual(returned_headers.get('Baz'), 'quux')

def test_http_with_ssl_keywords(self):
http = PoolManager(ca_certs='REQUIRED')

r = http.request('GET', 'http://%s:%s/' % (self.host, self.port))
self.assertEqual(r.status, 200)


if __name__ == '__main__':
Expand Down
47 changes: 23 additions & 24 deletions test/with_dummyserver/test_socketlevel.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from urllib3 import HTTPConnectionPool, HTTPSConnectionPool
from urllib3.poolmanager import proxy_from_url
from urllib3.exceptions import MaxRetryError, TimeoutError, SSLError
from urllib3 import util

from dummyserver.testcase import SocketDummyServerTestCase

from nose.plugins.skip import SkipTest
from threading import Event

try:
from ssl import HAS_SNI
except ImportError: # openssl without SNI
HAS_SNI = False


class TestCookies(SocketDummyServerTestCase):

Expand All @@ -34,28 +31,30 @@ def multicookie_response_handler(listener):
self.assertEquals(r.headers, {'set-cookie': 'foo=1, bar=1'})


if HAS_SNI:
class TestSNI(SocketDummyServerTestCase):
class TestSNI(SocketDummyServerTestCase):

def test_hostname_in_first_request_packet(self):
done_receiving = Event()
self.buf = b''
def test_hostname_in_first_request_packet(self):
if not util.HAS_SNI:
raise SkipTest('SNI-support not available')

def socket_handler(listener):
sock = listener.accept()[0]
done_receiving = Event()
self.buf = b''

def socket_handler(listener):
sock = listener.accept()[0]

self.buf = sock.recv(65536) # We only accept one packet
done_receiving.set() # let the test know it can proceed
self.buf = sock.recv(65536) # We only accept one packet
done_receiving.set() # let the test know it can proceed

self._start_server(socket_handler)
pool = HTTPSConnectionPool(self.host, self.port)
try:
pool.request('GET', '/', retries=0)
except SSLError: # We are violating the protocol
pass
done_receiving.wait()
self.assertTrue(self.host.encode() in self.buf,
"missing hostname in SSL handshake")
self._start_server(socket_handler)
pool = HTTPSConnectionPool(self.host, self.port)
try:
pool.request('GET', '/', retries=0)
except SSLError: # We are violating the protocol
pass
done_receiving.wait()
self.assertTrue(self.host.encode() in self.buf,
"missing hostname in SSL handshake")


class TestSocketClosing(SocketDummyServerTestCase):
Expand Down Expand Up @@ -102,7 +101,7 @@ def test_connection_refused(self):
# Does the pool retry if there is no listener on the port?
# Note: Socket server is not started until after the test.
pool = HTTPConnectionPool(self.host, self.port)
self.assertRaises(MaxRetryError, pool.request, 'GET', '/')
self.assertRaises(MaxRetryError, pool.request, 'GET', '/', retries=0)
self._start_server(lambda x: None)

def test_connection_timeout(self):
Expand Down
11 changes: 11 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[tox]
envlist = py26, py27, py32, py33, pypy

[testenv]
deps=
nose
tornado
coverage
commands=
nosetests \
[]
Loading