Skip to content

Commit

Permalink
Replace --show-redirects with --all and add --print-others, -P
Browse files Browse the repository at this point in the history
With --all, any intermediary requests/responses are shown (such as redirects
 or the initial unauthorized Digest auth request).

 The --print-others, -P option works like --print, -p, but only applies to
 intermediary requests/responses. The default behaviour is to inherit
 the value of -p.
  • Loading branch information
jkbrzt committed Mar 6, 2016
1 parent a6ebc44 commit 6e1dbad
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 52 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
to use for HTTPS requests.
* Added JSON detection with ``--json, -j`` to work around incorrect
``Content-Type``
* Added ``--show-redirects, -R`` to show intermediate responses with ``--follow``
* Added ``--all`` to show intermediate responses such as redirects (with ``--follow``)
* Added ``--print-others, -P WHAT``
* Added ``--max-redirects`` (default 30)
* Added ``-A`` as short name for ``--auth-type``
* Added ``-F`` as short name for ``--follow``
Expand Down
36 changes: 32 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -636,15 +636,15 @@ response is shown. To instruct HTTPie to follow the ``Location`` header of
``30x`` responses and show the final response instead, use the ``--follow, -F`` option.
If you additionally wish to see the intermediary requests/responses,
then use the ``--show-redirects, -R`` option as well.
then use the ``--all`` option as well.
To change the default limit of maximum 30 redirects, use the
``--max-redirects=<limit>`` option.
.. code-block:: bash
$ http --follow --show-redirects --max-redirects=5 httpbin.org/redirect/3
$ http --follow --all --max-redirects=5 httpbin.org/redirect/3
=======
Expand Down Expand Up @@ -771,15 +771,16 @@ You can use the following command to test SNI support:
Output Options
==============
By default, HTTPie outputs the whole response message (headers as well as the
body).
By default, HTTPie only outputs the final response and whole response message
is printed (headers as well as the body).
You can control what should be printed via several options:
================= =====================================================
``--headers, -h`` Only the response headers are printed.
``--body, -b`` Only the response body is printed.
``--verbose, -v`` Print the whole HTTP exchange (request and response).
This option also enables ``--all`` (see bellow).
``--print, -p`` Selects parts of the HTTP exchange.
================= =====================================================
Expand Down Expand Up @@ -833,6 +834,33 @@ Print request and response headers:
$ http --print=Hh PUT httpbin.org/put hello=world
---------------------------------------
Viewing Intermediary Requests/Responses
---------------------------------------
If you'd like to see any intermediary requests/responses together with the
final one, then use the ``--all`` option. Intermediary requests include
followed redirects (with ``--follow``), the first unauthorized request when
Digest auth is used (``--auth=digest``), etc. They are by default also
formatted according to ``--print, -p`` (and its shortcuts described above),
which can be customized with ``--print-others, -P`` which takes the same
arguments as ``--print, -p`` but applies to the intermediary requests only.
View all responses that lead to the final one:
.. code-block:: bash
$ http --all --follow httpbin.org/redirect/3
Print the final and the intermediary requests/responses differently:
.. code-block:: bash
$ http --all --follow --print=hH --print-others=H httpbin.org/redirect/3
-------------------------
Conditional Body Download
-------------------------
Expand Down
57 changes: 36 additions & 21 deletions httpie/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,17 +250,6 @@ def _split_lines(self, text, width):
default=OUTPUT_OPTIONS_DEFAULT,
)
)
output_options.add_argument(
'--verbose', '-v',
dest='output_options',
action='store_const',
const=''.join(OUTPUT_OPTIONS),
help="""
Print the whole request as well as the response. Shortcut for --print={0}.
"""
.format(''.join(OUTPUT_OPTIONS))
)
output_options.add_argument(
'--headers', '-h',
dest='output_options',
Expand All @@ -284,6 +273,42 @@ def _split_lines(self, text, width):
.format(OUT_RESP_BODY)
)

