diff --git a/httpretty/__init__.py b/httpretty/__init__.py index 751198a..9a07ee6 100644 --- a/httpretty/__init__.py +++ b/httpretty/__init__.py @@ -66,9 +66,10 @@ class Py3kObject(object): from datetime import datetime from datetime import timedelta try: - from urllib.parse import urlsplit, parse_qs + from urllib.parse import urlsplit, urlunsplit, parse_qs, quote, quote_plus except ImportError: - from urlparse import urlsplit, parse_qs + from urlparse import urlsplit, urlunsplit, parse_qs + from urllib import quote, quote_plus try: from http.server import BaseHTTPRequestHandler @@ -599,6 +600,13 @@ class Entry(Py3kObject): fk.seek(0) +def url_fix(s, charset='utf-8'): + scheme, netloc, path, querystring, fragment = urlsplit(s) + path = quote(path, b'/%') + querystring = quote_plus(querystring, b':&=') + return urlunsplit((scheme, netloc, path, querystring, fragment)) + + class URIInfo(Py3kObject): def __init__(self, username='', @@ -643,8 +651,16 @@ class URIInfo(Py3kObject): return hash(text_type(self)) def __eq__(self, other): - self_tuple = (self.port, decode_utf8(self.hostname), decode_utf8(self.path)) - other_tuple = (other.port, decode_utf8(other.hostname), decode_utf8(other.path)) + self_tuple = ( + self.port, + decode_utf8(self.hostname), + url_fix(decode_utf8(self.path)), + ) + other_tuple = ( + other.port, + decode_utf8(other.hostname), + url_fix(decode_utf8(other.path)), + ) return self_tuple == other_tuple def full_url(self): diff --git a/tests/functional/test_requests.py b/tests/functional/test_requests.py index bdf43d6..67c16a1 100644 --- a/tests/functional/test_requests.py +++ b/tests/functional/test_requests.py @@ -548,3 +548,16 @@ def test_httpretty_should_allow_multiple_responses_with_multiple_methods(): expect(requests.post(url).text).to.equal('d') expect(requests.post(url).text).to.equal('d') expect(requests.post(url).text).to.equal('d') + + +@httprettified +def test_httpretty_should_normalize_url_patching(): + u"HTTPretty should normalize all url patching" + + HTTPretty.register_uri( + HTTPretty.GET, + "http://yipit.com/foo(bar)", + body="Find the best daily deals") + + response = requests.get('http://yipit.com/foo%28bar%29') + expect(response.text).to.equal('Find the best daily deals') diff --git a/tests/functional/testserver.py b/tests/functional/testserver.py index 28f216b..03634a5 100644 --- a/tests/functional/testserver.py +++ b/tests/functional/testserver.py @@ -44,6 +44,21 @@ from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop from multiprocessing import Process +PY3 = sys.version_info[0] == 3 +if PY3: + text_type = str + byte_type = bytes +else: + text_type = unicode + byte_type = str + + +def utf8(s): + if isinstance(s, text_type): + s = s.encode('utf-8') + + return byte_type(s) + true_socket = socket.socket PY3 = sys.version_info[0] == 3 @@ -119,6 +134,10 @@ class TCPServer(object): data = conn.recv(1024) conn.send(b"RECEIVED: " + bytes(data)) + print("*" * 100) + print(data) + print("*" * 100) + conn.close() args = [self.port]