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 * Added Python 3 as a dependency for Homebrew installations
to ensure some of the newer HTTP features work out of the box to ensure some of the newer HTTP features work out of the box
for macOS users (starting with HTTPie 0.9.4.). 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) `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> 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 # Various separators used in args
SEP_HEADERS = ':' SEP_HEADERS = ':'
SEP_HEADERS_EMPTY = ';'
SEP_CREDENTIALS = ':' SEP_CREDENTIALS = ':'
SEP_PROXY = ':' SEP_PROXY = ':'
SEP_DATA = '=' SEP_DATA = '='
@ -67,6 +68,7 @@ SEP_GROUP_RAW_JSON_ITEMS = frozenset([
# Separators allowed in ITEM arguments # Separators allowed in ITEM arguments
SEP_GROUP_ALL_ITEMS = frozenset([ SEP_GROUP_ALL_ITEMS = frozenset([
SEP_HEADERS, SEP_HEADERS,
SEP_HEADERS_EMPTY,
SEP_QUERY, SEP_QUERY,
SEP_DATA, SEP_DATA,
SEP_DATA_RAW_JSON, SEP_DATA_RAW_JSON,
@ -655,11 +657,20 @@ def parse_items(items,
data = [] data = []
files = [] files = []
params = [] params = []
for item in items: for item in items:
value = item.value value = item.value
if item.sep == SEP_HEADERS: 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 target = headers
elif item.sep == SEP_QUERY: elif item.sep == SEP_QUERY:
target = params target = params

View File

@ -1,5 +1,7 @@
"""High-level tests.""" """High-level tests."""
import pytest import pytest
from httpie.input import ParseError
from utils import TestEnvironment, http, HTTP_OK from utils import TestEnvironment, http, HTTP_OK
from fixtures import FILE_PATH, FILE_CONTENT from fixtures import FILE_PATH, FILE_CONTENT
@ -75,6 +77,27 @@ def test_headers(httpbin_both):
assert '"Foo": "bar"' in r 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( @pytest.mark.skipif(
is_py26, is_py26,
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only' reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'