raise KeyError('unknown method ' + request.method)
# Handle curl's cryptic options for every individual HTTP method
- if request.method in ("POST", "PUT"):
+ if request.method == "GET":
+ if request.body is not None:
+ raise AssertionError('Body must be empty for GET request')
+ elif request.method in ("POST", "PUT") or request.body:
if request.body is None:
raise AssertionError(
'Body must not be empty for "%s" request'
curl.setopt(pycurl.IOCTLFUNCTION, ioctl)
curl.setopt(pycurl.POSTFIELDSIZE, len(request.body))
else:
+ curl.setopt(pycurl.UPLOAD, True)
curl.setopt(pycurl.INFILESIZE, len(request.body))
- elif request.method == "GET":
- if request.body is not None:
- raise AssertionError('Body must be empty for GET request')
if request.auth_username is not None:
userpwd = "%s:%s" % (request.auth_username, request.auth_password or '')
from __future__ import absolute_import, division, print_function, with_statement
+import json
from hashlib import md5
from tornado.escape import utf8
from tornado.testing import AsyncHTTPTestCase
from tornado.test import httpclient_test
from tornado.test.util import unittest
-from tornado.web import Application, RequestHandler
+from tornado.web import Application, RequestHandler, URLSpec
+
try:
import pycurl
def test_fail_custom_reason(self):
response = self.fetch('/custom_fail_reason')
self.assertEqual(str(response.error), "HTTP 400: Custom reason")
+
+
+class ContactListHandler(RequestHandler):
+
+ contact_list = {
+ "someone": {
+ "telephone": "1-800-247-9792",
+ "email": "some@email.com"
+ },
+ "another": {
+ "telephone": "1-104-132-7713",
+ "email": "other@email.com"
+ }
+ }
+
+ def get(self, contact_name):
+ data = self.contact_list.get(contact_name)
+ self.write(data)
+
+ def patch(self, contact_name):
+ """
+ Patch implementation according to RFC-6902
+ http://tools.ietf.org/html/rfc6902
+ """
+ patch_data = json.loads(self.request.body)
+ for patch_item in patch_data:
+ if patch_item["op"] == "replace":
+ attribute = patch_item["path"]
+ value = patch_item["value"]
+ self.contact_list[contact_name][attribute] = value
+
+
+@unittest.skipIf(pycurl is None, "pycurl module not present")
+class NonStandardMethodCurlHTTPClientTestCase(AsyncHTTPTestCase):
+
+ def setUp(self):
+ super(NonStandardMethodCurlHTTPClientTestCase, self).setUp()
+ self.http_client = CurlAsyncHTTPClient(self.io_loop,
+ defaults=dict(allow_ipv6=False))
+
+ def get_app(self):
+ return Application([
+ ('/(?P<contact_name>[\w\-]+)', ContactListHandler),
+ ])
+
+ def fetch(self, path, body=None, **kwargs):
+ kwargs['url'] = self.get_url(path)
+ request = HTTPRequest(**kwargs)
+ if body is not None:
+ request.body = body
+ request.allow_nonstandard_methods = True
+ self.http_client.fetch(request, self.stop, method=None)
+ return self.wait()
+
+ def test_get(self):
+ response = self.fetch("/someone", method='GET')
+ self.assertEqual(response.code, 200)
+ computed_body = json.loads(response.body)
+ expected_body = {
+ "telephone": "1-800-247-9792",
+ "email": "some@email.com"
+ }
+ self.assertEqual(computed_body, expected_body)
+
+ def test_patch_with_payload(self):
+ patch_list = [
+ {
+ "op": "replace",
+ "path": "telephone",
+ "value": "55-21-99756-1934"
+ }
+ ]
+ body = json.dumps(patch_list)
+ response_patch = self.fetch("/someone", method='PATCH', body=body)
+ self.assertEqual(response_patch.code, 200)
+
+ response_get = self.fetch("/someone", method="GET")
+ computed_body = json.loads(response_get.body)
+ expected_body = {
+ "telephone": "55-21-99756-1934",
+ "email": "some@email.com"
+ }
+ self.assertEqual(computed_body, expected_body)