output_options.add_argument(
'--verbose', '-v',
dest='verbose',
action='store_true',
help="""
Verbose output. Print the whole request as well as the response. Also print
any intermediary requests/responses (such as redirects).
It's a shortcut for: --all --print={0}
"""
.format(''.join(OUTPUT_OPTIONS))
)
output_options.add_argument(
'--all',
default=False,
action='store_true',
help="""
By default, only the final request/response is shown. Use this flag to show
any intermediary requests/responses as well. Intermediary requests include
followed redirects (with --follow), the first unauthorized request when
Digest auth is used (--auth=digest), etc.
"""
)
output_options.add_argument(
'--print-others', '-P',
dest='output_options_others',
metavar='WHAT',
help="""
The same as --print, -p but applies only to intermediary requests/responses
(such as redirects) when their inclusion is enabled with --all. If this
options is not specified, then they are formatted the same way as the final
response.
"""
)
output_options.add_argument(
'--stream', '-S',
action='store_true',
Expand Down Expand Up @@ -454,16 +479,6 @@ def _split_lines(self, text, width):
"""
)

network.add_argument(
'--show-redirects', '-R',
default=False,
action='store_true',
help="""
Show all responses within the redirect chain (works with --follow).
"""
)

network.add_argument(
'--max-redirects',
type=int,
Expand Down
15 changes: 10 additions & 5 deletions httpie/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ def program(args, env, log_error):
)
downloader.pre_request(args.headers)

last_response = get_response(args, config_dir=env.config.directory)
if args.show_redirects:
responses = last_response.history + [last_response]
final_response = get_response(args, config_dir=env.config.directory)
if args.all:
responses = final_response.history + [final_response]
else:
responses = [last_response]
responses = [final_response]

for response in responses:

Expand All @@ -121,6 +121,11 @@ def program(args, env, log_error):
env=env,
request=response.request,
response=response,
output_options=(
args.output_options
if response is final_response
else args.output_options_others
)
),
# NOTE: `env.stdout` will in fact be `stderr` with `--download`
'outfile': env.stdout,
Expand All @@ -140,7 +145,7 @@ def program(args, env, log_error):

if downloader and exit_status == ExitStatus.OK:
# Last response body download.
download_stream, download_to = downloader.start(last_response)
download_stream, download_to = downloader.start(final_response)
write_stream(
stream=download_stream,
outfile=download_to,
Expand Down
36 changes: 25 additions & 11 deletions httpie/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,18 +359,32 @@ def _process_output_options(self):
The default output options are stdout-type-sensitive.
"""
if not self.args.output_options:
self.args.output_options = (
OUTPUT_OPTIONS_DEFAULT
if self.env.stdout_isatty
else OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED
)
def check_options(value, option):
unknown = set(value) - OUTPUT_OPTIONS
if unknown:
self.error('Unknown output options: {0}={1}'.format(
option,
','.join(unknown)
))

if self.args.verbose:
self.args.all = True

if self.args.output_options is None:
if self.args.verbose:
self.args.output_options = ''.join(OUTPUT_OPTIONS)
else:
self.args.output_options = (
OUTPUT_OPTIONS_DEFAULT
if self.env.stdout_isatty
else OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED
)

unknown_output_options = set(self.args.output_options) - OUTPUT_OPTIONS
if unknown_output_options:
self.error(
'Unknown output options: %s' % ','.join(unknown_output_options)
)
if self.args.output_options_others is None:
self.args.output_options_others = self.args.output_options

check_options(self.args.output_options, '--print')
check_options(self.args.output_options_others, '--print-others')

if self.args.download and OUT_RESP_BODY in self.args.output_options:
# Response body is always downloaded with --download and it goes
Expand Down
10 changes: 5 additions & 5 deletions httpie/output/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ def write_stream_with_colors_win_py3(stream, outfile, flush):
outfile.flush()


def build_output_stream(args, env, request, response):
def build_output_stream(args, env, request, response, output_options):
"""Build and return a chain of iterators over the `request`-`response`
exchange each of which yields `bytes` chunks.
"""
req_h = OUT_REQ_HEAD in args.output_options
req_b = OUT_REQ_BODY in args.output_options
resp_h = OUT_RESP_HEAD in args.output_options
resp_b = OUT_RESP_BODY in args.output_options
req_h = OUT_REQ_HEAD in output_options
req_b = OUT_REQ_BODY in output_options
resp_h = OUT_RESP_HEAD in output_options
resp_b = OUT_RESP_BODY in output_options
req = req_h or req_b
resp = resp_h or resp_b

Expand Down
32 changes: 27 additions & 5 deletions tests/test_redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,38 @@
from utils import http, HTTP_OK


def test_follow_no_show_redirects(httpbin):
def test_follow_all_redirects_shown(httpbin):
r = http('--follow', '--all', httpbin.url + '/redirect/2')
assert r.count('HTTP/1.1') == 3
assert r.count('HTTP/1.1 302 FOUND', 2)
assert HTTP_OK in r


def test_follow_without_all_redirects_hidden(httpbin):
r = http('--follow', httpbin.url + '/redirect/2')
assert r.count('HTTP/1.1') == 1
assert HTTP_OK in r


def test_follow_show_redirects(httpbin):
r = http('--follow', '--show-redirects', httpbin.url + '/redirect/2')
assert r.count('HTTP/1.1') == 3
assert r.count('HTTP/1.1 302 FOUND', 2)
def test_follow_all_output_options_used_for_redirects(httpbin):
r = http('--check-status',
'--follow',
'--all',
'--print=H',
httpbin.url + '/redirect/2')
assert r.count('GET /') == 3
assert HTTP_OK not in r


def test_follow_redirect_output_options(httpbin):
r = http('--check-status',
'--follow',
'--all',
'--print=h',
'--print-others=H',
httpbin.url + '/redirect/2')
assert r.count('GET /') == 2
assert 'HTTP/1.1 302 FOUND' not in r
assert HTTP_OK in r


Expand Down

0 comments on commit 6e1dbad

Please sign in to comment.