Permalink
Browse files

Ensure that full querystring is printent with -v.

The `key==value` parameters weren't included in the Request-Line URL.

Also added tests.
  • Loading branch information...
1 parent 9391c89 commit f5cfd0143b083c907084f5d527a9bd97e02a28f8 @jkbrzt committed Jul 25, 2012
Showing with 87 additions and 21 deletions.
  1. +0 −3 httpie/cliparse.py
  2. +33 −16 httpie/models.py
  3. +54 −2 tests/tests.py
View
@@ -384,9 +384,6 @@ def parse_items(items, data=None, headers=None, files=None, params=None):
else:
raise ParseError('%s is not valid item' % item.orig)
- if key in target:
- ParseError('duplicate item %s (%s)' % (item.key, item.orig))
-
target[key] = value
return headers, data, files, params
View
@@ -63,36 +63,53 @@ def format(self, prettifier=None, with_headers=True, with_body=True):
@staticmethod
def from_request(request):
"""Make an `HTTPMessage` from `requests.models.Request`."""
- url = urlparse(request.url)
- request_headers = dict(request.headers)
- if 'Host' not in request_headers:
- request_headers['Host'] = url.netloc
- try:
- body = request.data
- except AttributeError:
- # requests < 0.12.1
- body = request._enc_data
-
- if isinstance(body, dict):
- # --form
- body = request.__class__._encode_params(body)
+ url = urlparse(request.url)
+ # Querystring
+ qs = ''
+ if url.query or request.params:
+ qs = '?'
+ if url.query:
+ qs += url.query
+ # Requests doesn't make params part of ``request.url``.
+ if request.params:
+ if url.query:
+ qs += '&'
+ qs += type(request)._encode_params(request.params)
+
+ # Request-Line
request_line = '{method} {path}{query} HTTP/1.1'.format(
method=request.method,
path=url.path or '/',
- query='' if url.query is '' else '?' + url.query
+ query=qs
)
+
+ # Headers
+ headers = dict(request.headers)
+ content_type = headers.get('Content-Type')
+ if 'Host' not in headers:
+ headers['Host'] = url.netloc
headers = '\n'.join(
str('%s: %s') % (name, value)
for name, value
- in request_headers.items()
+ in headers.items()
)
+
+ # Body
+ try:
+ body = request.data
+ except AttributeError:
+ # requests < 0.12.1
+ body = request._enc_data
+ if isinstance(body, dict):
+ body = type(request)._encode_params(body)
+
return HTTPMessage(
line=request_line,
headers=headers,
body=body,
- content_type=request_headers.get('Content-Type')
+ content_type=content_type
)
@classmethod
View
@@ -107,8 +107,10 @@ def http(*args, **kwargs):
except ValueError:
pass
else:
- r.strip().index('\n')
- r.json = json.loads(j)
+ try:
+ r.json = json.loads(j)
+ except ValueError:
+ pass
return r
@@ -217,6 +219,56 @@ def test_headers(self):
self.assertIn('"Foo": "bar"', r)
+class QuerystringTest(BaseTestCase):
+
+ def test_query_string_params_in_url(self):
+ r = http(
+ '--print=Hhb',
+ 'GET',
+ httpbin('/get?a=1&b=2')
+ )
+
+ path = '/get?a=1&b=2'
+ url = httpbin(path)
+
+ self.assertIn('HTTP/1.1 200', r)
+ self.assertIn('GET %s HTTP/1.1' % path, r)
+ self.assertIn('"url": "%s"' % url, r)
+
+ def test_query_string_params_items(self):
+ r = http(
+ '--print=Hhb',
+ 'GET',
+ httpbin('/get'),
+ 'a==1',
+ 'b==2'
+ )
+
+ path = '/get?a=1&b=2'
+ url = httpbin(path)
+
+ self.assertIn('HTTP/1.1 200', r)
+ self.assertIn('GET %s HTTP/1.1' % path, r)
+ self.assertIn('"url": "%s"' % url, r)
+
+ def test_query_string_params_in_url_and_items_with_duplicates(self):
+ r = http(
+ '--print=Hhb',
+ 'GET',
+ httpbin('/get?a=1&a=1'),
+ 'a==1',
+ 'a==1',
+ 'b==2',
+ )
+
+ path = '/get?a=1&a=1&a=1&a=1&b=2'
+ url = httpbin(path)
+
+ self.assertIn('HTTP/1.1 200', r)
+ self.assertIn('GET %s HTTP/1.1' % path, r)
+ self.assertIn('"url": "%s"' % url, r)
+
+
class AutoContentTypeAndAcceptHeadersTest(BaseTestCase):
"""
Test that Accept and Content-Type correctly defaults to JSON,

0 comments on commit f5cfd01

Please sign in to comment.