1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

Added the option to print the request

It is now possible to print any combination of the following
request-response bits:

    - Request headers (H)
    - Request body (B)
    - Response headers (h)
    - Response body (b)

The output is controlled by the --print / -p option which
defaults to "hb" (i.e., response headers and response body).

Note that -p was previously shortcut for --prety.

Closes #29.
This commit is contained in:
Jakub Roztocil
2012-03-14 00:05:44 +01:00
parent 31c28807c9
commit 02622a4135
6 changed files with 168 additions and 57 deletions

View File

@@ -2,6 +2,7 @@
import os
import sys
import json
from urlparse import urlparse
import requests
try:
from collections import OrderedDict
@@ -18,6 +19,69 @@ TYPE_FORM = 'application/x-www-form-urlencoded; charset=utf-8'
TYPE_JSON = 'application/json; charset=utf-8'
class HTTPMessage(object):
def __init__(self, line, headers, body, content_type=None):
# {Request,Status}-Line
self.line = line
self.headers = headers
self.body = body
self.content_type = content_type
def format_http_message(message, prettifier=None,
with_headers=True, with_body=True):
bits = []
if with_headers:
if prettifier:
bits.append(prettifier.headers(message.line))
bits.append(prettifier.headers(message.headers))
else:
bits.append(message.line)
bits.append(message.headers)
if with_body:
bits.append('\n')
if with_body:
if prettifier and message.content_type:
bits.append(prettifier.body(message.body, message.content_type))
else:
bits.append(message.body)
bits = [bit.strip() for bit in bits]
bits.append('')
return '\n'.join(bits)
def make_request_message(request):
"""Make an `HTTPMessage` from `requests.models.Request`."""
url = urlparse(request.url)
request_headers = dict(request.headers)
request_headers['Host'] = url.netloc
return HTTPMessage(
line='{method} {path} HTTP/1.1'.format(
method=request.method,
path=url.path),
headers='\n'.join('%s: %s' % (name, value)
for name, value
in request_headers.iteritems()),
body=request._enc_data,
content_type=request_headers.get('Content-Type')
)
def make_response_message(response):
"""Make an `HTTPMessage` from `requests.models.Response`."""
encoding = response.encoding or 'ISO-8859-1'
original = response.raw._original_response
response_headers = response.headers
return HTTPMessage(
line='HTTP/{version} {status} {reason}'.format(
version='.'.join(str(original.version)),
status=original.status, reason=original.reason,),
headers=str(original.msg).decode(encoding),
body=response.content.decode(encoding) if response.content else u'',
content_type=response_headers.get('Content-Type'))
def main(args=None,
stdin=sys.stdin,
stdin_isatty=sys.stdin.isatty(),
@@ -28,7 +92,8 @@ def main(args=None,
args = parser.parse_args(args if args is not None else sys.argv[1:])
do_prettify = (args.prettify is True or
(args.prettify == cli.PRETTIFY_STDOUT_TTY_ONLY and stdout_isatty))
(args.prettify == cli.PRETTIFY_STDOUT_TTY_ONLY
and stdout_isatty))
# Parse request headers and data from the command line.
headers = CaseInsensitiveDict()
@@ -79,36 +144,31 @@ def main(args=None,
sys.stderr.write(str(e.message) + '\n')
sys.exit(1)
# Reconstruct the raw response.
encoding = response.encoding or 'ISO-8859-1'
original = response.raw._original_response
status_line, headers, body = (
'HTTP/{version} {status} {reason}'.format(
version='.'.join(str(original.version)),
status=original.status, reason=original.reason,
),
str(original.msg).decode(encoding),
response.content.decode(encoding) if response.content else u''
)
prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
if do_prettify:
prettify = pretty.PrettyHttp(args.style)
if args.print_headers:
status_line = prettify.headers(status_line)
headers = prettify.headers(headers)
if args.print_body and 'Content-Type' in response.headers:
body = prettify.body(body, response.headers['Content-Type'])
output_request = (cli.OUT_REQUEST_HEADERS in args.output_options
or cli.OUT_REQUEST_BODY in args.output_options)
# Output.
# TODO: preserve leading/trailing whitespaces in the body.
# Some of the Pygments styles add superfluous line breaks.
if args.print_headers:
stdout.write(status_line.strip())
stdout.write('\n')
stdout.write(headers.strip().encode('utf-8'))
stdout.write('\n\n')
if args.print_body:
stdout.write(body.strip().encode('utf-8'))
output_response = (cli.OUT_RESPONSE_HEADERS in args.output_options
or cli.OUT_RESPONSE_BODY in args.output_options)
if output_request:
stdout.write(format_http_message(
message=make_request_message(response.request),
prettifier=prettifier,
with_headers=cli.OUT_REQUEST_HEADERS in args.output_options,
with_body=cli.OUT_REQUEST_BODY in args.output_options
).encode('utf-8'))
if output_response:
stdout.write('\n')
if output_response:
stdout.write(format_http_message(
message=make_response_message(response),
prettifier=prettifier,
with_headers=cli.OUT_RESPONSE_HEADERS in args.output_options,
with_body=cli.OUT_RESPONSE_BODY in args.output_options
).encode('utf-8'))
stdout.write('\n')