Added the ability to unset headers

Closes #476
This commit is contained in:
Jakub Roztocil 2016-07-02 11:50:30 +02:00
parent 0c7c248dce
commit 5acbc904b7
4 changed files with 55 additions and 3 deletions

View File

@ -12,6 +12,8 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
* Added Python 3 as a dependency for Homebrew installations
to ensure some of the newer HTTP features work out of the box
for macOS users (starting with HTTPie 0.9.4.).
* Added the ability to unset a request header with ``Header:``, and send an
empty value with ``Header;``.
`0.9.4`_ (2016-07-01)

View File

@ -560,7 +560,23 @@ There are a couple of default headers that HTTPie sets:
Host: <taken-from-URL>
Any of the default headers can be overwritten.
Any of the default headers can be overwritten and some of them unset.
To unset a header that has already been specified (such a one of the default
headers), use ``Header:``:
.. code-block:: bash
$ http httpbin.org/headers Accept: User-Agent:
To send a header with an empty value, use ``Header;``:
.. code-block:: bash
$ http httpbin.org/headers 'Header;'
==============

View File

@ -34,6 +34,7 @@ HTTPS = 'https://'
# Various separators used in args
SEP_HEADERS = ':'
SEP_HEADERS_EMPTY = ';'
SEP_CREDENTIALS = ':'
SEP_PROXY = ':'
SEP_DATA = '='
@ -67,6 +68,7 @@ SEP_GROUP_RAW_JSON_ITEMS = frozenset([
# Separators allowed in ITEM arguments
SEP_GROUP_ALL_ITEMS = frozenset([
SEP_HEADERS,
SEP_HEADERS_EMPTY,
SEP_QUERY,
SEP_DATA,
SEP_DATA_RAW_JSON,
@ -655,11 +657,20 @@ def parse_items(items,
data = []
files = []
params = []
for item in items:
value = item.value
if item.sep == SEP_HEADERS:
if value == '':
# No value => unset the header
value = None
target = headers
elif item.sep == SEP_HEADERS_EMPTY:
if item.value:
raise ParseError(
'Invalid item "%s" '
'(to specify an empty header use `Header;`)'
% item.orig
)
target = headers
elif item.sep == SEP_QUERY:
target = params

View File

@ -1,5 +1,7 @@
"""High-level tests."""
import pytest
from httpie.input import ParseError
from utils import TestEnvironment, http, HTTP_OK
from fixtures import FILE_PATH, FILE_CONTENT
@ -75,6 +77,27 @@ def test_headers(httpbin_both):
assert '"Foo": "bar"' in r
def test_headers_unset(httpbin_both):
r = http('GET', httpbin_both + '/headers')
assert 'Accept' in r.json['headers'] # default Accept present
r = http('GET', httpbin_both + '/headers', 'Accept:')
assert 'Accept' not in r.json['headers'] # default Accept unset
def test_headers_empty_value(httpbin_both):
r = http('GET', httpbin_both + '/headers')
assert r.json['headers']['Accept'] # default Accept has value
r = http('GET', httpbin_both + '/headers', 'Accept;')
assert r.json['headers']['Accept'] == '' # Accept has no value
def test_headers_empty_value_with_value_gives_error(httpbin):
with pytest.raises(ParseError):
http('GET', httpbin + '/headers', 'Accept;SYNTAX_ERROR')
@pytest.mark.skipif(
is_py26,
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'