From 4b1acaf8c8be472d79051c1f7f171d31b10ff9c8 Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Sat, 16 Mar 2013 19:48:58 -0400 Subject: [PATCH 1/2] Normalize urls matching for url quoting --- httpretty/__init__.py | 24 ++++++++++++++++++++---- tests/functional/test_requests.py | 13 +++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/httpretty/__init__.py b/httpretty/__init__.py index 4b24a67..65da2fe 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 @@ -582,6 +583,13 @@ class Entry(Py3kObject): fk.seek(0) +def url_fix(s, charset='utf-8'): + scheme, netloc, path, querystring, fragment = urlsplit(s) + path = quote(path, '/%') + querystring = quote_plus(querystring, ':&=') + return urlunsplit((scheme, netloc, path, querystring, fragment)) + + class URIInfo(Py3kObject): def __init__(self, username='', @@ -626,8 +634,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 b682927..2aaa738 100644 --- a/tests/functional/test_requests.py +++ b/tests/functional/test_requests.py @@ -482,3 +482,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') From 9b70834279c51f11744b6fe83857a4c6bc2e07de Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Sat, 16 Mar 2013 21:22:29 -0400 Subject: [PATCH 2/2] fix tests for py26 and py33 --- httpretty/__init__.py | 4 ++-- tests/functional/test_bypass.py | 2 +- tests/functional/testserver.py | 26 +++++++++++++++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/httpretty/__init__.py b/httpretty/__init__.py index 65da2fe..8071381 100644 --- a/httpretty/__init__.py +++ b/httpretty/__init__.py @@ -585,8 +585,8 @@ class Entry(Py3kObject): def url_fix(s, charset='utf-8'): scheme, netloc, path, querystring, fragment = urlsplit(s) - path = quote(path, '/%') - querystring = quote_plus(querystring, ':&=') + path = quote(path, b'/%') + querystring = quote_plus(querystring, b':&=') return urlunsplit((scheme, netloc, path, querystring, fragment)) diff --git a/tests/functional/test_bypass.py b/tests/functional/test_bypass.py index 0b91407..d8d73db 100644 --- a/tests/functional/test_bypass.py +++ b/tests/functional/test_bypass.py @@ -130,4 +130,4 @@ def test_using_httpretty_with_other_tcp_protocols(context): expect(got1).to.equal(b'BAR') - expect(context.client.send("foobar")).to.equal("RECEIVED: foobar") + expect(context.client.send("foobar")).to.equal(b"RECEIVED: foobar") diff --git a/tests/functional/testserver.py b/tests/functional/testserver.py index a0f48f0..d7dab0f 100644 --- a/tests/functional/testserver.py +++ b/tests/functional/testserver.py @@ -27,6 +27,7 @@ from __future__ import unicode_literals import os +import sys try: import io @@ -43,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 @@ -111,11 +127,11 @@ class TCPServer(object): while True: data = conn.recv(1024) - conn.send("RECEIVED: " + data) + conn.send(b"RECEIVED: " + data) - print "*" * 100 - print data - print "*" * 100 + print("*" * 100) + print(data) + print("*" * 100) conn.close() @@ -140,7 +156,7 @@ class TCPClient(object): self.sock.connect(('localhost', self.port)) def send(self, what): - self.sock.sendall(str(what)) + self.sock.sendall(utf8(what)) return self.sock.recv(len(what) + 11) def close(self):