mirror of
https://github.com/httpie/cli.git
synced 2025-08-16 18:41:33 +02:00
Compare commits
20 Commits
2.4.0
...
feature/te
Author | SHA1 | Date | |
---|---|---|---|
46fa79eff8 | |||
fc45bf0fe3 | |||
56c4ba1794 | |||
8f83bfe767 | |||
a32ad344dd | |||
c53fbe5ae3 | |||
070ba9fa5a | |||
82ee071362 | |||
97dffb35a2 | |||
18af03ac18 | |||
904dd4107a | |||
8efabc86e6 | |||
cc20488f49 | |||
b918972862 | |||
84c7327057 | |||
e944dbd7fa | |||
157f3a1840 | |||
61dbadb730 | |||
7be25d0751 | |||
5d5a8b4091 |
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a possible bug in HTTPie
|
||||
title: ''
|
||||
labels: "new, bug"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Checklist**
|
||||
|
||||
- [ ] I've searched for similar issues.
|
||||
- [ ] I'm using the the latest version of HTTPie.
|
||||
|
||||
---
|
||||
|
||||
**What are the steps to reproduce the problem?**
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
|
||||
**What is the expected result?**
|
||||
|
||||
|
||||
**What happens instead?**
|
||||
|
||||
|
||||
**Debug output**
|
||||
|
||||
Please re-run the command with `--debug`, then copy the entire command & output and paste both below:
|
||||
|
||||
```
|
||||
$ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
|
||||
<COMPLETE OUTPUT>
|
||||
```
|
||||
|
||||
|
||||
**Provide any additional information, screenshots, or code examples below:**
|
24
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an enhancement for HTTPie
|
||||
title: ''
|
||||
labels: "new, enhancement"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
**Checklist**
|
||||
|
||||
- [ ] I've searched for similar feature requests.
|
||||
|
||||
---
|
||||
|
||||
**What enhancement would you like to see?**
|
||||
|
||||
|
||||
**What problem does it solve?**
|
||||
|
||||
E.g. “I'm always frustrated when [...]”, “I’m trying to do […] so that […]”.
|
||||
|
||||
|
||||
**Provide any additional information, screenshots, or code examples below:**
|
||||
|
10
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Other
|
||||
about: Anything else that isn't a feature or a bug
|
||||
title: ''
|
||||
labels: "new"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
If you have a general question, please consider asking on Discord: https://httpie.io/chat
|
@ -7,10 +7,15 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
|
||||
|
||||
|
||||
|
||||
`2.5.0-dev`_ (unreleased)
|
||||
-------------------------
|
||||
* Fixed ``--continue --download`` with a single byte to be downloaded left. (`#1032`_)
|
||||
|
||||
|
||||
`2.4.0`_ (2021-02-06)
|
||||
---------------------
|
||||
* Added support for ``--session`` cookie expiration based on ``Set-Cookie: max-age=<n>``. (`#1029`_)
|
||||
* Show a ``--check-status`` warning with ``--quiet`` as well, not only when the output si redirected. (`#1026`_)
|
||||
* Show a ``--check-status`` warning with ``--quiet`` as well, not only when the output is redirected. (`#1026`_)
|
||||
* Fixed upload with ``--session`` (`#1020`_).
|
||||
* Fixed a missing blank line between request and response (`#1006`_).
|
||||
|
||||
@ -492,3 +497,4 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
|
||||
.. _#1020: https://github.com/httpie/httpie/issues/1020
|
||||
.. _#1026: https://github.com/httpie/httpie/issues/1026
|
||||
.. _#1029: https://github.com/httpie/httpie/issues/1029
|
||||
.. _#1032: https://github.com/httpie/httpie/issues/1032
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright © 2012-2020 Jakub Roztocil <jakub@roztocil.co>
|
||||
Copyright © 2012-2021 Jakub Roztocil <jakub@roztocil.co>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
@ -12,6 +12,13 @@ import hashlib
|
||||
import requests
|
||||
|
||||
|
||||
VERSIONS = {
|
||||
# By default, we use the latest packages. But sometimes Requests has a maximum supported versions.
|
||||
# Take a look here before making a release: <https://github.com/psf/requests/blob/master/setup.py>
|
||||
'idna': '2.10',
|
||||
}
|
||||
|
||||
|
||||
PACKAGES = [
|
||||
'httpie',
|
||||
'Pygments',
|
||||
@ -26,10 +33,17 @@ PACKAGES = [
|
||||
|
||||
|
||||
def get_package_meta(package_name):
|
||||
api_url = f'https://pypi.python.org/pypi/{package_name}/json'
|
||||
api_url = f'https://pypi.org/pypi/{package_name}/json'
|
||||
resp = requests.get(api_url).json()
|
||||
hasher = hashlib.sha256()
|
||||
for release in resp['urls']:
|
||||
version = VERSIONS.get(package_name)
|
||||
if package_name not in VERSIONS:
|
||||
# Latest version
|
||||
release_bundle = resp['urls']
|
||||
else:
|
||||
release_bundle = resp['releases'][version]
|
||||
|
||||
for release in release_bundle:
|
||||
download_url = release['url']
|
||||
if download_url.endswith('.tar.gz'):
|
||||
hasher.update(requests.get(download_url).content)
|
||||
|
@ -8,26 +8,31 @@ class Httpie < Formula
|
||||
include Language::Python::Virtualenv
|
||||
|
||||
desc "User-friendly cURL replacement (command-line HTTP client)"
|
||||
homepage "https://httpie.org/"
|
||||
url "https://files.pythonhosted.org/packages/b4/d4/712645808103f2d15c281b9eacd184c88754ef7e9a322d9a30ba343fd341/httpie-2.3.0.tar.gz"
|
||||
sha256 "d540571991d07329d217c31bf1ff95fd217957da2aa2def09bcfa0c0fca0cf96"
|
||||
homepage "https://httpie.io/"
|
||||
url "https://files.pythonhosted.org/packages/17/3a/90fb6702e600f5ba7d38d147bbc0b0a1e47159e3e244737319c98c140420/httpie-2.4.0.tar.gz"
|
||||
sha256 "4d1bf5779cf6c9007351cfcaa20bd19947267dc026af09246db6006a8927d8c6"
|
||||
license "BSD-3-Clause"
|
||||
head "https://github.com/httpie/httpie.git"
|
||||
|
||||
livecheck do
|
||||
url :stable
|
||||
bottle do
|
||||
rebuild 1
|
||||
sha256 cellar: :any_skip_relocation, arm64_big_sur: "a01ce8767f6ea88eb8e7894347ba64eb29294053a8ee91eed44dfaf0ab5e7ea2"
|
||||
sha256 cellar: :any_skip_relocation, big_sur: "bdffeff349595ed3c528ed791d568e308b0877246b49e05e867143ba3415a70f"
|
||||
sha256 cellar: :any_skip_relocation, catalina: "ba0627d70f0ee49c64677f5554881ebd56371f47d45196b6564680089ce69152"
|
||||
sha256 cellar: :any_skip_relocation, mojave: "0b87901e88bdcf53c55c5138677087b4621c5aaf1fca67b53b730d5a2fd5a40a"
|
||||
sha256 cellar: :any_skip_relocation, high_sierra: "87e7348b6fb40fd8e4f7597937952469601962189e62d321b8cb4fa421e035ef"
|
||||
end
|
||||
|
||||
depends_on "python@3.9"
|
||||
|
||||
resource "Pygments" do
|
||||
url "https://files.pythonhosted.org/packages/5d/0e/ff13c055b014d634ed17e9e9345a312c28ec6a06448ba6d6ccfa77c3b5e8/Pygments-2.7.2.tar.gz"
|
||||
sha256 "381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0"
|
||||
url "https://files.pythonhosted.org/packages/e1/86/8059180e8217299079d8719c6e23d674aadaba0b1939e25e0cc15dcf075b/Pygments-2.7.4.tar.gz"
|
||||
sha256 "df49d09b498e83c1a73128295860250b0b7edd4c723a32e9bc0d295c7c2ec337"
|
||||
end
|
||||
|
||||
resource "requests" do
|
||||
url "https://files.pythonhosted.org/packages/da/67/672b422d9daf07365259958912ba533a0ecab839d4084c487a5fe9a5405f/requests-2.24.0.tar.gz"
|
||||
sha256 "b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"
|
||||
url "https://files.pythonhosted.org/packages/6b/47/c14abc08432ab22dc18b9892252efaf005ab44066de871e72a38d6af464b/requests-2.25.1.tar.gz"
|
||||
sha256 "27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"
|
||||
end
|
||||
|
||||
resource "requests-toolbelt" do
|
||||
@ -36,13 +41,13 @@ class Httpie < Formula
|
||||
end
|
||||
|
||||
resource "certifi" do
|
||||
url "https://files.pythonhosted.org/packages/40/a7/ded59fa294b85ca206082306bba75469a38ea1c7d44ea7e1d64f5443d67a/certifi-2020.6.20.tar.gz"
|
||||
sha256 "5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"
|
||||
url "https://files.pythonhosted.org/packages/06/a9/cd1fd8ee13f73a4d4f491ee219deeeae20afefa914dfb4c130cfc9dc397a/certifi-2020.12.5.tar.gz"
|
||||
sha256 "1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"
|
||||
end
|
||||
|
||||
resource "urllib3" do
|
||||
url "https://files.pythonhosted.org/packages/76/d9/bbbafc76b18da706451fa91bc2ebe21c0daf8868ef3c30b869ac7cb7f01d/urllib3-1.25.11.tar.gz"
|
||||
sha256 "8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2"
|
||||
url "https://files.pythonhosted.org/packages/d7/8d/7ee68c6b48e1ec8d41198f694ecdc15f7596356f2ff8e6b1420300cf5db3/urllib3-1.26.3.tar.gz"
|
||||
sha256 "de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"
|
||||
end
|
||||
|
||||
resource "idna" do
|
||||
@ -51,8 +56,8 @@ class Httpie < Formula
|
||||
end
|
||||
|
||||
resource "chardet" do
|
||||
url "https://files.pythonhosted.org/packages/fc/bb/a5768c230f9ddb03acc9ef3f0d4a3cf93462473795d18e9535498c8f929d/chardet-3.0.4.tar.gz"
|
||||
sha256 "84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
|
||||
url "https://files.pythonhosted.org/packages/ee/2d/9cdc2b527e127b4c9db64b86647d567985940ac3698eeabc7ffaccb4ea61/chardet-4.0.0.tar.gz"
|
||||
sha256 "0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"
|
||||
end
|
||||
|
||||
resource "PySocks" do
|
||||
@ -65,7 +70,7 @@ class Httpie < Formula
|
||||
end
|
||||
|
||||
test do
|
||||
raw_url = "https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Formula/httpie.rb"
|
||||
raw_url = "https://raw.githubusercontent.com/Homebrew/homebrew-core/HEAD/Formula/httpie.rb"
|
||||
assert_match "PYTHONPATH", shell_output("#{bin}/http --ignore-stdin #{raw_url}")
|
||||
end
|
||||
end
|
||||
|
@ -3,6 +3,6 @@ HTTPie: command-line HTTP client for the API era.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '2.4.0'
|
||||
__version__ = '2.5.0-dev'
|
||||
__author__ = 'Jakub Roztocil'
|
||||
__licence__ = 'BSD'
|
||||
|
@ -671,6 +671,16 @@ network.add_argument(
|
||||
|
||||
"""
|
||||
)
|
||||
network.add_argument(
|
||||
# <https://github.com/httpie/httpie/issues/805>
|
||||
'--send-term-headers',
|
||||
'-T',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="""
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
#######################################################################
|
||||
# SSL
|
||||
|
@ -34,9 +34,10 @@ def collect_messages(
|
||||
args: argparse.Namespace,
|
||||
config_dir: Path,
|
||||
request_body_read_callback: Callable[[bytes], None] = None,
|
||||
extra_headers: dict = None,
|
||||
) -> Iterable[Union[requests.PreparedRequest, requests.Response]]:
|
||||
httpie_session = None
|
||||
httpie_session_headers = None
|
||||
base_headers = {}
|
||||
if args.session or args.session_read_only:
|
||||
httpie_session = get_httpie_session(
|
||||
config_dir=config_dir,
|
||||
@ -44,11 +45,11 @@ def collect_messages(
|
||||
host=args.headers.get('Host'),
|
||||
url=args.url,
|
||||
)
|
||||
httpie_session_headers = httpie_session.headers
|
||||
|
||||
base_headers = httpie_session.headers
|
||||
base_headers.update(extra_headers)
|
||||
request_kwargs = make_request_kwargs(
|
||||
args=args,
|
||||
base_headers=httpie_session_headers,
|
||||
base_headers=base_headers,
|
||||
request_body_read_callback=request_body_read_callback
|
||||
)
|
||||
send_kwargs = make_send_kwargs(args)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
from pprint import pprint
|
||||
from typing import IO, Optional
|
||||
|
||||
|
||||
@ -37,6 +38,13 @@ class Environment:
|
||||
stderr_isatty: bool = stderr.isatty()
|
||||
colors = 256
|
||||
program_name: str = 'http'
|
||||
|
||||
# <https://github.com/httpie/httpie/issues/805>
|
||||
env_lang = os.environ.get('LANG', '').split('_')[0]
|
||||
env_term = os.environ.get('TERM', '')
|
||||
env_columns = os.environ.get('COLUMNS', '')
|
||||
env_lines = os.environ.get('LINES', '')
|
||||
|
||||
if not is_windows:
|
||||
if curses:
|
||||
try:
|
||||
@ -126,3 +134,14 @@ class Environment:
|
||||
def log_error(self, msg, level='error'):
|
||||
assert level in ['error', 'warning']
|
||||
self._orig_stderr.write(f'\n{self.program_name}: {level}: {msg}\n\n')
|
||||
|
||||
|
||||
def get_term_info_headers(env:Environment):
|
||||
# <https://github.com/httpie/httpie/issues/805>
|
||||
return {
|
||||
'Accept-Language': env.env_lang,
|
||||
'X-Terminal': env.env_term,
|
||||
'X-Terminal-Attached': 'yes' if env.stdin.isatty() else 'no',
|
||||
'X-Terminal-Columns': env.env_columns,
|
||||
'X-Terminal-Lines': env.env_lines,
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ from requests import __version__ as requests_version
|
||||
from httpie import __version__ as httpie_version
|
||||
from httpie.cli.constants import OUT_REQ_BODY, OUT_REQ_HEAD, OUT_RESP_BODY, OUT_RESP_HEAD
|
||||
from httpie.client import collect_messages
|
||||
from httpie.context import Environment
|
||||
from httpie.context import Environment, get_term_info_headers
|
||||
from httpie.downloads import Downloader
|
||||
from httpie.output.writer import write_message, write_stream, MESSAGE_SEPARATOR_BYTES
|
||||
from httpie.plugins.registry import plugin_manager
|
||||
@ -160,8 +160,12 @@ def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
|
||||
args.follow = True # --download implies --follow.
|
||||
downloader = Downloader(output_file=args.output_file, progress_file=env.stderr, resume=args.download_resume)
|
||||
downloader.pre_request(args.headers)
|
||||
messages = collect_messages(args=args, config_dir=env.config.directory,
|
||||
request_body_read_callback=request_body_read_callback)
|
||||
messages = collect_messages(
|
||||
args=args,
|
||||
config_dir=env.config.directory,
|
||||
extra_headers=get_term_info_headers(env) if args.send_term_headers else None,
|
||||
request_body_read_callback=request_body_read_callback,
|
||||
)
|
||||
force_separator = False
|
||||
prev_with_body = False
|
||||
|
||||
|
@ -81,7 +81,7 @@ def parse_content_range(content_range: str, resumed_from: int) -> int:
|
||||
# last-byte-pos value, is invalid. The recipient of an invalid
|
||||
# byte-content-range- spec MUST ignore it and any content
|
||||
# transferred along with it."
|
||||
if (first_byte_pos >= last_byte_pos
|
||||
if (first_byte_pos > last_byte_pos
|
||||
or (instance_length is not None
|
||||
and instance_length <= last_byte_pos)):
|
||||
raise ContentRangeError(
|
||||
|
@ -1,3 +1,7 @@
|
||||
# Please keep all characters in this file in ASCII
|
||||
# distutils uses system's locale to interpret it and not everybody
|
||||
# uses UTF-8. See https://github.com/httpie/httpie/issues/1039
|
||||
# for an example
|
||||
[wheel]
|
||||
|
||||
|
||||
@ -13,7 +17,7 @@ addopts = --tb=native --doctest-modules
|
||||
exclude = .git,.idea,__pycache__,build,dist,.pytest_cache,*.egg-info
|
||||
|
||||
# <http://pycodestyle.pycqa.org/en/latest/intro.html#error-codes>
|
||||
# E241 - multiple spaces after ‘,’
|
||||
# E241 - multiple spaces after ','
|
||||
# E501 - line too long
|
||||
# W503 - line break before binary operator
|
||||
ignore = E241,E501,W503
|
||||
|
1
setup.py
1
setup.py
@ -42,6 +42,7 @@ install_requires = [
|
||||
'requests[socks]>=2.22.0',
|
||||
'Pygments>=2.5.2',
|
||||
'requests-toolbelt>=0.9.1',
|
||||
'setuptools',
|
||||
]
|
||||
install_requires_win_only = [
|
||||
'colorama>=0.2.4',
|
||||
|
@ -30,6 +30,9 @@ class TestDownloadUtils:
|
||||
assert parse('bytes 100-199/200', 100) == 200
|
||||
assert parse('bytes 100-199/*', 100) == 200
|
||||
|
||||
# single byte
|
||||
assert parse('bytes 100-100/*', 100) == 101
|
||||
|
||||
# missing
|
||||
pytest.raises(ContentRangeError, parse, None, 100)
|
||||
|
||||
@ -45,9 +48,6 @@ class TestDownloadUtils:
|
||||
# invalid byte-range-resp-spec
|
||||
pytest.raises(ContentRangeError, parse, 'bytes 100-99/199', 100)
|
||||
|
||||
# invalid byte-range-resp-spec
|
||||
pytest.raises(ContentRangeError, parse, 'bytes 100-100/*', 100)
|
||||
|
||||
@pytest.mark.parametrize('header, expected_filename', [
|
||||
('attachment; filename=hello-WORLD_123.txt', 'hello-WORLD_123.txt'),
|
||||
('attachment; filename=".hello-WORLD_123.txt"', 'hello-WORLD_123.txt'),
|
||||
|
@ -79,7 +79,7 @@ def test_terminal_request_headers_response_headers(httpbin):
|
||||
|
||||
|
||||
def test_raw_request_headers_response_headers(httpbin):
|
||||
r = http('--print=Hh', httpbin + '/get')
|
||||
r = http('--print=Hh', httpbin + '/get', env=MockEnvironment(stdout_isatty=False))
|
||||
assert_output_matches(r, [Expect.REQUEST_HEADERS, Expect.RESPONSE_HEADERS])
|
||||
|
||||
|
||||
@ -97,10 +97,7 @@ def test_raw_headers_and_body():
|
||||
|
||||
|
||||
def test_raw_body():
|
||||
r = http(
|
||||
'--print=B', '--offline', 'pie.dev', 'AAA=BBB',
|
||||
env=MockEnvironment(stdout_isatty=False),
|
||||
)
|
||||
r = http('--print=B', '--offline', 'pie.dev', 'AAA=BBB', env=MockEnvironment(stdout_isatty=False))
|
||||
assert_output_matches(r, RAW_BODY)
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user