Merge pull request #88 from toumorokoshi/parsed_post

Adding parsed_body parameter to simplify checks
This commit is contained in:
Gabriel Falcão
2013-09-29 20:59:20 -07:00
2 changed files with 57 additions and 2 deletions

View File

@@ -33,6 +33,7 @@ import itertools
import warnings
import logging
import traceback
import json
from .compat import (
@@ -102,13 +103,14 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass):
def __init__(self, headers, body=''):
self.body = utf8(body)
self.raw_headers = utf8(headers)
self.rfile = StringIO(b'\r\n\r\n'.join([headers.strip(), body]))
self.rfile = StringIO(b'\r\n\r\n'.join([utf8(headers.strip()), self.body]))
self.wfile = StringIO()
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
self.method = self.command
self.querystring = parse_qs(self.path.split("?", 1)[-1])
self.parsed_body = self.__parse_body(self.body)
def __str__(self):
return 'HTTPrettyRequest(headers={0}, body="{1}")'.format(
@@ -116,6 +118,19 @@ class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass):
self.body,
)
def __parse_body(self, body):
""" Attempt to parse the post based on the content-type passed. Return the regular body if not """
return_value = body.decode('utf-8')
try:
for header in self.headers.keys():
if header.lower() == 'content-type':
if self.headers['content-type'].lower() == 'application/json':
return_value = json.loads(return_value)
elif self.headers['content-type'].lower() == 'application/x-www-form-urlencoded':
return_value = parse_qs(return_value)
finally:
return return_value
class EmptyRequestHeaders(dict):
pass

View File

@@ -25,9 +25,10 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
from __future__ import unicode_literals
import json
from sure import expect
from httpretty import HTTPretty, HTTPrettyError, core
from httpretty.core import URIInfo, BaseClass, Entry, FakeSockFile
from httpretty.core import URIInfo, BaseClass, Entry, FakeSockFile, HTTPrettyRequest
from httpretty.http import STATUSES
try:
@@ -35,6 +36,12 @@ try:
except ImportError:
from unittest.mock import MagicMock
TEST_HEADER = """
GET /test/test.html HTTP/1.1
Host: www.host1.com:80
Content-Type: %(content_type)s
"""
def test_httpretty_should_raise_proper_exception_on_inconsistent_length():
"HTTPretty should raise proper exception on inconsistent Content-Length / "\
@@ -344,3 +351,36 @@ def test_fake_socket_passes_through_shutdown():
s.truesock = MagicMock()
expect(s.shutdown).called_with(socket.SHUT_RD).should_not.throw(AttributeError)
s.truesock.shutdown.assert_called_with(socket.SHUT_RD)
def test_HTTPrettyRequest_json_body():
""" A content-type of application/json should parse a valid json body """
header = TEST_HEADER % {'content_type': 'application/json'}
test_dict = {'hello': 'world'}
request = HTTPrettyRequest(header, json.dumps(test_dict))
expect(request.parsed_body).to.equal(test_dict)
def test_HTTPrettyRequest_invalid_json_body():
""" A content-type of application/json with an invalid json body should return the content unaltered """
header = TEST_HEADER % {'content_type': 'application/json'}
invalid_json = u"{'hello', 'world','thisstringdoesntstops}"
request = HTTPrettyRequest(header, invalid_json)
expect(request.parsed_body).to.equal(invalid_json)
def test_HTTPrettyRequest_queryparam():
""" A content-type of x-www-form-urlencoded with a valid queryparam body should return parsed content """
header = TEST_HEADER % {'content_type': 'application/x-www-form-urlencoded'}
valid_queryparam = u"hello=world&this=isavalidquerystring"
valid_results = {'hello': ['world'], 'this': ['isavalidquerystring']}
request = HTTPrettyRequest(header, valid_queryparam)
expect(request.parsed_body).to.equal(valid_results)
def test_HTTPrettyRequest_arbitrarypost():
""" A non-handled content type request's post body should return the content unaltered """
header = TEST_HEADER % {'content_type': 'thisis/notarealcontenttype'}
gibberish_body = "1234567890!@#$%^&*()"
request = HTTPrettyRequest(header, gibberish_body)
expect(request.parsed_body).to.equal(gibberish_body)