Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Do not remove empty GET/POST parameters #585

Closed
wants to merge 2 commits into from

5 participants

@ysimonson

Is there a reason why tornado currently removes empty GET/POST parameters? It is causing issues with validating forms generated by formalchemy, because formalchemy expects GET/POST parameters to be there, even if they are empty.

@travisbot

This pull request passes (merged ebf17aa into 2b07385).

@superduper

Especially useful for OAuth basestring calculation, when you need list of all parameters even if they have empty values.

@bdarnell
Owner

This has come up several times before and I think it's a good change (with the exception that I'm not sure whether the singular RequestHandler.get_argument should treat empty arguments as unspecified). It is potentially backwards-compatibile, though, so I'd like to hold off until tornado 3.0 (which is not that far off - I'm going to do a 2.4 release soon and then next will probably be 3.0).

@bdarnell bdarnell closed this pull request from a commit
@bdarnell bdarnell Merge commit 'ebf17aa'
Closes #585.
f1ae398
@bdarnell bdarnell closed this in f1ae398
@kung-foo

FYI, this pull does not enable empty POST parameters. I've submitted a pull here with the update: #614

@superduper

@kung-foo nice catch, but still incomplete :P your pull does not enable empty POST parameters for requests with Content-Type multipart/form-data

@kung-foo

ah yes. now I remember starting to look into the multipart processing code and thinking, wtf. nope. :neutral_face:

@superduper

@kung-foo false alarm :blush: your patch seems to be fine. I've checked again parse_multipart_form_data implementation and figured out that there is no filter for empty values on multipart data forms. maybe need to add tests for this case.

@techiev2 techiev2 referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@Rudd-O Rudd-O referenced this pull request from a commit in Rudd-O/tornado
@bdarnell bdarnell Merge commit 'ebf17aa'
Closes #585.
9cbe1c3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 16, 2012
  1. @ysimonson
Commits on Sep 5, 2012
  1. @ysimonson
This page is out of date. Refresh to see the latest.
View
39 tornado/auth.py
@@ -230,20 +230,14 @@ def authorize_redirect(self, callback_uri=None, extra_params=None,
raise Exception("This service does not support oauth_callback")
if http_client is None:
http_client = httpclient.AsyncHTTPClient()
- if getattr(self, "_OAUTH_VERSION", "1.0a") == "1.0a":
- http_client.fetch(
- self._oauth_request_token_url(callback_uri=callback_uri,
- extra_params=extra_params),
- self.async_callback(
- self._on_request_token,
- self._OAUTH_AUTHORIZE_URL,
- callback_uri))
- else:
- http_client.fetch(
- self._oauth_request_token_url(),
- self.async_callback(
- self._on_request_token, self._OAUTH_AUTHORIZE_URL,
- callback_uri))
+
+ request_token_url = self._oauth_request_token_url(
+ callback_uri=callback_uri, extra_params=extra_params)
+
+ callback = self.async_callback(
+ self._on_request_token, self._OAUTH_AUTHORIZE_URL, callback_uri)
+
+ http_client.fetch(request_token_url, callback)
def get_authenticated_user(self, callback, http_client=None):
"""Gets the OAuth authorized user and access token on callback.
@@ -288,14 +282,17 @@ def _oauth_request_token_url(self, callback_uri=None, extra_params=None):
oauth_nonce=escape.to_basestring(binascii.b2a_hex(uuid.uuid4().bytes)),
oauth_version=getattr(self, "_OAUTH_VERSION", "1.0a"),
)
+
+ if callback_uri == "oob":
+ args["oauth_callback"] = "oob"
+ elif callback_uri:
+ args["oauth_callback"] = urlparse.urljoin(
+ self.request.full_url(), callback_uri)
+
+ if extra_params:
+ args.update(extra_params)
+
if getattr(self, "_OAUTH_VERSION", "1.0a") == "1.0a":
- if callback_uri == "oob":
- args["oauth_callback"] = "oob"
- elif callback_uri:
- args["oauth_callback"] = urlparse.urljoin(
- self.request.full_url(), callback_uri)
- if extra_params:
- args.update(extra_params)
signature = _oauth10a_signature(consumer_token, "GET", url, args)
else:
signature = _oauth_signature(consumer_token, "GET", url, args)
View
7 tornado/httpserver.py
@@ -382,12 +382,7 @@ def __init__(self, method, uri, version="HTTP/1.0", headers=None,
self._finish_time = None
self.path, sep, self.query = uri.partition('?')
- arguments = parse_qs_bytes(self.query)
- self.arguments = {}
- for name, values in arguments.iteritems():
- values = [v for v in values if v]
- if values:
- self.arguments[name] = values
+ self.arguments = parse_qs_bytes(self.query, keep_blank_values=True)
def supports_http_1_1(self):
"""Returns True if this request supports HTTP/1.1 semantics"""
View
5 tornado/test/httpserver_test.py
@@ -300,6 +300,11 @@ def test_query_string_encoding(self):
data = json_decode(response.body)
self.assertEqual(data, {u"foo": [u"\u00e9"]})
+ def test_empty_query_string(self):
+ response = self.fetch("/echo?foo=&foo=")
+ data = json_decode(response.body)
+ self.assertEqual(data, {u"foo": [u"", u""]})
+
def test_types(self):
headers = {"Cookie": "foo=bar"}
response = self.fetch("/typecheck?foo=bar", headers=headers)
Something went wrong with that request. Please try again.