Compare commits

...

202 Commits

Author SHA1 Message Date
279e387d86 WIP 2021-10-08 10:45:49 +02:00
50f57f8c82 Add help output for --chunked (#1174) 2021-10-07 17:37:06 +02:00
555afef486 Update README.md 2021-10-07 16:21:36 +02:00
476eb4f0d9 Use HTTPie repository everywhere 2021-10-07 16:15:52 +02:00
3869c3ce99 Remove unused import 2021-10-07 14:41:03 +02:00
17f74f10f3 Add summary to Chocolatey metadata
It is strongly recommended to add a summary.
It will be effective for the next release though.
2021-10-07 14:34:33 +02:00
1e094d0a79 Fix Snapcraft and Spack anchors 2021-10-07 14:06:06 +02:00
bd227c0364 Specify the API key to submit Chocolatey packages 2021-10-07 13:58:02 +02:00
9dda23a322 Add Chocolatey packaging information (#1172)
* Add Chocolatey packaging information

* Fix working directory

* Fix Python dependency

* Update icon URL

* Fix local installation

* Simplify links

* Remove the workflow, it adds no real value and th etime to fix is is not worth
2021-10-07 13:53:11 +02:00
ef4fa20ceb Tweak 2021-10-06 19:31:43 +02:00
7e0bed4e54 Add more types and docs for plugins API II. 2021-10-06 19:28:21 +02:00
e1627803fe Add more types and docs for plugins API 2021-10-06 19:24:10 +02:00
f954c9e2b7 Update CHANGELOG.md 2021-10-06 17:35:07 +02:00
80e83f0463 Ignore more venv folders and VS Code folder 2021-10-06 17:29:03 +02:00
4f1c9441c5 Fix encoding error with non-prettified encoded responses (#1168)
* Fix encoding error with non-prettified encoded responses

Removed `--format-option response.as` an promote `--response-as`: using
the format option would be misleading as it is now also used by non-prettified
responses.

* Encoding refactoring

* split --response-as into --response-mime and --response-charset
* add support for Content-Type charset for requests printed to terminal
* add support charset detection for requests printed to terminal without a Content-Type charset
* etc.

* `test_unicode.py` → `test_encoding.py`

* Drop sequence length check

* Clean-up tests

* [skip ci] Tweaks

* Use the compatible release clause for `charset_normalizer` requirement

Cf. https://www.python.org/dev/peps/pep-0440/#version-specifiers

* Clean-up

* Partially revert d52a4833e4

* Changelog

* Tweak tests

* [skip ci] Better test name

* Cleanup tests and add request body charset detection

* More test suite cleanups

* Cleanup

* Fix code style in test

* Improve detect_encoding() docstring

* Uniformize pytest.mark.parametrize() calls

* [skip ci] Comment out TODOs (will be tackled in a specific PR)

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-10-06 17:27:07 +02:00
7989e438d2 Add documentation about our release process (#1159)
* Add documentation about our release process

* Fixes

* Add company-related tasks, enable back WIP pages

* Fix WIP links

* Add AOSC OS

* Add WIP for AOSC OS

* Tweak

* Remove maintainers email IDs

* Use GH nicknames

* Remove useless WIP for brew

* Tweaks
2021-10-06 16:45:44 +02:00
93114072c8 Fix looked path for workflow testing packages 2021-10-06 11:21:54 +02:00
08751d3672 Add install/update instructions database (#1160)
* Add install/update instructions database

* Update the database

* Revert README changes

They will be overwritten later.

* Revert

* Tweak

* Tweaks

* Upgrade database

* Complete commands

Still not sure about Spack upgrades.

* Sort

* Doc generation script draft

* Remove OS names from tool names

* Fix Linuxbrew name

* `wheel` already installs `setuptools`

* Gen docs

* Update

* Tweak

* Add a GitHub workflow to check for outdated installation instructions

* Fix return value

* Test

* Delete test

* Rename the script

* Add `make doc-install-inst`

* Add missing dev requirement

* The first tool is the primary we want to display

Then they are simply sorted by `tool.title`.

* Sort OSes by name

* Refactoring, jinja template, etc.

* Add tool title uniqueness `assert`, fix platform list extra `\n`

* Rebuild docs

* Update generate.py

* Update README.md

* Update methods.yml

* Update distros derived, more assertions

* Tweaks

* Add workflow to auto-update the docs

* Do not hide the command

* Tweaks

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-10-06 11:18:27 +02:00
0c9d701618 Add make install-reqs to install packages without creating env 2021-10-05 21:37:48 +02:00
a3fa016428 Cover on Python 3.10 2021-10-05 21:30:28 +02:00
9c52449344 Add self to paths; same paths for PR and push 2021-10-05 21:28:39 +02:00
e4e4927567 Test on Python 3.10 2021-10-05 21:25:10 +02:00
031b4b89e3 Fix docs formatting 2021-10-05 15:46:10 +02:00
e1c08a3de5 Mention Snapcraft for unstable version installation 2021-10-05 15:45:34 +02:00
033798adc1 Update README.md 2021-10-03 03:20:23 +02:00
6a4e985f71 Remove redundant/inconsistent article 2021-10-03 03:08:05 +02:00
a6c70334cf Expand HTTP method docs
* mention `POST` without a body
* mention `GET` with a body
* mention custom method names
* include examples for default `GET`/`POST`
2021-10-03 03:05:37 +02:00
7388401134 Update setup.py 2021-10-02 16:50:39 +02:00
4ef31ecf71 Update utils.py 2021-10-02 16:43:29 +02:00
2423f893e5 Update config.json 2021-09-30 14:39:32 +02:00
b6a694afbc master/latest docs differ since --response-as 2021-09-30 14:39:18 +02:00
71adcd97d0 Improve handling of prettified responses without correct content-type encoding (#1110)
* Improve handling of responses without correct content-type charset

* [skip ci] Minor tweaks in tests

* [skip ci] Add documentation

Co-authored-by: claudiatd <claudiatd@gmail.com>

* Improve unknown encoding test

[skip ci]

* Review mime and options retrieval

* Add full content-type example in help output

* Simplify decoder

* [skip ci] s/charset/encoding/

* Tweaks

* [skip ci] Fix type annotation

* [skip ci] s/charset/encoding/

* Tweaks

* Fix type annoation

* Improvement

* Introduce `codec.encode()`

* [skip ci] Tweak changelog

Co-authored-by: claudiatd <claudiatd@gmail.com>
2021-09-29 20:22:19 +02:00
b50f9aa7e7 Use PYthon 3 documentation
[skip ci]
2021-09-28 12:54:16 +02:00
fe96b2af20 Use httpie.io/docs everywhere
[skip ci]
2021-09-28 12:53:53 +02:00
727b8a2c05 Sort available style choices (#1166) 2021-09-27 16:55:10 +02:00
9c89c703ae Allow to overwrite the response Content-Type from options (#1134)
* Allow to override the response `Content-Type` from options

* Apply suggestions from code review

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Rename the option from `--response.content-type` to `--response-as`

* Update CHANGELOG.md

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-09-27 13:58:19 +02:00
8f8851f1db Remove trailing comma in test 2021-09-24 10:37:59 +02:00
bce2b3a98e Sort changelog 2021-09-23 17:17:29 +02:00
474093acdf Include plugin info in --debug output (#1165)
* Include plugin info in `--debug` output

* Adapt issue number

* Fix docs
2021-09-23 17:15:14 +02:00
1535d0c976 Mention XML when explaining formatting 2021-09-23 12:27:03 +02:00
cae83b3f9e Add FreeBSD installation instructions
Closes #761.
2021-09-23 10:46:06 +02:00
507514b795 Add workflow to test with pyOpenSSL active (#1164)
* Add workflow to test with pyOpenSSL active

Original patch by @gmelodie.

* Fix tests on Windows with Python 3.6
2021-09-23 10:37:23 +02:00
d7ed45bbcd Fix duplicate keys preservation of JSON data (#1163)
* Fix duplicate keys preservation of JSON data

* Update issue number

* Fix type annotations

* Changes after review

* Rewording
2021-09-21 19:07:59 +02:00
e6c5cd3e4b Improve JSON output when there is leading data before the actual JSON body (#1130)
In some special cases, to prevent against Cross Site Script Inclusion (XSSI)
attacks, the JSON response body starts with a magic prefix line that must be
stripped before feeding the rest of the response body to the JSON parser.
Such prefix is now simply ignored from the parser but still printed in the
terminal.

* Fix Windows tests
2021-09-21 11:15:43 +02:00
273134123a Bump the version to 2.6.0.dev0 (#1162)
[skip ci]
2021-09-21 10:40:09 +02:00
529aa78ee1 Expand the pytest configuration (#1161)
And rely on it to run tests.
2021-09-20 17:36:03 +02:00
e2ba214ac0 [snap] Improve OS integration (#1157)
Get back read-write access to `$HOME/.config/httpie` and `$HOME/.httpie`.
2021-09-15 16:50:44 +02:00
9dd0203bae Use HTTPie for the documentation build request (#1150)
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-09-15 14:25:46 +02:00
ba6fd0bc14 Add a blog post link 2021-09-14 01:01:46 +02:00
8f7f4a6ef4 Remove some horizontal lines in the bug report
And add myself to assignees.
2021-09-13 12:36:01 +02:00
9984447f18 Reverse results in bug report temlpate
Ir seems weird to ask for the expected result before knowing the current one.
2021-09-13 12:33:32 +02:00
10081b9fcc Update README.md 2021-09-11 17:17:15 +02:00
4f84362d73 Update config.json 2021-09-10 23:58:33 +02:00
2b5f8f48bf Update update-documentation.yml 2021-09-10 20:06:29 +02:00
a51068a44d Update update-documentation.yml 2021-09-10 20:05:23 +02:00
f06d870012 Update and rename documentations.yml to check-markdown.yml 2021-09-10 20:04:52 +02:00
0115a4a466 Create config.json 2021-09-10 18:50:45 +02:00
7c1d26a8fa Update README.md 2021-09-10 11:17:23 +02:00
7734e47280 Update README.md 2021-09-10 11:17:10 +02:00
30c595b770 [snap] Comment out the problematic interface
It seems it just needs to be present for the snap to be rejected.
2021-09-10 11:04:57 +02:00
b38352858f [snap] Remove personal-files interface
Use of the `personal-files` interface is reserved for vetted publishers.

The interface requires a validation, but we need to publish at least
one package first. So let's skip that part, release a version and ask
for the interface access in a second time.

Also add a workflow to build & test the snap package.
2021-09-10 10:30:44 +02:00
a45b94fda6 Complete CentOS installation instructions 2021-09-09 16:38:36 +02:00
513e5080e4 Add the release workflow
It has to be triggered manually for now.
2021-09-09 16:13:13 +02:00
7c9f415107 Add a workflow to check documentations (#1151)
* Add a workflow to check documentations

* Fix markdown issues

* Install Ruby 2.7

* Finally, handle and fix GitHub templates

* Minor improvement in the feature request template

* Verbose mode to be sure all files are checked
2021-09-09 15:52:24 +02:00
4c8633c6e5 Split the monolithic workflow into specific ones (#1149)
* Split the monolithic workflow into specific ones

* Rename workflows, improve commands

* Update pip from the venv

* Fix Windows setup

* Lowercase macos-latest

* Fix Windows run, again
2021-09-08 16:41:55 +02:00
4d7d6b66cf Trigger official documentation build when documentation is updated here 2021-09-08 15:43:34 +02:00
a586fca246 Update brew formula to 2.5.0 (#1144)
* Update brew formula to 2.5.0

* Can use `idna` 3.2

* Sort requirements to ease reproductible builds

And also to have the same output as `brew bump-formula-pr`.

* Sync `bottles` with official Formula

And keep the `high_sierra` one.

* Add a workflow to check the Formula
2021-09-08 11:01:27 +02:00
978258ec5b Add Alpine Linux installation instructions 2021-09-08 10:04:49 +02:00
84ef9f588c Use lzo compression for snap (#1146) 2021-09-07 16:57:05 +02:00
cf21790411 Add the Snap build file for general Linux packaging
Based on the work of @elopio and @chipaca.

- Added support for the `snapd` protocol URL.
- Packaged Unix socket transport plugin.
2021-09-07 16:45:57 +02:00
1ef127c61d Packit: Get the current Fedora Rawhide specfile
Using the fork is not needed anymore,
since Rawhide was updated to 2.5.0 and no longer has patches.
2021-09-07 11:03:04 +02:00
4eaa4d67c5 v2.5.0 (#1140)
[skip ci]
2021-09-06 20:23:14 +02:00
9764cc74a4 Cleanup 2021-09-06 20:23:00 +02:00
778360cde1 Cleanup 2021-09-06 20:21:49 +02:00
60a7ed4e7b Cleanup 2021-09-06 20:21:09 +02:00
185af7c9f1 Cleanup 2021-09-06 20:20:30 +02:00
7e9e7c783f Readme tweaks (#1141) 2021-09-06 20:17:21 +02:00
6039bd8582 Switch from reStructuredText to Markdown and add docs/ (#1139)
* Convert most of the documentation from the frontend `README.rst` to `docs/REAME.md`

Also converted all reStructuredText files to Markdown.

* Tell `mdformat` to use LF for end on lines

* `--check` is not needed in the help message

* Skip tests on GitHub Windows.

Those tests pass on a real Windows machine.
Let's revisit those failure later, if needed.

* Move `mdoformat` requirement from `test` to `dev` extra

To fix Fedora CI.
2021-09-06 17:36:13 +02:00
e7d8b9cece Spelling and bash completion fixes (#1137)
* Remove hashbang from bash completion

Completion files are not supposed to have a hashbang.
They are sourced, not executed.

* Fix spelling

* Trim excess whitespace
2021-09-03 15:05:03 +02:00
a62391e789 Tiny clean-up in program() (#1135) 2021-09-02 16:47:01 +02:00
41666d897f Update CHANGELOG.rst 2021-09-02 10:37:14 +02:00
71008bbedb Move example URL in a global variable for XML tests 2021-09-01 16:56:23 +02:00
85110643e7 Move example URL in a global variable for tests 2021-09-01 16:52:10 +02:00
fdd486415a Fix XML formatter tests 2021-09-01 10:28:03 +02:00
6c501d23c3 Change default XML indent to 2 spaces 2021-08-31 22:52:16 +02:00
d10e108b5f Added support for XML formatting (#1129)
As a side effect, XHTML responses will be pretty-printed too.
2021-08-31 22:49:53 +02:00
8618f12fce Tweak format options docs 2021-08-24 17:18:45 +02:00
dac0d716c1 Add the formatting options section in the docs (#1131)
It will ease future changes and should improve reading/finding information.
2021-08-24 17:11:40 +02:00
0340f8caf5 Fix missing links in the changelog
[skip ci]
2021-08-17 11:21:04 +02:00
d7caeaf372 Fix handling of session files with Cookie: followed by other headers (#1127)
* Fix the handling of cookies from session files

* Apply suggestions from code review

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Fix test docstring formatting

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-08-16 14:50:46 +02:00
54c8612452 Remove unused code in BasicConfig (#1123) 2021-08-06 18:04:08 +02:00
4ff22defe4 Rework __main__.py to follow best practices (#1124)
It also simplifies how the `main()` function could be tested.
2021-08-06 16:57:19 +02:00
c50e287c57 CI: Run tests on Python 3.10 RC1 (#1121) 2021-08-06 13:11:21 +02:00
6bd6648545 Simplify get_content_type() (#1125)
We were using the potential `encoding` returned by `mimetypes.guess_type()`
to expand the `Content-Type` header.
According to the RFC-7231 [1] the `Content-Type` should contain a charset
and nothing more. But as stated in the `mimetypes.guess_type()` doc [2],
the `encoding` would be the name of the program used to encode (e.g. compress
or gzip) the payload. The `encoding` is suitable for use as a `Content-Encoding`
header. See [3] for potential `encoding`s, none is a IANA registered one [4], and
so a valid charset to be used by the `Content-Type` header.

[1] https://httpwg.org/specs/rfc7231.html#header.content-type
[2] https://docs.python.org/3/library/mimetypes.html#guess_type
[3] 938e84b4fa/Lib/mimetypes.py (L416-L422)
[4] https://www.iana.org/assignments/character-sets/character-sets.xhtml
2021-08-06 12:35:38 +02:00
6633b5ae9b Use UTF8 constant in FORM_CONTENT_TYPE as well 2021-08-05 21:00:17 +02:00
c6cbc7dfa5 Uniformize UTF-8 naming (#1115)
* Uniformize UTF-8 naming

Replace `utf8` -> `utf-8` everywhere.
It should have no impact, `utf8` is an alias of `utf-8` [1].

[1] ee03bad25e/Lib/encodings/aliases.py (L534)

* Always specify the encoding

Let's be explicit over implicit. And prevent future warnings from PEP-597 [1].

[1] https://www.python.org/dev/peps/pep-0597/#using-the-default-encoding-is-a-common-mistake

* Update `UTF8` constant (`utf-8` -> `utf_8`)

* Remove default argument from `str.encode()` and `bytes.decode()`

* Clean-up
2021-08-05 20:58:43 +02:00
11399dde76 Refine abstract methods and properties (#1118) 2021-08-05 20:57:23 +02:00
da47e37c44 Use builtin open() in setup.py (#1120) 2021-08-05 20:56:59 +02:00
a66af2497a Add converter plugin streaming tests (#1117)
Also fixed minor glitches here and there and re-enabled a unicode test.
2021-08-05 14:37:08 +02:00
a94d6d807c Packit: Enable the Koji repsitory in Copr (#1119)
By default, only updates that are propagated trough the Fedora's update system
will be available in the community Copr build system.
On stable Fedora releases,
updates (including new packages) might be delayed 1+ week.

This adds the latest Koji (that's the name of the official Fedora build system) repo.
That repo contains more recent packages available during the official Fedora builds.

The Koji repo is not mirrored,
so the Copr builds are more likely to encounter a network issue,
but I think it is worth it.
The `/packit build` command may be used in the pull request if this happens.
2021-08-04 20:30:41 +02:00
de13423839 --download: Use time.monotonic() and rework code to prevent ZeroDivisionError specific handling (#1113) 2021-07-29 16:05:56 +02:00
04d05a8abd Minor clean-up (#1112)
* Remove Python 2 clean-up misses

* Remove unused `Environment.devnull` setter

* Simplifies `get_filename_max_length()`
2021-07-26 23:56:38 +02:00
2f8d7f77bd Add more download tests (#1114) 2021-07-26 20:27:36 +02:00
aee77a23af Simplify spinner_pos calculation a little (#1111) 2021-07-20 18:24:49 +02:00
64c31d554a Revert "Use http in the 'hello world' example to be consitent (#1109)"
This reverts commit 41c251ec7c.
2021-07-16 15:49:41 +02:00
41c251ec7c Use http in the 'hello world' example to be consitent (#1109) 2021-07-15 16:17:05 +02:00
147a066dbe Add internal support for file-like object responses to improve adapter plugin support (#1094)
* Support `requests.response.raw` being a file-like object

Previously HTTPie relied on `requests.models.Response.raw` being
`urllib3.HTTPResponse`. The `requests` documentation specifies that
(requests.models.Response.raw)[https://docs.python-requests.org/en/master/api/#requests.Response.raw]
is a file-like object but allows for other types for internal use.

This change introduces graceful handling for scenarios when
`requests.models.Response.raw` is not `urllib3.HTTPResponse`. In such a scenario
HTTPie now falls back to extracting metadata from `requests.models.Response`
directly instead of direct access from protected protected members such as
`response.raw._original_response`. A side effect in this fallback procedure is
that we can no longer determine HTTP protocol version and report it as `1.1`.

This change is necessary to make it possible to implement `TransportPlugins`
without having to also needing to emulate internal behavior of `urlib3` and
`http.client`.

* Load cookies from `response.headers` instead of `response.raw._original_response.msg._headers`

`response.cookies` was not utilized as it not possible to construct original
payload from `http.cookiejar.Cookie`. Data is stored in lossy format. For example
`Cookie.secure` defaults to `False` so we cannot distinguish if `Cookie.secure` was
set to `False` or was not set at all. Same problem applies to other fields also.

* Simpler HTTP envelope data extraction

* Test cookie extraction and make cookie presentment backwards compatible

Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-07-06 21:00:06 +02:00
b7300c1096 Update Chocolatey command in the docs 2021-07-02 17:54:07 +02:00
5d4e7a9a18 Use echo -n in the docs (#1102)
I argue that you most likely don't want/need to send the trailing newline.
2021-07-02 10:31:38 +02:00
5717fb1ad5 Normalize the version (#1101)
To fix that warning:

    setuptools/dist.py:473: UserWarning: Normalizing '2.5.0-dev' to '2.5.0.dev0'
2021-07-01 10:34:51 +02:00
9c38da96b0 Remove snap installation method until package name fixed 2021-06-28 13:46:02 +02:00
e5bda98ee7 Mention snap install http in the docs (#1097) 2021-06-28 12:28:21 +02:00
c8d70e8c0b Simplify return statements in client.py (#1096)
Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
2021-06-28 09:05:24 +02:00
ae6f57dc76 Skip tests that randomly fail on Windows in CI 2021-06-26 14:03:31 +02:00
b4c94e0f26 Mention choco install httpie in the docs 2021-06-26 13:12:05 +02:00
7ceb313ccf Add --follow test for HTTP 308 2021-06-15 17:31:56 +02:00
3228e74df5 Add --follow --verbose test for HTTP 308 2021-06-15 17:24:26 +02:00
dc4309771e Mention 308 Permanent Redirect 2021-06-15 14:59:24 +02:00
07a0359316 Final touches for #1088 (#1091)
* Make sure there’s no trailing \n in test files for easier output inspection

* Refactor output matching test utils

* More robust `test_http_307_allow_redirect_post_verbose()`

* Changelog

* Mention HTTP 307 Temporary Redirect re-post behaviour in README
2021-06-15 14:48:44 +02:00
2d55c01c7e Fix printing redirected prepared request in verbose mode (#1088) 2021-06-15 13:39:46 +02:00
1470ca0c77 CI: Do not fail fast to have a real view of potential failures (#1090) 2021-06-11 20:55:51 +02:00
9857693ebf Use a more modern approach to run tests (#1089)
Running tests through `python setup.py test` is deprecated:

> WARNING: Testing via this command is deprecated and will be removed
> in a future version. Users looking for a generic test entry point
> independent of test runner are encouraged to use tox.

I am not in favor of moving back to `tox`, we should simply run tests
using `python -m pytest` (or `make test`) and that's it.

A new extra was added, `dev`, to install development requirements:

    $ python -m pip install --upgrade --editable '.[dev]'
2021-06-11 20:55:26 +02:00
da03a0656e Add a Packit configuration for Fedora packaging (#1086)
* Add Packit configuration for Fedora packaging

 - all pull requests are build-tested in https://copr.fedorainfracloud.org
 - new releases will create pull requests in https://src.fedoraproject.org/rpms/httpie

Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
2021-06-09 17:18:27 +02:00
61f1ffd0eb Prevent installation of test files (#1087)
(They’re still included in the package as per #182)
2021-06-09 17:14:27 +02:00
9792513c68 Add a reproduction test case for #1082 (#1085)
The fix may actually be slightly more complex than I expected.
We would need, at first sight, to loose the prepared requests + responses streaming.

A potential solution will come in a near future.
2021-06-09 09:43:06 +02:00
350f973f70 Switch from pycodestyle to flake8 for code style checks (#1083) 2021-06-02 11:06:46 +02:00
8d35a12d27 Fix several issues found with flake8 (#1081) 2021-06-01 14:46:58 +02:00
8374a9ed83 Review OSError exceptions handling (#1080)
- Replace obsolete `IOError` (Python 2) with `OSError`,
  cf https://docs.python.org/3/library/exceptions.html#OSError.
- Improve `OSError` catches at different places, simplifying
  the code.
2021-05-31 10:10:41 +02:00
a61f9e1114 Minor clean-up (#1078)
- Remove default arguments to `open()`.
- Make use of `pytest` mechanisms for temporary folders.
2021-05-29 12:06:06 +02:00
611b278b63 Fix --style colors list help indentation (#1077) 2021-05-28 12:45:40 +02:00
175e36da6b Remove Python 3.10 build
Not supported by GitHub actions yet.
2021-05-27 20:19:55 +02:00
19e1e26d97 Add Python 3.10 build 2021-05-27 20:17:14 +02:00
9b5aedb02d updated fish shell completions (#1076) 2021-05-27 20:13:00 +02:00
3865fabf09 Adapt doctest of tests.utils.http to work on Python 3.10 as well (#1075)
https://docs.python.org/3.10/whatsnew/3.10.html#enum

Python 3.10 changed the repr of enum members, and the doctest of tests.utils.http failed.
Exact reprs are unfortunately not considered stable API between Python releases:

    =================================== FAILURES ===================================
    __________________________ [doctest] tests.utils.http __________________________
    209
    210     Example:
    211
    212     $ http --auth=user:password GET pie.dev/basic-auth/user/password
    213
    214         >>> httpbin = getfixture('httpbin')
    215         >>> r = http('-a', 'user:pw', httpbin.url + '/basic-auth/user/pw')
    216         >>> type(r) == StrCLIResponse
    217         True
    218         >>> r.exit_status
    Expected:
        <ExitStatus.SUCCESS: 0>
    Got:
        ExitStatus.SUCCESS

A simple replacement of the expected output however breaks the doctest on Python 3.9.

This is the best solution I could think of
that keeps the docstring readable and doctest working in Pythons both old and new.
2021-05-27 19:54:33 +02:00
355befcbfc Skip http://pie.dev tests when offline (#1072) 2021-05-27 19:30:36 +02:00
fc7a349d36 Declare a [test] extra with test dependencies (#1074)
Since `python setup.py test` is deprecated and `tests_require` is only used by that,
this allows to programmatically read the tests dependencies from the metadata.
2021-05-27 19:21:34 +02:00
06ef27c576 Remove an useless shebang form non-executable file (#1073)
Shebangs have no function in non-executable files.
This file does not need to be directly executed.
2021-05-27 19:17:04 +02:00
0e556ec3a8 pytest: Add hidden files to norecursedirs (#1071)
The default value already contains this,
but when setting a custom one, it was overridden.

In Fedora, we build the package in `.pyproject-builddir` and not ignoring it confuses pytest:

    _pytest.pathlib.ImportPathMismatchError: ('httpie.__main__', '/builddir/build/BUILD/httpie-2.4.0/.pyproject-builddir/pip-req-build-aedma65c/build/lib/httpie/__main__.py', PosixPath('/builddir/build/BUILD/httpie-2.4.0/.pyproject-builddir/pip-req-build-aedma65c/httpie/__main__.py'))
2021-05-27 16:59:57 +02:00
464b5b4c1d Polish Python 2 removal (#1070) 2021-05-27 13:05:41 +02:00
264d45cdf5 Modernize the code base with f-strings in tests (#1069)
Simple concatenations were kept for readability purpose.
2021-05-26 14:09:38 +02:00
0ff0874fa3 Modernize the code base with f-strings (#1068) 2021-05-25 20:49:07 +02:00
39314887c4 README 2021-05-24 15:00:01 +02:00
f9a488d47e README 2021-05-24 14:40:08 +02:00
0001297f41 Add --raw to allow specifying the raw request body as an alternative to stdin (#1062)
* Add --raw to allow specifying the raw request body without extra processing

As an alternative to `stdin`.

Co-authored-by: Elena Lape <elapinskaite@gmail.com>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Update README.rst

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Update README.rst

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Fix default HTTP method on empty data

Co-authored-by: Elena Lape <elapinskaite@gmail.com>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-05-24 14:29:54 +02:00
e2d43c14ce Prefer usage of "python -m pip" instead of "pip" (#1059)
* Prefer usage of "python -m pip" instead of "pip"

It will prevent issues when users think that they are using
the correct `pip` version. It can refers to the one from the OS
Python installation, or even worse to a Python 2 installation.
Let's be clear on how to install stuff.

Also used short version of `pip` arguments, because we are all lazy :)

* Apply suggestions from code review
2021-05-05 14:17:04 +02:00
a3a08a9a22 Use relative imports (#1057)
* Use relative imports in test

* Use relative imports

* Add myself to contributors :)
2021-05-05 14:13:39 +02:00
7cbdf2c608 Prefer usage of pytest rather than py.test (#1058)
`py.test` was chosen over `pytest` but it is not planned for removal yet [1].
Anyway, it is a good thing to ensure we are using the correct Python version
with the right `pytest` installed, so using `python -m pytest` is recommended.

[1] https://github.com/pytest-dev/pytest/issues/1629
2021-05-03 18:40:25 +02:00
1274d869f6 Replace usage of mock with unittest.mock (#1054)
Since Python 3, the mock dependency is no more required as
it is already part of the unittest module.
2021-04-30 15:08:27 +02:00
611bcdaab1 Fail gracefully if multiple request data files are supplied (#1042) 2021-04-15 09:35:50 +02:00
fc45bf0fe3 Explicitly require setuptools, httpie/plugins/manager.py imports pkg_resources (#1049) 2021-03-30 22:54:53 +02:00
56c4ba1794 Warn against non-ascii in setup.cfg (#1041) 2021-02-24 14:56:57 +01:00
8f83bfe767 Replace typography quotes (#1040)
fixes #1039
2021-02-24 14:38:18 +01:00
a32ad344dd Update README.rst 2021-02-23 12:51:06 +01:00
c53fbe5ae3 Typo 2021-02-23 12:22:35 +01:00
070ba9fa5a Tweaks 2021-02-18 13:48:48 +01:00
82ee071362 Tweaks 2021-02-18 13:47:58 +01:00
97dffb35a2 Spacing 2021-02-18 13:46:10 +01:00
18af03ac18 Issue templates tweaks II 2021-02-18 13:44:29 +01:00
904dd4107a Issue templates tweaks 2021-02-18 13:42:59 +01:00
8efabc86e6 Issue templates (#1031)
* add bug report template

* add feature request template

* add other template

* a httpie to an httpie

Co-authored-by: bl-ue <54780737+bl-ue@users.noreply.github.com>

* Update .github/ISSUE_TEMPLATE/bug_report.md

Co-authored-by: bl-ue <54780737+bl-ue@users.noreply.github.com>

* Update .github/ISSUE_TEMPLATE/bug_report.md

Co-authored-by: bl-ue <54780737+bl-ue@users.noreply.github.com>

* Update .github/ISSUE_TEMPLATE/bug_report.md

Co-authored-by: bl-ue <54780737+bl-ue@users.noreply.github.com>

* minor changes

* add discord

Co-authored-by: bl-ue <54780737+bl-ue@users.noreply.github.com>
2021-02-18 12:55:15 +01:00
cc20488f49 Formatting 2021-02-14 13:34:20 +01:00
b918972862 CHANGELOG #1032 2021-02-14 13:33:38 +01:00
84c7327057 Correctly handle single-byte Content-Range (#1032)
HTTPie previously failed if it continued a download with a single byte left.
2021-02-14 13:30:58 +01:00
e944dbd7fa 2.5.0-dev 2021-02-06 13:34:04 +01:00
157f3a1840 2021 2021-02-06 13:29:02 +01:00
61dbadb730 Tests 2021-02-06 13:21:21 +01:00
7be25d0751 Update brew formula to 2.4.0 2021-02-06 11:54:15 +01:00
5d5a8b4091 Typo 2021-02-06 11:26:15 +01:00
bb36897054 2.4.0 2021-02-06 11:17:24 +01:00
173e622567 Update upload command 2021-02-06 11:17:14 +01:00
3426030370 Fix README formatting 2021-02-06 11:13:04 +01:00
d014498713 Changelog entry for cookie expiration based on Set-Cookie: max-age=<n>
#1029
2021-02-06 11:02:26 +01:00
5414d1853e Refactoring
#1029
2021-02-06 10:58:36 +01:00
1ac8f69651 Add more output matching tests 2021-02-06 10:52:30 +01:00
3c07a25326 Add support for max-age=0 cookie expiry (#1029)
Close #998
2021-02-06 10:50:34 +01:00
cf78a12e46 Show --check-status warning with --quiet as well. (#1026)
Fixes #1028
2021-01-31 00:58:56 +01:00
0f1e098cc4 Fix incorrect separators and introduce assert_output_matches() (close #1027) 2021-01-30 22:14:57 +01:00
0401d7b31c fixed typo (#1024) 2021-01-21 22:35:41 +01:00
795627f965 Update chat icon 2021-01-13 22:24:20 +01:00
21cc008cb2 Add Linux Solus install to README (#1018) 2021-01-13 21:52:00 +01:00
77b8c37cb0 Update changelog
#1020
2021-01-13 21:49:53 +01:00
db685d58b5 Decode headers using utf-8 only if they are not str (#1020) 2021-01-13 21:45:56 +01:00
44ae67685d Add HTTPie Discord link to README (#1016)
* add discord link

* update link
2021-01-12 15:27:45 +01:00
6922a0c912 Switch from httpbin.org to pie.dev 2020-12-24 21:34:30 +01:00
2afdc958c6 Update URLs 2020-12-23 22:07:27 +01:00
57b1baf1d1 Add a test to reproduce #1006 2020-12-22 22:56:45 +01:00
1828da6a50 Update --stream example comment 2020-12-21 12:17:04 +01:00
0629f2ff42 Fix --stream example II 2020-12-21 12:14:41 +01:00
d71b7eee81 Fix --stream example
Close #1002
2020-12-21 12:12:11 +01:00
9883a46575 Cleanup (#993) 2020-12-21 12:03:25 +01:00
2409077a6d Clarify 2020-12-21 11:51:19 +01:00
02971b938d Fix documentation on file upload (#1000)
As documented later on in "File upload forms", the correct syntax to set
the mimetype of the upload is `field@file;type=filetype`
2020-12-21 11:47:47 +01:00
f7e77efe4b Test on Python 3.9 (#986) 2020-12-21 11:42:21 +01:00
5d8bd0da7c python -m pip (#1005) 2020-12-21 11:38:00 +01:00
3c6e7c73fe Update setup.py 2020-12-19 14:07:31 +01:00
d64c0ee415 Remove funding request 2020-12-18 17:54:13 +01:00
311a5ede70 Simplify Hello World 2020-10-29 10:07:45 +01:00
f64c90010f Simplify Hello World 2020-10-29 10:06:26 +01:00
8456ddb27c Update brew instructions for dev 2020-10-25 21:48:09 +01:00
cf254680b7 Update homebrew 2020-10-25 21:43:20 +01:00
42c4a7596b 2.4.0-dev 2020-10-25 21:36:24 +01:00
1573058811 v2.3.0 2020-10-25 21:12:38 +01:00
189 changed files with 11467 additions and 4187 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: jakubroztocil # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom:

44
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,44 @@
---
name: Bug report
about: Report a possible bug in HTTPie
title: ''
labels: "new, bug"
assignees: 'BoboTiG'
---
## Checklist
- [ ] I've searched for similar issues.
- [ ] I'm using the latest version of HTTPie.
---
## Minimal reproduction code and steps
1.
2.
3.
## Current result
## Expected result
---
## Debug output
Please re-run the command with `--debug`, then copy the entire command & output and paste both below:
```bash
$ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
<COMPLETE OUTPUT>
```
## Additional information, screenshots, or code examples

View File

@ -0,0 +1,30 @@
---
name: Feature request
about: Suggest an enhancement for HTTPie
title: ''
labels: "new, enhancement"
assignees: ''
---
## Checklist
- [ ] I've searched for similar feature requests.
---
## Enhancement request
---
## Problem it solves
E.g. “I'm always frustrated when […]”, “Im trying to do […] so that […]”.
---
## Additional information, screenshots, or code examples

10
.github/ISSUE_TEMPLATE/other.md vendored Normal file
View 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

9
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,9 @@
version: 2
updates:
# GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
assignees:
- BoboTiG

View File

@ -1,37 +0,0 @@
name: Build
on: [push, pull_request]
jobs:
extras:
# Run coverage and extra tests only once
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: 3.8
- run: python -m pip install --upgrade pip setuptools wheel
- run: make install
- run: make pycodestyle
- run: make test-cover
- run: make codecov-upload
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_REPO_TOKEN }}
- run: make test-dist
test:
# Run core HTTPie tests everywhere
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
python-version: [3.6, 3.7, 3.8]
exclude:
- os: windows-latest
python-version: 3.8
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install --upgrade pip setuptools wheel
- run: python -m pip install --upgrade --editable .
- run: python setup.py test

19
.github/workflows/code-style.yml vendored Normal file
View File

@ -0,0 +1,19 @@
on:
pull_request:
paths:
- .github/workflows/code-style.yml
- extras/*.py
- httpie/**/*.py
- setup.py
- tests/**/*.py
jobs:
code-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- run: make venv
- run: make codestyle

22
.github/workflows/coverage.yml vendored Normal file
View File

@ -0,0 +1,22 @@
on:
pull_request:
paths:
- .github/workflows/coverage.yml
- httpie/**/*.py
- setup.*
- tests/**/*.py
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "3.10"
- run: make install
- run: make test-cover
- run: make codecov-upload
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_REPO_TOKEN }}
- run: make test-dist

View File

@ -0,0 +1,19 @@
on:
pull_request:
paths:
- "*.md"
- "**/*.md"
jobs:
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
- name: Install the linter
run: sudo gem install mdl
- name: Check files
run: make doc-check

20
.github/workflows/docs-deploy.yml vendored Normal file
View File

@ -0,0 +1,20 @@
on:
push:
branches:
- master
paths:
- docs/README.md
- docs/config.json
release:
types:
- published
- unpublished
- deleted
jobs:
trigger-doc-build:
runs-on: ubuntu-latest
steps:
- name: Install HTTPie
run: sudo snap install --edge httpie
- name: Trigger new documentation build
run: http --ignore-stdin POST ${{ secrets.DOCS_UPDATE_VERCEL_HOOK }}

View File

@ -0,0 +1,26 @@
on:
push:
branches:
- master
paths:
- docs/installation/*
# Allow to call the workflow manually
workflow_dispatch:
jobs:
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- run: make install
- run: make doc-update-install
- uses: Automattic/action-commit-to-branch@master
with:
branch: master
commit_message: Auto-update installation instructions in the docs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

26
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,26 @@
on:
# Add a "Trigger" button to manually start the workflow.
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
# It could be fully automated by uncommenting following lines.
# Let's see later if we are confident enough to try it :)
# release:
# types:
# - published
jobs:
new-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- run: make publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}

View File

@ -0,0 +1,23 @@
on:
pull_request:
paths:
- .github/workflows/test-package-linux-snap.yml
- snapcraft.yaml
jobs:
snap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build
uses: snapcore/action-build@v1
id: snapcraft
- name: Install
run: sudo snap install --dangerous ${{ steps.snapcraft.outputs.snap }}
- name: Test
run: |
httpie.http --version
httpie.https --version
# Auto-aliases cannot be tested when installing a snap outside the store.
# http --version
# https --version

View File

@ -0,0 +1,17 @@
on:
pull_request:
paths:
- .github/workflows/test-package-mac-brew.yml
- docs/packaging/brew/httpie.rb
jobs:
brew:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Setup brew
run: |
brew developer on
brew update
- name: Build and test the formula
run: make brew-test

45
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,45 @@
on:
push:
branches:
- master
paths:
- .github/workflows/tests.yml
- httpie/**/*.py
- setup.*
- tests/**/*.py
pull_request:
paths:
- .github/workflows/tests.yml
- httpie/**/*.py
- setup.*
- tests/**/*.py
jobs:
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
pyopenssl: [0, 1]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Windows setup
if: matrix.os == 'windows-latest'
run: |
python -m pip install --upgrade pip wheel
python -m pip install --upgrade '.[dev]'
python -m pytest --verbose ./httpie ./tests
env:
HTTPIE_TEST_WITH_PYOPENSSL: ${{ matrix.pyopenssl }}
- name: Linux & Mac setup
if: matrix.os != 'windows-latest'
run: |
make install
make test
env:
HTTPIE_TEST_WITH_PYOPENSSL: ${{ matrix.pyopenssl }}

12
.gitignore vendored
View File

@ -118,6 +118,7 @@ celerybeat.pid
.venv
env/
venv/
venv*/
ENV/
env.bak/
venv.bak/
@ -139,3 +140,14 @@ dmypy.json
# Pyre type checker
.pyre/
# Packit
/httpie.spec
/httpie-*.rpm
/httpie-*.tar.gz
# VS Code
.vscode/
# Windows Chocolatey
*.nupkg

19
.packit.yaml Normal file
View File

@ -0,0 +1,19 @@
# See the documentation for more information:
# https://packit.dev/docs/configuration/
specfile_path: httpie.spec
actions:
# get the current Fedora Rawhide specfile:
post-upstream-clone: "wget https://src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -O httpie.spec"
jobs:
- job: copr_build
trigger: pull_request
metadata:
targets:
- fedora-all
additional_repos:
- "https://kojipkgs.fedoraproject.org/repos/f$releasever-build/latest/$basearch/"
- job: propose_downstream
trigger: release
metadata:
dist_git_branches:
- rawhide

41
AUTHORS.md Normal file
View File

@ -0,0 +1,41 @@
# HTTPie authors
- [Jakub Roztocil](https://github.com/jakubroztocil)
## Patches, features, ideas
[Complete list of contributors on GitHub](https://github.com/httpie/httpie/graphs/contributors)
- [Cláudia T. Delgado](https://github.com/claudiatd)
- [Hank Gay](https://github.com/gthank)
- [Jake Basile](https://github.com/jakebasile)
- [Vladimir Berkutov](https://github.com/dair-targ)
- [Jakob Kramer](https://github.com/gandaro)
- [Chris Faulkner](https://github.com/faulkner)
- [Alen Mujezinovic](https://github.com/flashingpumpkin)
- [Praful Mathur](https://github.com/tictactix)
- [Marc Abramowitz](https://github.com/msabramo)
- [Ismail Badawi](https://github.com/isbadawi)
- [Laurent Bachelier](https://github.com/laurentb)
- [Isman Firmansyah](https://github.com/iromli)
- [Simon Olofsson](https://github.com/simono)
- [Churkin Oleg](https://github.com/Bahus)
- [Jökull Sólberg Auðunsson](https://github.com/jokull)
- [Matthew M. Boedicker](https://github.com/mmb)
- [marblar](https://github.com/marblar)
- [Tomek Wójcik](https://github.com/tomekwojcik)
- [Davey Shafik](https://github.com/dshafik)
- [cido](https://github.com/cido)
- [Justin Bonnar](https://github.com/jargonjustin)
- [Nathan LaFreniere](https://github.com/nlf)
- [Matthias Lehmann](https://github.com/matleh)
- [Dennis Brakhane](https://github.com/brakhane)
- [Matt Layman](https://github.com/mblayman)
- [Edward Yang](https://github.com/honorabrutroll)
- [Aleksandr Vinokurov](https://github.com/aleksandr-vin)
- [Jeff Byrnes](https://github.com/jeffbyrnes)
- [Denis Belavin](https://github.com/LuckyDenis)
- [Mickaël Schoentgen](https://github.com/BoboTiG)
- [Elena Lape](https://github.com/elenalape)
- [Rohit Sehgal](https://github.com/r0hi7)
- [Bartłomiej Jacak](https://github.com/bartekjacak)

View File

@ -1,42 +0,0 @@
==============
HTTPie authors
==============
* `Jakub Roztocil <https://github.com/jakubroztocil>`_
Patches and ideas
-----------------
`Complete list of contributors on GitHub <https://github.com/jakubroztocil/httpie/graphs/contributors>`_
* `Cláudia T. Delgado <https://github.com/claudiatd>`_ (logo)
* `Hank Gay <https://github.com/gthank>`_
* `Jake Basile <https://github.com/jakebasile>`_
* `Vladimir Berkutov <https://github.com/dair-targ>`_
* `Jakob Kramer <https://github.com/gandaro>`_
* `Chris Faulkner <https://github.com/faulkner>`_
* `Alen Mujezinovic <https://github.com/flashingpumpkin>`_
* `Praful Mathur <https://github.com/tictactix>`_
* `Marc Abramowitz <https://github.com/msabramo>`_
* `Ismail Badawi <https://github.com/isbadawi>`_
* `Laurent Bachelier <https://github.com/laurentb>`_
* `Isman Firmansyah <https://github.com/iromli>`_
* `Simon Olofsson <https://github.com/simono>`_
* `Churkin Oleg <https://github.com/Bahus>`_
* `Jökull Sólberg Auðunsson <https://github.com/jokull>`_
* `Matthew M. Boedicker <https://github.com/mmb>`_
* `marblar <https://github.com/marblar>`_
* `Tomek Wójcik <https://github.com/tomekwojcik>`_
* `Davey Shafik <https://github.com/dshafik>`_
* `cido <https://github.com/cido>`_
* `Justin Bonnar <https://github.com/jargonjustin>`_
* `Nathan LaFreniere <https://github.com/nlf>`_
* `Matthias Lehmann <https://github.com/matleh>`_
* `Dennis Brakhane <https://github.com/brakhane>`_
* `Matt Layman <https://github.com/mblayman>`_
* `Edward Yang <https://github.com/honorabrutroll>`_
* `Aleksandr Vinokurov <https://github.com/aleksandr-vin>`_
* `Jeff Byrnes <https://github.com/jeffbyrnes>`_

378
CHANGELOG.md Normal file
View File

@ -0,0 +1,378 @@
# Change Log
This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/).
## [2.6.0.dev0](https://github.com/httpie/httpie/compare/2.5.0...master) (unreleased)
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/httpie/issues/1130))
- Added `--response-charset` to allow overriding the response encoding for terminal display purposes. ([#1168](https://github.com/httpie/httpie/issues/1168))
- Added `--response-mime` to allow overriding the response mime type for coloring and formatting for the terminal. ([#1168](https://github.com/httpie/httpie/issues/1168))
- Improved handling of responses with incorrect `Content-Type`. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
- Installed plugins are now listed in `--debug` output. ([#1165](https://github.com/httpie/httpie/issues/1165))
- Fixed duplicate keys preservation of JSON data. ([#1163](https://github.com/httpie/httpie/issues/1163))
## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06)
Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Added `--raw` to allow specifying the raw request body without extra processing as
an alternative to `stdin`. ([#534](https://github.com/httpie/httpie/issues/534))
- Added support for XML formatting. ([#1129](https://github.com/httpie/httpie/issues/1129))
- Added internal support for file-like object responses to improve adapter plugin support. ([#1094](https://github.com/httpie/httpie/issues/1094))
- Fixed `--continue --download` with a single byte to be downloaded left. ([#1032](https://github.com/httpie/httpie/issues/1032))
- Fixed `--verbose` HTTP 307 redirects with streamed request body. ([#1088](https://github.com/httpie/httpie/issues/1088))
- Fixed handling of session files with `Cookie:` followed by other headers. ([#1126](https://github.com/httpie/httpie/issues/1126))
## [2.4.0](https://github.com/httpie/httpie/compare/2.3.0...2.4.0) (2021-02-06)
- Added support for `--session` cookie expiration based on `Set-Cookie: max-age=<n>`. ([#1029](https://github.com/httpie/httpie/issues/1029))
- Show a `--check-status` warning with `--quiet` as well, not only when the output is redirected. ([#1026](https://github.com/httpie/httpie/issues/1026))
- Fixed upload with `--session` ([#1020](https://github.com/httpie/httpie/issues/1020)).
- Fixed a missing blank line between request and response ([#1006](https://github.com/httpie/httpie/issues/1006)).
## [2.3.0](https://github.com/httpie/httpie/compare/2.2.0...2.3.0) (2020-10-25)
- Added support for streamed uploads ([#201](https://github.com/httpie/httpie/issues/201)).
- Added support for multipart upload streaming ([#684](https://github.com/httpie/httpie/issues/684)).
- Added support for body-from-file upload streaming (`http pie.dev/post @file`).
- Added `--chunked` to enable chunked transfer encoding ([#753](https://github.com/httpie/httpie/issues/753)).
- Added `--multipart` to allow `multipart/form-data` encoding for non-file `--form` requests as well.
- Added support for preserving field order in multipart requests ([#903](https://github.com/httpie/httpie/issues/903)).
- Added `--boundary` to allow a custom boundary string for `multipart/form-data` requests.
- Added support for combining cookies specified on the CLI and in a session file ([#932](https://github.com/httpie/httpie/issues/932)).
- Added out of the box SOCKS support with no extra installation ([#904](https://github.com/httpie/httpie/issues/904)).
- Added `--quiet, -q` flag to enforce silent behaviour.
- Fixed the handling of invalid `expires` dates in `Set-Cookie` headers ([#963](https://github.com/httpie/httpie/issues/963)).
- Removed Tox testing entirely ([#943](https://github.com/httpie/httpie/issues/943)).
## [2.2.0](https://github.com/httpie/httpie/compare/2.1.0...2.2.0) (2020-06-18)
- Added support for custom content types for uploaded files ([#668](https://github.com/httpie/httpie/issues/668)).
- Added support for `$XDG_CONFIG_HOME` ([#920](https://github.com/httpie/httpie/issues/920)).
- Added support for `Set-Cookie`-triggered cookie expiration ([#853](https://github.com/httpie/httpie/issues/853)).
- Added `--format-options` to allow disabling sorting, etc. ([#128](https://github.com/httpie/httpie/issues/128))
- Added `--sorted` and `--unsorted` shortcuts for (un)setting all sorting-related `--format-options`. ([#128](https://github.com/httpie/httpie/issues/128))
- Added `--ciphers` to allow configuring OpenSSL ciphers ([#870](https://github.com/httpie/httpie/issues/870)).
- Added `netrc` support for auth plugins. Enabled for `--auth-type=basic`
and `digest`, 3rd parties may opt in ([#718](https://github.com/httpie/httpie/issues/718), [#719](https://github.com/httpie/httpie/issues/719), [#852](https://github.com/httpie/httpie/issues/852), [#934](https://github.com/httpie/httpie/issues/934)).
- Fixed built-in plugins-related circular imports ([#925](https://github.com/httpie/httpie/issues/925)).
## [2.1.0](https://github.com/httpie/httpie/compare/2.0.0...2.1.0) (2020-04-18)
- Added `--path-as-is` to bypass dot segment (`/../` or `/./`)
URL squashing ([#895](https://github.com/httpie/httpie/issues/895)).
- Changed the default `Accept` header value for JSON requests from
`application/json, */*` to `application/json, */*;q=0.5`
to clearly indicate preference ([#488](https://github.com/httpie/httpie/issues/488)).
- Fixed `--form` file upload mixed with redirected `stdin` error handling
([#840](https://github.com/httpie/httpie/issues/840)).
## [2.0.0](https://github.com/httpie/httpie/compare/1.0.3...2.0.0) (2020-01-12)
- Removed Python 2.7 support ([EOL Jan 2020](https://www.python.org/doc/sunset-python-2/).
- Added `--offline` to allow building an HTTP request and printing it but not
actually sending it over the network.
- Replaced the old collect-all-then-process handling of HTTP communication
with one-by-one processing of each HTTP request or response as they become
available. This means that you can see headers immediately,
see what is being sent even if the request fails, etc.
- Removed automatic config file creation to avoid concurrency issues.
- Removed the default 30-second connection `--timeout` limit.
- Removed Pythons default limit of 100 response headers.
- Added `--max-headers` to allow setting the max header limit.
- Added `--compress` to allow request body compression.
- Added `--ignore-netrc` to allow bypassing credentials from `.netrc`.
- Added `https` alias command with `https://` as the default scheme.
- Added `$ALL_PROXY` documentation.
- Added type annotations throughout the codebase.
- Added `tests/` to the PyPi package for the convenience of
downstream package maintainers.
- Fixed an error when `stdin` was a closed fd.
- Improved `--debug` output formatting.
## [1.0.3](https://github.com/httpie/httpie/compare/1.0.2...1.0.3) (2019-08-26)
- Fixed CVE-2019-10751 — the way the output filename is generated for
`--download` requests without `--output` resulting in a redirect has
been changed to only consider the initial URL as the base for the generated
filename, and not the final one. This fixes a potential security issue under
the following scenario:
1. A `--download` request with no explicit `--output` is made (e.g.,
`$ http -d example.org/file.txt`), instructing httpie to
[generate the output filename](https://httpie.org/doc#downloaded-filename)
from the `Content-Disposition` response header, or from the URL if the header
is not provided.
2. The server handling the request has been modified by an attacker and
instead of the expected response the URL returns a redirect to another
URL, e.g., `attacker.example.org/.bash_profile`, whose response does
not provide a `Content-Disposition` header (i.e., the base for the
generated filename becomes `.bash_profile` instead of `file.txt`).
3. Your current directory doesnt already contain `.bash_profile`
(i.e., no unique suffix is added to the generated filename).
4. You dont notice the potentially unexpected output filename
as reported by httpie in the console output
(e.g., `Downloading 100.00 B to ".bash_profile"`).
Reported by Raul Onitza and Giulio Comi.
## [1.0.2](https://github.com/httpie/httpie/compare/1.0.1...1.0.2) (2018-11-14)
- Fixed tests for installation with pyOpenSSL.
## [1.0.1](https://github.com/httpie/httpie/compare/1.0.0...1.0.1) (2018-11-14)
- Removed external URL calls from tests.
## [1.0.0](https://github.com/httpie/httpie/compare/0.9.9...1.0.0) (2018-11-02)
- Added `--style=auto` which follows the terminal ANSI color styles.
- Added support for selecting TLS 1.3 via `--ssl=tls1.3`
(available once implemented in upstream libraries).
- Added `true`/`false` as valid values for `--verify`
(in addition to `yes`/`no`) and the boolean value is case-insensitive.
- Changed the default `--style` from `solarized` to `auto` (on Windows it stays `fruity`).
- Fixed default headers being incorrectly case-sensitive.
- Removed Python 2.6 support.
## [0.9.9](https://github.com/httpie/httpie/compare/0.9.8...0.9.9) (2016-12-08)
- Fixed README.
## [0.9.8](https://github.com/httpie/httpie/compare/0.9.6...0.9.8) (2016-12-08)
- Extended auth plugin API.
- Added exit status code `7` for plugin errors.
- Added support for `curses`-less Python installations.
- Fixed `REQUEST_ITEM` arg incorrectly being reported as required.
- Improved `CTRL-C` interrupt handling.
- Added the standard exit status code `130` for keyboard interrupts.
## [0.9.6](https://github.com/httpie/httpie/compare/0.9.4...0.9.6) (2016-08-13)
- 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;`.
- Added `--default-scheme <URL_SCHEME>` to enable things like
`$ alias https='http --default-scheme=https`.
- Added `-I` as a shortcut for `--ignore-stdin`.
- Added fish shell completion (located in `extras/httpie-completion.fish`
in the GitHub repo).
- Updated `requests` to 2.10.0 so that SOCKS support can be added via
`pip install requests[socks]`.
- Changed the default JSON `Accept` header from `application/json`
to `application/json, */*`.
- Changed the pre-processing of request HTTP headers so that any leading
and trailing whitespace is removed.
## [0.9.4](https://github.com/httpie/httpie/compare/0.9.3...0.9.4) (2016-07-01)
- Added `Content-Type` of files uploaded in `multipart/form-data` requests
- Added `--ssl=<PROTOCOL>` to specify the desired SSL/TLS protocol version
to use for HTTPS requests.
- Added JSON detection with `--json, -j` to work around incorrect
`Content-Type`
- Added `--all` to show intermediate responses such as redirects (with `--follow`)
- Added `--history-print, -P WHAT` to specify formatting of intermediate responses
- Added `--max-redirects=N` (default 30)
- Added `-A` as short name for `--auth-type`
- Added `-F` as short name for `--follow`
- Removed the `implicit_content_type` config option
(use `"default_options": ["--form"]` instead)
- Redirected `stdout` doesn't trigger an error anymore when `--output FILE`
is set
- Changed the default `--style` back to `solarized` for better support
of light and dark terminals
- Improved `--debug` output
- Fixed `--session` when used with `--download`
- Fixed `--download` to trim too long filenames before saving the file
- Fixed the handling of `Content-Type` with multiple `+subtype` parts
- Removed the XML formatter as the implementation suffered from multiple issues
## [0.9.3](https://github.com/httpie/httpie/compare/0.9.2...0.9.3) (2016-01-01)
- Changed the default color `--style` from `solarized` to `monokai`
- Added basic Bash autocomplete support (need to be installed manually)
- Added request details to connection error messages
- Fixed `'requests.packages.urllib3' has no attribute 'disable_warnings'`
errors that occurred in some installations
- Fixed colors and formatting on Windows
- Fixed `--auth` prompt on Windows
## [0.9.2](https://github.com/httpie/httpie/compare/0.9.1...0.9.2) (2015-02-24)
- Fixed compatibility with Requests 2.5.1
- Changed the default JSON `Content-Type` to `application/json` as UTF-8
is the default JSON encoding
## [0.9.1](https://github.com/httpie/httpie/compare/0.9.0...0.9.1) (2015-02-07)
- Added support for Requests transport adapter plugins
(see [httpie-unixsocket](https://github.com/httpie/httpie-unixsocket)
and [httpie-http2](https://github.com/httpie/httpie-http2))
## [0.9.0](https://github.com/httpie/httpie/compare/0.8.0...0.9.0) (2015-01-31)
- Added `--cert` and `--cert-key` parameters to specify a client side
certificate and private key for SSL
- Improved unicode support
- Improved terminal color depth detection via `curses`
- To make it easier to deal with Windows paths in request items, `\`
now only escapes special characters (the ones that are used as key-value
separators by HTTPie)
- Switched from `unittest` to `pytest`
- Added Python `wheel` support
- Various test suite improvements
- Added `CONTRIBUTING`
- Fixed `User-Agent` overwriting when used within a session
- Fixed handling of empty passwords in URL credentials
- Fixed multiple file uploads with the same form field name
- Fixed `--output=/dev/null` on Linux
- Miscellaneous bugfixes
## [0.8.0](https://github.com/httpie/httpie/compare/0.7.1...0.8.0) (2014-01-25)
- Added `field=@file.txt` and `field:=@file.json` for embedding
the contents of text and JSON files into request data
- Added curl-style shorthand for localhost
- Fixed request `Host` header value output so that it doesn't contain
credentials, if included in the URL
## [0.7.1](https://github.com/httpie/httpie/compare/0.6.0...0.7.1) (2013-09-24)
- Added `--ignore-stdin`
- Added support for auth plugins
- Improved `--help` output
- Improved `Content-Disposition` parsing for `--download` mode
- Update to Requests 2.0.0
## [0.6.0](https://github.com/httpie/httpie/compare/0.5.1...0.6.0) (2013-06-03)
- XML data is now formatted
- `--session` and `--session-read-only` now also accept paths to
session files (eg. `http --session=/tmp/session.json example.org`)
## [0.5.1](https://github.com/httpie/httpie/compare/0.5.0...0.5.1) (2013-05-13)
- `Content-*` and `If-*` request headers are not stored in sessions
anymore as they are request-specific
## [0.5.0](https://github.com/httpie/httpie/compare/0.4.1...0.5.0) (2013-04-27)
- Added a download mode via `--download`
- Fixes miscellaneous bugs
## [0.4.1](https://github.com/httpie/httpie/compare/0.4.0...0.4.1) (2013-02-26)
- Fixed `setup.py`
## [0.4.0](https://github.com/httpie/httpie/compare/0.3.0...0.4.0) (2013-02-22)
- Added Python 3.3 compatibility
- Added Requests >= v1.0.4 compatibility
- Added support for credentials in URL
- Added `--no-option` for every `--option` to be config-friendly
- Mutually exclusive arguments can be specified multiple times. The
last value is used
## [0.3.0](https://github.com/httpie/httpie/compare/0.2.7...0.3.0) (2012-09-21)
- Allow output redirection on Windows
- Added configuration file
- Added persistent session support
- Renamed `--allow-redirects` to `--follow`
- Improved the usability of `http --help`
- Fixed installation on Windows with Python 3
- Fixed colorized output on Windows with Python 3
- CRLF HTTP header field separation in the output
- Added exit status code `2` for timed-out requests
- Added the option to separate colorizing and formatting
(`--pretty=all`, `--pretty=colors` and `--pretty=format`)
`--ugly` has bee removed in favor of `--pretty=none`
## [0.2.7](https://github.com/httpie/httpie/compare/0.2.5...0.2.7) (2012-08-07)
- Added compatibility with Requests 0.13.6
- Added streamed terminal output. `--stream, -S` can be used to enable
streaming also with `--pretty` and to ensure a more frequent output
flushing
- Added support for efficient large file downloads
- Sort headers by name (unless `--pretty=none`)
- Response body is fetched only when needed (e.g., not with `--headers`)
- Improved content type matching
- Updated Solarized color scheme
- Windows: Added `--output FILE` to store output into a file
(piping results in corrupted data on Windows)
- Proper handling of binary requests and responses
- Fixed printing of `multipart/form-data` requests
- Renamed `--traceback` to `--debug`
## [0.2.6](https://github.com/httpie/httpie/compare/0.2.5...0.2.6) (2012-07-26)
- The short option for `--headers` is now `-h` (`-t` has been
removed, for usage use `--help`)
- Form data and URL parameters can have multiple fields with the same name
(e.g.,`http -f url a=1 a=2`)
- Added `--check-status` to exit with an error on HTTP 3xx, 4xx and
5xx (3, 4, and 5, respectively)
- If the output is piped to another program or redirected to a file,
the default behaviour is to only print the response body
(It can still be overwritten via the `--print` flag.)
- Improved highlighting of HTTP headers
- Added query string parameters (`param==value`)
- Added support for terminal colors under Windows
## [0.2.5](https://github.com/httpie/httpie/compare/0.2.2...0.2.5) (2012-07-17)
- Unicode characters in prettified JSON now don't get escaped for
improved readability
- --auth now prompts for a password if only a username provided
- Added support for request payloads from a file path with automatic
`Content-Type` (`http URL @/path`)
- Fixed missing query string when displaying the request headers via
`--verbose`
- Fixed Content-Type for requests with no data
## [0.2.2](https://github.com/httpie/httpie/compare/0.2.1...0.2.2) (2012-06-24)
- The `METHOD` positional argument can now be omitted (defaults to
`GET`, or to `POST` with data)
- Fixed --verbose --form
- Added support for Tox
## [0.2.1](https://github.com/httpie/httpie/compare/0.2.0...0.2.1) (2012-06-13)
- Added compatibility with `requests-0.12.1`
- Dropped custom JSON and HTTP lexers in favor of the ones newly included
in `pygments-1.5`
## [0.2.0](https://github.com/httpie/httpie/compare/0.1.6...0.2.0) (2012-04-25)
- Added Python 3 support
- Added the ability to print the HTTP request as well as the response
(see `--print` and `--verbose`)
- Added support for Digest authentication
- Added file upload support
(`http -f POST file_field_name@/path/to/file`)
- Improved syntax highlighting for JSON
- Added support for field name escaping
- Many bug fixes
## [0.1.6](https://github.com/httpie/httpie/compare/0.1.5...0.1.6) (2012-03-04)
- Fixed `setup.py`
## [0.1.5](https://github.com/httpie/httpie/compare/0.1.4...0.1.5) (2012-03-04)
- Many improvements and bug fixes
## [0.1.4](https://github.com/httpie/httpie/compare/b966efa...0.1.4) (2012-02-28)
- Many improvements and bug fixes
## [0.1.0](https://github.com/httpie/httpie/commit/b966efa) (2012-02-25)
- Initial public release

View File

@ -1,475 +0,0 @@
==========
Change Log
==========
This document records all notable changes to `HTTPie <https://httpie.org>`_.
This project adheres to `Semantic Versioning <https://semver.org/>`_.
`2.3.0-dev`_ (unreleased)
-------------------------
* Added support for multipart upload streaming (`#684`_).
* Added support for body-from-file upload streaming (``http httpbin.org/post @file``).
* Added ``--chunked`` to allow chunked transfer encoding.
* Added ``--multipart`` to allow ``multipart/form-data`` encoding for non-file ``--form`` requests as well.
* Added ``--boundary`` to allow a custom boundary string for ``multipart/form-data`` requests.
* Added support for combining cookies specified on the CLI and in a session file (`#932`_).
* Added out of the box SOCKS support with no extra installation (`#904`_).
* Added ``--quiet, -q`` flag to enforce silent behaviour.
* Fixed the handling of invalid ``expires`` dates in ``Set-Cookie`` headers (`#963`_).
* Removed Tox testing entirely (`#943`_).
`2.2.0`_ (2020-06-18)
-------------------------
* Added support for custom content types for uploaded files (`#668`_).
* Added support for ``$XDG_CONFIG_HOME`` (`#920`_).
* Added support for ``Set-Cookie``-triggered cookie expiration (`#853`_).
* Added ``--format-options`` to allow disabling sorting, etc. (`#128`_)
* Added ``--sorted`` and ``--unsorted`` shortcuts for (un)setting all sorting-related ``--format-options``. (`#128`_)
* Added ``--ciphers`` to allow configuring OpenSSL ciphers (`#870`_).
* Added ``netrc`` support for auth plugins. Enabled for ``--auth-type=basic``
and ``digest``, 3rd parties may opt in (`#718`_, `#719`_, `#852`_, `#934`_).
* Fixed built-in plugins-related circular imports (`#925`_).
`2.1.0`_ (2020-04-18)
---------------------
* Added ``--path-as-is`` to bypass dot segment (``/../`` or ``/./``)
URL squashing (`#895`_).
* Changed the default ``Accept`` header value for JSON requests from
``application/json, */*`` to ``application/json, */*;q=0.5``
to clearly indicate preference (`#488`_).
* Fixed ``--form`` file upload mixed with redirected ``stdin`` error handling
(`#840`_).
`2.0.0`_ (2020-01-12)
-------------------------
* Removed Python 2.7 support (`EOL Jan 2020 <https://www.python.org/doc/sunset-python-2/>`_).
* Added ``--offline`` to allow building an HTTP request and printing it but not
actually sending it over the network.
* Replaced the old collect-all-then-process handling of HTTP communication
with one-by-one processing of each HTTP request or response as they become
available. This means that you can see headers immediately,
see what is being sent even if the request fails, etc.
* Removed automatic config file creation to avoid concurrency issues.
* Removed the default 30-second connection ``--timeout`` limit.
* Removed Pythons default limit of 100 response headers.
* Added ``--max-headers`` to allow setting the max header limit.
* Added ``--compress`` to allow request body compression.
* Added ``--ignore-netrc`` to allow bypassing credentials from ``.netrc``.
* Added ``https`` alias command with ``https://`` as the default scheme.
* Added ``$ALL_PROXY`` documentation.
* Added type annotations throughout the codebase.
* Added ``tests/`` to the PyPi package for the convenience of
downstream package maintainers.
* Fixed an error when ``stdin`` was a closed fd.
* Improved ``--debug`` output formatting.
`1.0.3`_ (2019-08-26)
---------------------
* Fixed CVE-2019-10751 — the way the output filename is generated for
``--download`` requests without ``--output`` resulting in a redirect has
been changed to only consider the initial URL as the base for the generated
filename, and not the final one. This fixes a potential security issue under
the following scenario:
1. A ``--download`` request with no explicit ``--output`` is made (e.g.,
``$ http -d example.org/file.txt``), instructing httpie to
`generate the output filename <https://httpie.org/doc#downloaded-filename>`_
from the ``Content-Disposition`` response header, or from the URL if the header
is not provided.
2. The server handling the request has been modified by an attacker and
instead of the expected response the URL returns a redirect to another
URL, e.g., ``attacker.example.org/.bash_profile``, whose response does
not provide a ``Content-Disposition`` header (i.e., the base for the
generated filename becomes ``.bash_profile`` instead of ``file.txt``).
3. Your current directory doesnt already contain ``.bash_profile``
(i.e., no unique suffix is added to the generated filename).
4. You dont notice the potentially unexpected output filename
as reported by httpie in the console output
(e.g., ``Downloading 100.00 B to ".bash_profile"``).
Reported by Raul Onitza and Giulio Comi.
`1.0.2`_ (2018-11-14)
-------------------------
* Fixed tests for installation with pyOpenSSL.
`1.0.1`_ (2018-11-14)
-------------------------
* Removed external URL calls from tests.
`1.0.0`_ (2018-11-02)
-------------------------
* Added ``--style=auto`` which follows the terminal ANSI color styles.
* Added support for selecting TLS 1.3 via ``--ssl=tls1.3``
(available once implemented in upstream libraries).
* Added ``true``/``false`` as valid values for ``--verify``
(in addition to ``yes``/``no``) and the boolean value is case-insensitive.
* Changed the default ``--style`` from ``solarized`` to ``auto`` (on Windows it stays ``fruity``).
* Fixed default headers being incorrectly case-sensitive.
* Removed Python 2.6 support.
`0.9.9`_ (2016-12-08)
---------------------
* Fixed README.
`0.9.8`_ (2016-12-08)
---------------------
* Extended auth plugin API.
* Added exit status code ``7`` for plugin errors.
* Added support for ``curses``-less Python installations.
* Fixed ``REQUEST_ITEM`` arg incorrectly being reported as required.
* Improved ``CTRL-C`` interrupt handling.
* Added the standard exit status code ``130`` for keyboard interrupts.
`0.9.6`_ (2016-08-13)
---------------------
* 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;``.
* Added ``--default-scheme <URL_SCHEME>`` to enable things like
``$ alias https='http --default-scheme=https``.
* Added ``-I`` as a shortcut for ``--ignore-stdin``.
* Added fish shell completion (located in ``extras/httpie-completion.fish``
in the GitHub repo).
* Updated ``requests`` to 2.10.0 so that SOCKS support can be added via
``pip install requests[socks]``.
* Changed the default JSON ``Accept`` header from ``application/json``
to ``application/json, */*``.
* Changed the pre-processing of request HTTP headers so that any leading
and trailing whitespace is removed.
`0.9.4`_ (2016-07-01)
---------------------
* Added ``Content-Type`` of files uploaded in ``multipart/form-data`` requests
* Added ``--ssl=<PROTOCOL>`` to specify the desired SSL/TLS protocol version
to use for HTTPS requests.
* Added JSON detection with ``--json, -j`` to work around incorrect
``Content-Type``
* Added ``--all`` to show intermediate responses such as redirects (with ``--follow``)
* Added ``--history-print, -P WHAT`` to specify formatting of intermediate responses
* Added ``--max-redirects=N`` (default 30)
* Added ``-A`` as short name for ``--auth-type``
* Added ``-F`` as short name for ``--follow``
* Removed the ``implicit_content_type`` config option
(use ``"default_options": ["--form"]`` instead)
* Redirected ``stdout`` doesn't trigger an error anymore when ``--output FILE``
is set
* Changed the default ``--style`` back to ``solarized`` for better support
of light and dark terminals
* Improved ``--debug`` output
* Fixed ``--session`` when used with ``--download``
* Fixed ``--download`` to trim too long filenames before saving the file
* Fixed the handling of ``Content-Type`` with multiple ``+subtype`` parts
* Removed the XML formatter as the implementation suffered from multiple issues
`0.9.3`_ (2016-01-01)
---------------------
* Changed the default color ``--style`` from ``solarized`` to ``monokai``
* Added basic Bash autocomplete support (need to be installed manually)
* Added request details to connection error messages
* Fixed ``'requests.packages.urllib3' has no attribute 'disable_warnings'``
errors that occurred in some installations
* Fixed colors and formatting on Windows
* Fixed ``--auth`` prompt on Windows
`0.9.2`_ (2015-02-24)
---------------------
* Fixed compatibility with Requests 2.5.1
* Changed the default JSON ``Content-Type`` to ``application/json`` as UTF-8
is the default JSON encoding
`0.9.1`_ (2015-02-07)
---------------------
* Added support for Requests transport adapter plugins
(see `httpie-unixsocket <https://github.com/httpie/httpie-unixsocket>`_
and `httpie-http2 <https://github.com/httpie/httpie-http2>`_)
`0.9.0`_ (2015-01-31)
---------------------
* Added ``--cert`` and ``--cert-key`` parameters to specify a client side
certificate and private key for SSL
* Improved unicode support
* Improved terminal color depth detection via ``curses``
* To make it easier to deal with Windows paths in request items, ``\``
now only escapes special characters (the ones that are used as key-value
separators by HTTPie)
* Switched from ``unittest`` to ``pytest``
* Added Python `wheel` support
* Various test suite improvements
* Added ``CONTRIBUTING``
* Fixed ``User-Agent`` overwriting when used within a session
* Fixed handling of empty passwords in URL credentials
* Fixed multiple file uploads with the same form field name
* Fixed ``--output=/dev/null`` on Linux
* Miscellaneous bugfixes
`0.8.0`_ (2014-01-25)
---------------------
* Added ``field=@file.txt`` and ``field:=@file.json`` for embedding
the contents of text and JSON files into request data
* Added curl-style shorthand for localhost
* Fixed request ``Host`` header value output so that it doesn't contain
credentials, if included in the URL
`0.7.1`_ (2013-09-24)
---------------------
* Added ``--ignore-stdin``
* Added support for auth plugins
* Improved ``--help`` output
* Improved ``Content-Disposition`` parsing for ``--download`` mode
* Update to Requests 2.0.0
`0.6.0`_ (2013-06-03)
---------------------
* XML data is now formatted
* ``--session`` and ``--session-read-only`` now also accept paths to
session files (eg. ``http --session=/tmp/session.json example.org``)
`0.5.1`_ (2013-05-13)
---------------------
* ``Content-*`` and ``If-*`` request headers are not stored in sessions
anymore as they are request-specific
`0.5.0`_ (2013-04-27)
---------------------
* Added a download mode via ``--download``
* Fixes miscellaneous bugs
`0.4.1`_ (2013-02-26)
---------------------
* Fixed ``setup.py``
`0.4.0`_ (2013-02-22)
---------------------
* Added Python 3.3 compatibility
* Added Requests >= v1.0.4 compatibility
* Added support for credentials in URL
* Added ``--no-option`` for every ``--option`` to be config-friendly
* Mutually exclusive arguments can be specified multiple times. The
last value is used
`0.3.0`_ (2012-09-21)
---------------------
* Allow output redirection on Windows
* Added configuration file
* Added persistent session support
* Renamed ``--allow-redirects`` to ``--follow``
* Improved the usability of ``http --help``
* Fixed installation on Windows with Python 3
* Fixed colorized output on Windows with Python 3
* CRLF HTTP header field separation in the output
* Added exit status code ``2`` for timed-out requests
* Added the option to separate colorizing and formatting
(``--pretty=all``, ``--pretty=colors`` and ``--pretty=format``)
``--ugly`` has bee removed in favor of ``--pretty=none``
`0.2.7`_ (2012-08-07)
---------------------
* Added compatibility with Requests 0.13.6
* Added streamed terminal output. ``--stream, -S`` can be used to enable
streaming also with ``--pretty`` and to ensure a more frequent output
flushing
* Added support for efficient large file downloads
* Sort headers by name (unless ``--pretty=none``)
* Response body is fetched only when needed (e.g., not with ``--headers``)
* Improved content type matching
* Updated Solarized color scheme
* Windows: Added ``--output FILE`` to store output into a file
(piping results in corrupted data on Windows)
* Proper handling of binary requests and responses
* Fixed printing of ``multipart/form-data`` requests
* Renamed ``--traceback`` to ``--debug``
`0.2.6`_ (2012-07-26)
---------------------
* The short option for ``--headers`` is now ``-h`` (``-t`` has been
removed, for usage use ``--help``)
* Form data and URL parameters can have multiple fields with the same name
(e.g.,``http -f url a=1 a=2``)
* Added ``--check-status`` to exit with an error on HTTP 3xx, 4xx and
5xx (3, 4, and 5, respectively)
* If the output is piped to another program or redirected to a file,
the default behaviour is to only print the response body
(It can still be overwritten via the ``--print`` flag.)
* Improved highlighting of HTTP headers
* Added query string parameters (``param==value``)
* Added support for terminal colors under Windows
`0.2.5`_ (2012-07-17)
---------------------
* Unicode characters in prettified JSON now don't get escaped for
improved readability
* --auth now prompts for a password if only a username provided
* Added support for request payloads from a file path with automatic
``Content-Type`` (``http URL @/path``)
* Fixed missing query string when displaying the request headers via
``--verbose``
* Fixed Content-Type for requests with no data
`0.2.2`_ (2012-06-24)
---------------------
* The ``METHOD`` positional argument can now be omitted (defaults to
``GET``, or to ``POST`` with data)
* Fixed --verbose --form
* Added support for Tox
`0.2.1`_ (2012-06-13)
---------------------
* Added compatibility with ``requests-0.12.1``
* Dropped custom JSON and HTTP lexers in favor of the ones newly included
in ``pygments-1.5``
`0.2.0`_ (2012-04-25)
---------------------
* Added Python 3 support
* Added the ability to print the HTTP request as well as the response
(see ``--print`` and ``--verbose``)
* Added support for Digest authentication
* Added file upload support
(``http -f POST file_field_name@/path/to/file``)
* Improved syntax highlighting for JSON
* Added support for field name escaping
* Many bug fixes
`0.1.6`_ (2012-03-04)
---------------------
* Fixed ``setup.py``
`0.1.5`_ (2012-03-04)
---------------------
* Many improvements and bug fixes
`0.1.4`_ (2012-02-28)
---------------------
* Many improvements and bug fixes
`0.1.0`_ (2012-02-25)
---------------------
* Initial public release
.. _`0.1.0`: https://github.com/jakubroztocil/httpie/commit/b966efa
.. _0.1.4: https://github.com/jakubroztocil/httpie/compare/b966efa...0.1.4
.. _0.1.5: https://github.com/jakubroztocil/httpie/compare/0.1.4...0.1.5
.. _0.1.6: https://github.com/jakubroztocil/httpie/compare/0.1.5...0.1.6
.. _0.2.0: https://github.com/jakubroztocil/httpie/compare/0.1.6...0.2.0
.. _0.2.1: https://github.com/jakubroztocil/httpie/compare/0.2.0...0.2.1
.. _0.2.2: https://github.com/jakubroztocil/httpie/compare/0.2.1...0.2.2
.. _0.2.5: https://github.com/jakubroztocil/httpie/compare/0.2.2...0.2.5
.. _0.2.6: https://github.com/jakubroztocil/httpie/compare/0.2.5...0.2.6
.. _0.2.7: https://github.com/jakubroztocil/httpie/compare/0.2.5...0.2.7
.. _0.3.0: https://github.com/jakubroztocil/httpie/compare/0.2.7...0.3.0
.. _0.4.0: https://github.com/jakubroztocil/httpie/compare/0.3.0...0.4.0
.. _0.4.1: https://github.com/jakubroztocil/httpie/compare/0.4.0...0.4.1
.. _0.5.0: https://github.com/jakubroztocil/httpie/compare/0.4.1...0.5.0
.. _0.5.1: https://github.com/jakubroztocil/httpie/compare/0.5.0...0.5.1
.. _0.6.0: https://github.com/jakubroztocil/httpie/compare/0.5.1...0.6.0
.. _0.7.1: https://github.com/jakubroztocil/httpie/compare/0.6.0...0.7.1
.. _0.8.0: https://github.com/jakubroztocil/httpie/compare/0.7.1...0.8.0
.. _0.9.0: https://github.com/jakubroztocil/httpie/compare/0.8.0...0.9.0
.. _0.9.1: https://github.com/jakubroztocil/httpie/compare/0.9.0...0.9.1
.. _0.9.2: https://github.com/jakubroztocil/httpie/compare/0.9.1...0.9.2
.. _0.9.3: https://github.com/jakubroztocil/httpie/compare/0.9.2...0.9.3
.. _0.9.4: https://github.com/jakubroztocil/httpie/compare/0.9.3...0.9.4
.. _0.9.6: https://github.com/jakubroztocil/httpie/compare/0.9.4...0.9.6
.. _0.9.8: https://github.com/jakubroztocil/httpie/compare/0.9.6...0.9.8
.. _0.9.9: https://github.com/jakubroztocil/httpie/compare/0.9.8...0.9.9
.. _1.0.0: https://github.com/jakubroztocil/httpie/compare/0.9.9...1.0.0
.. _1.0.1: https://github.com/jakubroztocil/httpie/compare/1.0.0...1.0.1
.. _1.0.2: https://github.com/jakubroztocil/httpie/compare/1.0.1...1.0.2
.. _1.0.3: https://github.com/jakubroztocil/httpie/compare/1.0.2...1.0.3
.. _2.0.0: https://github.com/jakubroztocil/httpie/compare/1.0.3...2.0.0
.. _2.1.0: https://github.com/jakubroztocil/httpie/compare/2.0.0...2.1.0
.. _2.2.0: https://github.com/jakubroztocil/httpie/compare/2.1.0...2.2.0
.. _2.3.0-dev: https://github.com/jakubroztocil/httpie/compare/2.2.0...master
.. _#128: https://github.com/jakubroztocil/httpie/issues/128
.. _#488: https://github.com/jakubroztocil/httpie/issues/488
.. _#668: https://github.com/jakubroztocil/httpie/issues/668
.. _#684: https://github.com/jakubroztocil/httpie/issues/684
.. _#718: https://github.com/jakubroztocil/httpie/issues/718
.. _#719: https://github.com/jakubroztocil/httpie/issues/719
.. _#840: https://github.com/jakubroztocil/httpie/issues/840
.. _#853: https://github.com/jakubroztocil/httpie/issues/853
.. _#852: https://github.com/jakubroztocil/httpie/issues/852
.. _#870: https://github.com/jakubroztocil/httpie/issues/870
.. _#895: https://github.com/jakubroztocil/httpie/issues/895
.. _#920: https://github.com/jakubroztocil/httpie/issues/920
.. _#904: https://github.com/jakubroztocil/httpie/issues/904
.. _#925: https://github.com/jakubroztocil/httpie/issues/925
.. _#932: https://github.com/jakubroztocil/httpie/issues/932
.. _#934: https://github.com/jakubroztocil/httpie/issues/934
.. _#943: https://github.com/jakubroztocil/httpie/issues/943
.. _#963: https://github.com/jakubroztocil/httpie/issues/963

View File

@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
@ -67,10 +67,8 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
<https://www.contributor-covenant.org/faq>

196
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,196 @@
# Contributing to HTTPie
Bug reports and code and documentation patches are welcome. You can
help this project also by using the development version of HTTPie
and by reporting any bugs you might encounter.
## 1. Reporting bugs
**It's important that you provide the full command argument list
as well as the output of the failing command.**
Use the `--debug` flag and copy&paste both the command and its output
to your bug report, e.g.:
```bash
$ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
<COMPLETE OUTPUT>
```
## 2. Contributing Code and Docs
Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/httpie/issues)
to see whether it has previously been discussed.
If your change alters HTTPies behaviour or interface, it's a good idea to
discuss it before you start working on it.
If you are fixing an issue, the first step should be to create a test case that
reproduces the incorrect behaviour. That will also help you to build an
understanding of the issue at hand.
**Pull requests introducing code changes without tests
will generally not get merged. The same goes for PRs changing HTTPies
behaviour and not providing documentation.**
Conversely, PRs consisting of documentation improvements or tests
for existing-yet-previously-untested behavior will very likely be merged.
Therefore, docs and tests improvements are a great candidate for your first
contribution.
Consider also adding a [CHANGELOG](https://github.com/httpie/httpie/blob/master/CHANGELOG.md) entry for your changes.
### Development Environment
#### Getting the code
Go to <https://github.com/httpie/httpie> and fork the project repository.
```bash
# Clone your fork
$ git clone git@github.com:<YOU>/httpie.git
# Enter the project directory
$ cd httpie
# Create a branch for your changes
$ git checkout -b my_topical_branch
```
#### Setup
The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started. Just run
the following command, which:
- Creates an isolated Python virtual environment inside `./venv`
(via the standard library [venv](https://docs.python.org/3/library/venv.html) tool);
- installs all dependencies and also installs HTTPie
(in editable mode so that the `http` command will point to your
working copy).
- and runs tests (It is the same as running `make install test`).
```bash
$ make
```
#### Python virtual environment
Activate the Python virtual environment—created via the `make install`
task during [setup](#setup) for your active shell session using the following command:
```bash
$ source venv/bin/activate
```
(If you use `virtualenvwrapper`, you can also use `workon httpie` to
activate the environment — we have created a symlink for you. Its a bit of
a hack but it works™.)
You should now see `(httpie)` next to your shell prompt, and
the `http` command should point to your development copy:
```bash
(httpie) ~/Code/httpie $ which http
/Users/<user>/Code/httpie/venv/bin/http
(httpie) ~/Code/httpie $ http --version
2.0.0-dev
```
(Btw, you dont need to activate the virtual environment if you just want
run some of the `make` tasks. You can also invoke the development
version of HTTPie directly with `./venv/bin/http` without having to activate
the environment first. The same goes for `./venv/bin/pytest`, etc.).
### Making Changes
Please make sure your changes conform to [Style Guide for Python Code](https://python.org/dev/peps/pep-0008/) (PEP8)
and that `make pycodestyle` passes.
### Testing & CI
Please add tests for any new features and bug fixes.
When you open a Pull Request, [GitHub Actions](https://github.com/httpie/httpie/actions) will automatically run HTTPies [test suite](https://github.com/httpie/httpie/tree/master/tests) against your code, so please make sure all checks pass.
#### Running tests locally
HTTPie uses the [pytest](https://pytest.org/) runner.
```bash
# Run tests on the current Python interpreter with coverage.
$ make test
# Run tests with coverage
$ make test-cover
# Test PEP8 compliance
$ make codestyle
# Run extended tests — for code as well as .md files syntax, packaging, etc.
$ make test-all
```
#### Running specific tests
After you have activated your virtual environment (see [setup](#setup)), you
can run specific tests from the terminal:
```bash
# Run specific tests on the current Python
$ python -m pytest tests/test_uploads.py
$ python -m pytest tests/test_uploads.py::TestMultipartFormDataFileUpload
$ python -m pytest tests/test_uploads.py::TestMultipartFormDataFileUpload::test_upload_ok
```
See [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) for additional development utilities.
#### Windows
If you are on a Windows machine and not able to run `make`,
follow the next steps for a basic setup. As a prerequisite, you need to have
Python 3.6+ installed.
Create a virtual environment and activate it:
```powershell
C:\> python -m venv --prompt httpie venv
C:\> venv\Scripts\activate
```
Install HTTPie in editable mode with all the dependencies:
```powershell
C:\> python -m pip install --upgrade -e . -r requirements-dev.txt
```
You should now see `(httpie)` next to your shell prompt, and
the `http` command should point to your development copy:
```powershell
# In PowerShell:
(httpie) PS C:\Users\ovezovs\httpie> Get-Command http
CommandType Name Version Source
----------- ---- ------- ------
Application http.exe 0.0.0.0 C:\Users\ovezovs\httpie\venv\Scripts\http.exe
```
```bash
# In CMD:
(httpie) C:\Users\ovezovs\httpie> where http
C:\Users\ovezovs\httpie\venv\Scripts\http.exe
C:\Users\ovezovs\AppData\Local\Programs\Python\Python38-32\Scripts\http.exe
(httpie) C:\Users\ovezovs\httpie> http --version
2.3.0-dev
```
Use `pytest` to run tests locally with an active virtual environment:
```bash
# Run all tests
$ python -m pytest
```
______________________________________________________________________
Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/httpie/blob/master/AUTHORS.md)!

View File

@ -1,239 +0,0 @@
######################
Contributing to HTTPie
######################
Bug reports and code and documentation patches are welcome. You can
help this project also by using the development version of HTTPie
and by reporting any bugs you might encounter.
1. Reporting bugs
=================
**It's important that you provide the full command argument list
as well as the output of the failing command.**
Use the ``--debug`` flag and copy&paste both the command and its output
to your bug report, e.g.:
.. code-block:: bash
$ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
<COMPLETE OUTPUT>
2. Contributing Code and Docs
=============================
Before working on a new feature or a bug, please browse `existing issues`_
to see whether it has previously been discussed.
If your change alters HTTPies behaviour or interface, it's a good idea to
discuss it before you start working on it.
If you are fixing an issue, the first step should be to create a test case that
reproduces the incorrect behaviour. That will also help you to build an
understanding of the issue at hand.
**Pull requests introducing code changes without tests
will generally not get merged. The same goes for PRs changing HTTPies
behaviour and not providing documentation.**
Conversely, PRs consisting of documentation improvements or tests
for existing-yet-previously-untested behavior will very likely be merged.
Therefore, docs and tests improvements are a great candidate for your first
contribution.
Consider also adding a ``CHANGELOG`` entry for your changes.
Development Environment
--------------------------------
Getting the code
****************
Go to https://github.com/jakubroztocil/httpie and fork the project repository.
.. code-block:: bash
# Clone your fork
git clone git@github.com:<YOU>/httpie.git
# Enter the project directory
cd httpie
# Create a branch for your changes
git checkout -b my_topical_branch
Setup
*****
The `Makefile`_ contains a bunch of tasks to get you started. Just run
the following command, which:
* Creates an isolated Python virtual environment inside ``./venv``
(via the standard library `venv`_ tool);
* installs all dependencies and also installs HTTPie
(in editable mode so that the ``http`` command will point to your
working copy).
* and runs tests (It is the same as running ``make install test``).
.. code-block:: bash
make
Python virtual environment
**************************
Activate the Python virtual environment—created via the ``make install``
task during `setup`_—for your active shell session using the following command:
.. code-block:: bash
source venv/bin/activate
(If you use ``virtualenvwrapper``, you can also use ``workon httpie`` to
activate the environment — we have created a symlink for you. Its a bit of
a hack but it works™.)
You should now see ``(httpie)`` next to your shell prompt, and
the ``http`` command should point to your development copy:
.. code-block::
(httpie) ~/Code/httpie $ which http
/Users/jakub/Code/httpie/venv/bin/http
(httpie) ~/Code/httpie $ http --version
2.0.0-dev
(Btw, you dont need to activate the virtual environment if you just want
run some of the ``make`` tasks. You can also invoke the development
version of HTTPie directly with ``./venv/bin/http`` without having to activate
the environment first. The same goes for ``./venv/bin/py.test``, etc.).
Making Changes
--------------
Please make sure your changes conform to `Style Guide for Python Code`_ (PEP8)
and that ``make pycodestyle`` passes.
Testing & CI
------------
Please add tests for any new features and bug fixes.
When you open a pull request,
`GitHub Actions <https://github.com/jakubroztocil/httpie/actions>`_
will automatically run HTTPies `test suite`_ against your code
so please make sure all checks pass.
Running tests locally
*********************
HTTPie uses the `pytest`_ runner.
.. code-block:: bash
# Run tests on the current Python interpreter with coverage.
make test
# Run tests with coverage
make test-cover
# Test PEP8 compliance
make pycodestyle
# Run extended tests — for code as well as .rst files syntax, packaging, etc.
make test-all
Running specific tests
**********************
After you have activated your virtual environment (see `setup`_), you
can run specific tests from the terminal:
.. code-block:: bash
# Run specific tests on the current Python
py.test tests/test_uploads.py
py.test tests/test_uploads.py::TestMultipartFormDataFileUpload
py.test tests/test_uploads.py::TestMultipartFormDataFileUpload::test_upload_ok
-----
See `Makefile`_ for additional development utilities.
Windows
*******
If you are on a Windows machine and not able to run ``make``,
follow the next steps for a basic setup. As a prerequisite, you need to have
Python 3.6+ installed.
Create a virtual environment and activate it:
.. code-block:: powershell
python -m venv --prompt httpie venv
venv\Scripts\activate
Install HTTPie in editable mode with all the dependencies:
.. code-block:: powershell
pip install --upgrade -e . -r requirements-dev.txt
You should now see ``(httpie)`` next to your shell prompt, and
the ``http`` command should point to your development copy:
.. code-block:: powershell
# In PowerShell:
(httpie) PS C:\Users\ovezovs\httpie> Get-Command http
CommandType Name Version Source
----------- ---- ------- ------
Application http.exe 0.0.0.0 C:\Users\ovezovs\httpie\venv\Scripts\http.exe
.. code-block:: bash
# In CMD:
(httpie) C:\Users\ovezovs\httpie> where http
C:\Users\ovezovs\httpie\venv\Scripts\http.exe
C:\Users\ovezovs\AppData\Local\Programs\Python\Python38-32\Scripts\http.exe
(httpie) C:\Users\ovezovs\httpie> http --version
2.3.0-dev
Use ``pytest`` to run tests locally with an active virtual environment:
.. code-block:: bash
# Run all tests
py.test
-----
Finally, feel free to add yourself to `AUTHORS`_!
.. _existing issues: https://github.com/jakubroztocil/httpie/issues?state=open
.. _AUTHORS: https://github.com/jakubroztocil/httpie/blob/master/AUTHORS.rst
.. _Makefile: https://github.com/jakubroztocil/httpie/blob/master/Makefile
.. _venv: https://docs.python.org/3/library/venv.html
.. _pytest: https://pytest.org/
.. _Style Guide for Python Code: https://python.org/dev/peps/pep-0008/
.. _test suite: https://github.com/jakubroztocil/httpie/tree/master/tests

View File

@ -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:

View File

@ -1,7 +1,8 @@
include LICENSE
include README.rst
include CHANGELOG.rst
include AUTHORS.rst
include README.md
include CHANGELOG.md
include AUTHORS.md
include docs/README.md
# <https://github.com/jakubroztocil/httpie/issues/182>
# <https://github.com/httpie/httpie/issues/182>
recursive-include tests/ *

View File

@ -1,10 +1,11 @@
###############################################################################
# See ./CONTRIBUTING.rst
# See ./CONTRIBUTING.md
###############################################################################
.PHONY: build
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
VERSION=$(shell grep __version__ httpie/__init__.py)
REQUIREMENTS=requirements-dev.txt
H1="\n\n\033[0;32m\#\#\# "
H1END=" \#\#\# \033[0m\n"
@ -24,15 +25,22 @@ export PATH := $(VENV_BIN):$(PATH)
all: uninstall-httpie install test
install: venv
install: venv install-reqs
install-reqs:
@echo $(H1)Updating package tools$(H1END)
$(VENV_PIP) install --upgrade pip wheel
@echo $(H1)Installing dev requirements$(H1END)
$(VENV_PIP) install --upgrade -r $(REQUIREMENTS)
$(VENV_PIP) install --upgrade --editable '.[dev]'
@echo $(H1)Installing HTTPie$(H1END)
$(VENV_PIP) install --upgrade --editable .
@echo
clean:
@echo $(H1)Cleaning up$(H1END)
rm -rf $(VENV_ROOT)
@ -76,17 +84,17 @@ venv:
test:
@echo $(H1)Running tests$(HEADER_EXTRA)$(H1END)
$(VENV_BIN)/py.test $(COV) ./httpie $(COV) ./tests --doctest-modules --verbose ./httpie ./tests
$(VENV_BIN)/python -m pytest $(COV)
@echo
test-cover: COV=--cov
test-cover: COV=--cov=httpie --cov=tests
test-cover: HEADER_EXTRA=' (with coverage)'
test-cover: test
# test-all is meant to test everything — even this Makefile
test-all: clean install test test-dist pycodestyle
test-all: clean install test test-dist codestyle
@echo
@ -111,10 +119,18 @@ test-bdist-wheel: clean venv
@echo
pycodestyle:
@echo $(H1)Running pycodestyle$(H1END)
@[ -f $(VENV_BIN)/pycodestyle ] || $(VENV_PIP) install pycodestyle
$(VENV_BIN)/pycodestyle httpie/ tests/ extras/ *.py
twine-check:
twine check dist/*
# Kept for convenience, "make codestyle" is preferred though
pycodestyle: codestyle
codestyle:
@echo $(H1)Running flake8$(H1END)
@[ -f $(VENV_BIN)/flake8 ] || $(VENV_PIP) install --upgrade --editable '.[dev]'
$(VENV_BIN)/flake8 httpie/ tests/ docs/packaging/brew/ *.py
@echo
@ -126,11 +142,26 @@ codecov-upload:
@echo
doc-check:
@echo $(H1)Running documentations checks$(H1END)
mdl --git-recurse --style docs/markdownlint.rb .
doc-update-install:
@echo $(H1)Updating installation instructions in the docs$(H1END)
$(VENV_PYTHON) docs/installation/generate.py
###############################################################################
# Publishing to PyPi
###############################################################################
build:
rm -rf build/
$(VENV_PYTHON) setup.py sdist bdist_wheel
publish: test-all publish-no-test
@ -138,8 +169,9 @@ publish-no-test:
@echo $(H1)Testing wheel build an installation$(H1END)
@echo "$(VERSION)"
@echo "$(VERSION)" | grep -q "dev" && echo '!!!Not publishing dev version!!!' && exit 1 || echo ok
$(VENV_PYTHON) setup.py sdist bdist_wheel
$(VENV_BIN)/twine upload dist/*
make build
make twine-check
$(VENV_BIN)/twine upload --repository=httpie dist/*
@echo
@ -159,29 +191,22 @@ uninstall-httpie:
@echo
###############################################################################
# Docs
###############################################################################
pdf:
@echo "Converting README.rst to PDF…"
rst2pdf \
--strip-elements-with-class=no-pdf \
README.rst \
-o README.pdf
@echo "Done"
@echo
###############################################################################
# Homebrew
###############################################################################
brew-deps:
extras/brew-deps.py
docs/packaging/brew/brew-deps.py
brew-test:
@echo $(H1)Uninstalling httpie$(H1END)
- brew uninstall httpie
brew install --build-from-source ./extras/httpie.rb
@echo $(H1)Building from source…$(H1END)
- brew install --build-from-source ./docs/packaging/brew/httpie.rb
@echo $(H1)Verifying…$(H1END)
brew test httpie
@echo $(H1)Auditing…$(H1END)
brew audit --strict httpie

84
README.md Normal file
View File

@ -0,0 +1,84 @@
<br/>
<a href="https://httpie.io" target="blank_">
<img height="100" alt="HTTPie" src="https://raw.githubusercontent.com/httpie/httpie/master/docs/httpie-logo.svg" />
</a>
<br/>
# HTTPie: human-friendly CLI HTTP client for the API era
HTTPie (pronounced _aitch-tee-tee-pie_) is a command-line HTTP client.
Its goal is to make CLI interaction with web services as human-friendly as possible.
HTTPie is designed for testing, debugging, and generally interacting with APIs & HTTP servers.
The `http` & `https` commands allow for creating and sending arbitrary HTTP requests.
They use simple and natural syntax and provide formatted and colorized output.
[![Docs](https://img.shields.io/badge/stable%20docs-httpie.io%2Fdocs-brightgreen?style=flat&color=%2373DC8C&label=Docs)](https://httpie.org/docs)
[![Latest version](https://img.shields.io/pypi/v/httpie.svg?style=flat&label=Latest&color=%234B78E6&logo=&logoColor=white)](https://pypi.python.org/pypi/httpie)
[![Build](https://img.shields.io/github/workflow/status/httpie/httpie/Build?color=%23FA9BFA&label=Build)](https://github.com/httpie/httpie/actions)
[![Coverage](https://img.shields.io/codecov/c/github/httpie/httpie?style=flat&label=Coverage&color=%2373DC8C)](https://codecov.io/gh/httpie/httpie)
[![Twitter](https://img.shields.io/twitter/follow/httpie?style=flat&color=%234B78E6&logoColor=%234B78E6)](https://twitter.com/httpie)
[![Chat](https://img.shields.io/badge/chat-Discord-brightgreen?style=flat&label=Chat%20on&color=%23FA9BFA)](https://httpie.io/discord)
<img src="https://raw.githubusercontent.com/httpie/httpie/master/docs/httpie-animation.gif" alt="HTTPie in action" width="100%"/>
## Getting started
- [Installation instructions →](https://httpie.io/docs#installation)
- [Full documentation →](https://httpie.io/docs)
## Features
- Expressive and intuitive syntax
- Formatted and colorized terminal output
- Built-in JSON support
- Forms and file uploads
- HTTPS, proxies, and authentication
- Arbitrary request data
- Custom headers
- Persistent sessions
- `wget`-like downloads
[See all features →](https://httpie.io/docs)
## Examples
Hello World:
```bash
$ https httpie.io/hello
```
Custom [HTTP method](https://httpie.io/docs#http-method), [HTTP headers](https://httpie.io/docs#http-headers) and [JSON](https://httpie.io/docs#json) data:
```bash
$ http PUT pie.dev/put X-API-Token:123 name=John
```
Build and print a request without sending it using [offline mode](https://httpie.io/docs#offline-mode):
```bash
$ http --offline pie.dev/post hello=offline
```
Use [GitHub API](https://developer.github.com/v3/issues/comments/#create-a-comment) to post a comment on an [Issue](https://github.com/httpie/httpie/issues/83) with [authentication](https://httpie.io/docs#authentication):
```bash
$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:'
```
[See more examples →](https://httpie.io/docs#examples)
## Community & support
- Visit the [HTTPie website](https://httpie.io) for full documentation and useful links.
- Join our [Discord server](https://httpie.io/discord) is to ask questions, discuss features, and for general API chat.
- Tweet at [@httpie](https://twitter.com/httpie) on Twitter.
- Use [StackOverflow](https://stackoverflow.com/questions/tagged/httpie) to ask questions and include a `httpie` tag.
- Create [GitHub Issues](https://github.com/httpie/httpie/issues) for bug reports and feature requests.
- Subscribe to the [HTTPie newsletter](https://httpie.io) for occasional updates.
## Contributing
Have a look through existing [Issues](https://github.com/httpie/httpie/issues) and [Pull Requests](https://github.com/httpie/httpie/pulls) that you could help with. If you'd like to request a feature or report a bug, please [create a GitHub Issue](https://github.com/httpie/httpie/issues) using one of the templates provided.
[See contribution guide →](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md)

2204
README.rst

File diff suppressed because it is too large Load Diff

1979
docs/README.md Normal file

File diff suppressed because it is too large Load Diff

5
docs/config.json Normal file
View File

@ -0,0 +1,5 @@
{
"website": {
"master_and_released_docs_differ_after": "8f8851f1dbd511d3bc0ea0f6da7459045610afce"
}
}

View File

Before

Width:  |  Height:  |  Size: 1019 KiB

After

Width:  |  Height:  |  Size: 1019 KiB

1
docs/httpie-logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1635.31 470"><defs><style>.cls-1{fill:#4b78e6;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M1322.19,73.91h0a36.56,36.56,0,0,1,36.56-36.29h3.41a36.56,36.56,0,0,1,36.56,36.83h0a36.56,36.56,0,0,1-36.56,36.29h-3.41A36.56,36.56,0,0,1,1322.19,73.91Zm6.16,276.93V142.35a7.94,7.94,0,0,1,8-7.94h48.32a7.93,7.93,0,0,1,7.94,7.94V350.84a7.94,7.94,0,0,1-7.94,7.94H1336.3A8,8,0,0,1,1328.35,350.84Z"/><path class="cls-1" d="M1635.31,233.34c0-61.06-33.28-105.09-101.71-105.09-72.17,0-114.82,45.45-114.82,123.08,0,74.79,46.86,113.6,113.89,113.6,56.83,0,85.93-27.17,98.33-63.86a8,8,0,0,0-5.34-10.28l-40.32-11.39a8,8,0,0,0-9.54,4.73c-5.77,14.37-16.57,25.42-42.2,25.42-29.32,0-46.06-13.62-50.74-44.29a7.17,7.17,0,0,0,.81.08h143.7a8,8,0,0,0,7.94-7.94V242.23c0-.09,0-.18,0-.28C1635.31,239.17,1635.31,236.36,1635.31,233.34Zm-103.58-51.6c28.59,0,43.12,15.15,45,45H1483C1487.21,195,1503.61,181.74,1531.73,181.74Z"/><path class="cls-1" d="M581.91,358.75H533.56a7.93,7.93,0,0,1-7.94-7.94V76.39a7.93,7.93,0,0,1,7.94-7.94h48.35a7.93,7.93,0,0,1,7.94,7.94v84.66a6,6,0,0,0,11.22,2.77c13.45-25.56,34.68-35.33,60.42-35.69,38.66-.55,70,31.45,70,70.12V350.81a7.94,7.94,0,0,1-7.94,7.94H675.63a7.94,7.94,0,0,1-7.94-7.94V227.1c0-23.21-10.32-40.73-37-40.73-25.79,0-40.8,15.15-40.8,40.73V350.81A7.93,7.93,0,0,1,581.91,358.75Z"/><path class="cls-1" d="M1052.84,306.12a7.94,7.94,0,0,0-9.77-6.78c-6.47,1.55-13.73,3.05-20.35,3.05-19.23,0-25.79-8.52-25.79-26.52V188.26h50.67a7.94,7.94,0,0,0,7.94-7.94v-38.1a8,8,0,0,0-7.94-7.95H996.93V85.86A7.94,7.94,0,0,0,989,77.92H941.1a7.93,7.93,0,0,0-7.94,7.94v48.41H842.67V85.86a7.94,7.94,0,0,0-7.94-7.94H786.84a7.93,7.93,0,0,0-7.94,7.94v48.41H761.05a7.94,7.94,0,0,0-7.94,7.95v38.1a7.93,7.93,0,0,0,7.94,7.94H778.9v99.93c0,42.62,21.57,77.19,73.15,77.19,21.16,0,32.43-2.5,46.08-6.56a8,8,0,0,0,5.65-8.56l-5.2-44.14a7.94,7.94,0,0,0-9.77-6.78c-6.47,1.55-13.73,3.05-20.35,3.05-19.23,0-25.79-8.52-25.79-26.52V188.26h90.49v99.93c0,42.62,21.57,77.19,73.14,77.19,21.17,0,32.44-2.5,46.09-6.56a8,8,0,0,0,5.65-8.56Z"/><path class="cls-1" d="M1219.14,365.27c-28.49,0-49.51-10.92-62.87-35.86a6,6,0,0,0-11.19,2.84v82.83a7.93,7.93,0,0,1-7.94,7.94h-48.32a7.94,7.94,0,0,1-8-7.94V142.21a8,8,0,0,1,8-7.94h48.32a7.94,7.94,0,0,1,7.94,7.94v18.95c0,6.13,8.21,8.3,11.15,2.92,13.74-25.16,35.63-36,64.31-36,53.43,0,81.08,44,81.08,116.92C1301.62,320.78,1273,365.27,1219.14,365.27Zm19.21-119.76c0-37.39-14.06-59.17-46.4-59.17-29.53,0-46.87,20.35-46.87,57.28v4.26c0,36.45,17.34,59.17,46.87,59.17C1223.82,307.05,1238.35,284.33,1238.35,245.51Z"/><path class="cls-1" d="M394.41,102.12C394,45.31,346.61,0,289.8,0H104.69C48.31,0,1.09,44.6,0,101A103.07,103.07,0,0,0,103,205.92h82.7a6,6,0,0,1,2.39,11.42L61.31,272.91A103.09,103.09,0,0,0,0,367.83C.43,424.65,47.79,470,104.62,470H148c57.23,0,104.88-45.9,104.79-103.13a103.1,103.1,0,0,0-64.49-95.31,5.94,5.94,0,0,1-.1-10.94l145-63.58A103.08,103.08,0,0,0,394.41,102.12Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,5 @@
Here we maintain a database of installation methods, from which we generate
the installation section in docs. If youd like add or update an installation method,
edit [methods.yml](./methods.yml), do not edit the main docs directly.
For HTTPie installation instructions see: <https://httpie.io/docs#installation>.

View File

@ -0,0 +1,85 @@
import re
import sys
from pathlib import Path
from typing import Dict
import yaml
from jinja2 import Template
Database = Dict[str, dict]
# Files
HERE = Path(__file__).parent
DB_FILE = HERE / 'methods.yml'
DOC_FILE = HERE.parent / 'README.md'
TPL_FILE = HERE / 'installation.jinja2'
# Database keys
KEY_DOC_STRUCTURE = 'docs-structure'
KEY_TOOLS = 'tools'
# Markers in-between content will be put.
MARKER_START = '<div data-installation-instructions>'
MARKER_END = '</div>'
def generate_documentation() -> str:
database = load_database()
structure = build_docs_structure(database)
template = Template(source=TPL_FILE.read_text(encoding='utf-8'))
output = template.render(structure=structure)
output = clean_template_output(output)
return output
def save_doc_file(content: str) -> None:
current_doc = load_doc_file()
marker_start = current_doc.find(MARKER_START) + len(MARKER_START)
assert marker_start > 0, 'cannot find the start marker'
marker_end = current_doc.find(MARKER_END, marker_start)
assert marker_start < marker_end, f'{marker_end=} < {marker_start=}'
updated_doc = (
current_doc[:marker_start]
+ '\n\n'
+ content
+ '\n\n'
+ current_doc[marker_end:]
)
if current_doc != updated_doc:
DOC_FILE.write_text(updated_doc, encoding='utf-8')
def build_docs_structure(database: Database):
tools = database[KEY_TOOLS]
assert len(tools) == len({tool['title'] for tool in tools.values()}), 'tool titles need to be unique'
tree = database[KEY_DOC_STRUCTURE]
structure = []
for platform, tools_ids in tree.items():
assert platform.isalnum(), f'{platform=} must be alpha-numeric for generated links to work'
platform_tools = [tools[tool_id] for tool_id in tools_ids]
structure.append((platform, platform_tools))
return structure
def clean_template_output(output):
output = '\n'.join(line.strip() for line in output.strip().splitlines())
output = re.sub('\n{3,}', '\n\n', output)
return output
def load_database() -> Database:
return yaml.safe_load(DB_FILE.read_text(encoding='utf-8'))
def load_doc_file() -> str:
return DOC_FILE.read_text(encoding='utf-8')
def main() -> int:
content = generate_documentation()
save_doc_file(content)
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,37 @@
<!--
THE INSTALLATION SECTION IS GENERATED
Do not edit here, but in docs/installation/.
-->
{% for platform, tools in structure %}
- [{{ platform }}](#{{ platform.lower() }}){% endfor %} {# <= keep `endfor` here to prevent unwanted `\n` #}
{% for platform, tools in structure %}
### {{ platform }}
{% for tool in tools %}
#### {{ tool.title }}
{% if tool.note %}
{{ tool.note }}
{% endif %}
{% if tool.links.setup %}
To install [{{ tool.name }}]({{ tool.links.homepage }}) follow [installation instructions]({{ tool.links.setup }}).
{% endif %}
```bash
# Install
$ {{ tool.commands.install|join('\n$ ') }}
```
```bash
# Upgrade
$ {{ tool.commands.upgrade|join('\n$ ') }}
```
{% endfor %}
{% endfor %}
<!-- /GENERATED SECTION -->

View File

@ -0,0 +1,269 @@
# Database of HTTPie installation methods. Used to build the docs.
#
# We currently only include here methods for popular systems where we take care of the package,
# or have a good relationship with the maintainers.
#
# Each tool name should be unique (it becomes a linkable header).
# If a tools have `links.setup`, it also needs `links.homepage`.
# Some tools are available on multiple platforms, take into account when editing.
#
docs-structure:
Universal:
- pypi
macOS:
- brew-mac
- port
- snap-mac
- spack-mac
Windows:
- chocolatey
Linux:
- snap-linux
- brew-linux
- apt
- dnf
- yum
- apk
- emerge
- pacman
- xbps-install
- spack-linux
FreeBSD:
- pkg
tools:
apk:
title: Alpine Linux
name: apk
links:
homepage: https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management
package: https://pkgs.alpinelinux.org/package/edge/community/x86/httpie
commands:
install:
- apk update
- apk add httpie
upgrade:
- apk update
- apk add --upgrade httpie
apt:
title: Debian and Ubuntu
note: Also works for other Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc.
name: APT
links:
homepage: https://en.wikipedia.org/wiki/APT_(software)
package: https://packages.debian.org/sid/web/httpie
commands:
install:
- apt update
- apt install httpie
upgrade:
- apt update
- apt upgrade httpie
brew-mac:
title: Homebrew
name: Homebrew
links:
homepage: https://brew.sh/
setup: https://docs.brew.sh/Installation
package: https://formulae.brew.sh/formula/httpie
commands:
install:
- brew update
- brew install httpie
upgrade:
- brew update
- brew upgrade httpie
brew-linux:
title: Linuxbrew
name: Linuxbrew
links:
homepage: https://docs.brew.sh/Homebrew-on-Linux
setup: https://docs.brew.sh/Homebrew-on-Linux#install
package: https://formulae.brew.sh/formula/httpie
commands:
install:
- brew update
- brew install httpie
upgrade:
- brew update
- brew upgrade httpie
chocolatey:
title: Chocolatey
name: Chocolatey
links:
homepage: https://chocolatey.org/
setup: https://chocolatey.org/install
package: https://community.chocolatey.org/packages/httpie/
commands:
install:
- choco install httpie
upgrade:
- choco upgrade httpie
dnf:
title: Fedora
name: DNF
links:
homepage: https://fedoraproject.org/wiki/DNF
package: https://src.fedoraproject.org/rpms/httpie
commands:
install:
- dnf update
- dnf install httpie
upgrade:
- dnf update
- dnf upgrade httpie
emerge:
title: Gentoo
name: Portage
links:
homepage: https://wiki.gentoo.org/wiki/Portage
package: https://packages.gentoo.org/packages/net-misc/httpie
commands:
install:
- emerge --sync
- emerge httpie
upgrade:
- emerge --sync
- emerge --update httpie
pacman:
title: Arch Linux
name: pacman
note: Also works for other Arch-derived distributions like ArcoLinux, EndeavourOS, Artix Linux, etc.
links:
homepage: https://archlinux.org/pacman/
package: https://archlinux.org/packages/community/any/httpie/
commands:
install:
- pacman -Sy httpie
upgrade:
- pacman -Syu httpie
pkg:
title: FreshPorts
name: FreshPorts
links:
homepage: https://www.freebsd.org/cgi/man.cgi?query=pkg&sektion=8&n=1
package: https://www.freshports.org/www/py-httpie/
commands:
install:
- pkg install www/py-httpie
upgrade:
- pkg upgrade www/py-httpie
port:
title: MacPorts
name: MacPorts
links:
homepage: https://www.macports.org/
setup: https://www.macports.org/install.php
package: https://ports.macports.org/port/httpie/
commands:
install:
- port selfupdate
- port install httpie
upgrade:
- port selfupdate
- port upgrade httpie
pypi:
title: PyPi
name: pip
note: Please make sure you have Python 3.6 or newer (`python --version`).
links:
homepage: https://pypi.org/
# setup: https://pip.pypa.io/en/stable/installation/
package: https://pypi.org/project/httpie/
commands:
install:
- python -m pip install --upgrade pip wheel
- python -m pip install httpie
upgrade:
- python -m pip install --upgrade pip wheel
- python -m pip install --upgrade httpie
snap-linux:
title: Snapcraft (Linux)
name: Snapcraft
links:
homepage: https://snapcraft.io/
setup: https://snapcraft.io/docs/installing-snapd
package: https://snapcraft.io/httpie
commands:
install:
- snap install httpie
upgrade:
- snap refresh httpie
snap-mac:
title: Snapcraft (macOS)
name: Snapcraft
links:
homepage: https://snapcraft.io/
setup: https://snapcraft.io/docs/installing-snapd
package: https://snapcraft.io/httpie
commands:
install:
- snap install httpie
upgrade:
- snap refresh httpie
spack-linux:
title: Spack (Linux)
name: Spack
links:
homepage: https://spack.readthedocs.io/en/latest/index.html
setup: https://spack.readthedocs.io/en/latest/getting_started.html#installation
commands:
install:
- spack install httpie
upgrade:
- spack install httpie
spack-mac:
title: Spack (macOS)
name: Spack
links:
homepage: https://spack.readthedocs.io/en/latest/index.html
setup: https://spack.readthedocs.io/en/latest/getting_started.html#installation
commands:
install:
- spack install httpie
upgrade:
- spack install httpie
xbps-install:
title: Void Linux
name: XBPS
links:
homepage: https://docs.voidlinux.org/xbps/index.html
commands:
install:
- xbps-install -Su
- xbps-install -S httpie
upgrade:
- xbps-install -Su
- xbps-install -Su httpie
yum:
title: CentOS and RHEL
name: Yum
note: Also works for other RHEL-derived distributions like ClearOS, Oracle Linux, etc.
links:
homepage: http://yum.baseurl.org/
package: https://src.fedoraproject.org/rpms/httpie
commands:
install:
- yum update
- yum install epel-release
- yum install httpie
upgrade:
- yum update
- yum upgrade httpie

41
docs/markdownlint.rb Normal file
View File

@ -0,0 +1,41 @@
# Rules for <https://github.com/markdownlint/markdownlint>
# Load all rules by default
all
#
# Tweak rules
#
# MD002 First header should be a top level header
# Because we use HTML to hide them on the website.
exclude_rule 'MD002'
# MD013 Line length
exclude_rule 'MD013'
# MD014 Dollar signs used before commands without showing output
exclude_rule 'MD014'
# Tell the linter to use ordered lists:
# 1. Foo
# 2. Bar
# 3. Baz
#
# Instead of:
# 1. Foo
# 1. Bar
# 1. Baz
rule 'MD029', :style => :ordered
# MD033 Inline HTML
# TODO: Tweak elements when https://github.com/markdownlint/markdownlint/issues/118 will be done?
exclude_rule 'MD033'
# MD034 Bare URL used
# TODO: Remove when https://github.com/markdownlint/markdownlint/issues/328 will be fixed.
exclude_rule 'MD034'
# MD041 First line in file should be a top level header
# Because we use HTML to hide them on the website.
exclude_rule 'MD041'

49
docs/packaging/README.md Normal file
View File

@ -0,0 +1,49 @@
# HTTPie release process
Welcome on the documentation part of the **HTTPie release process**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions, then you can find all you need for your OS on [that page](https://httpie.io/docs#installation). In the case you do not find your OS, [let us know](https://github.com/httpie/httpie/issues/).
- If you are looking for technical information about the HTTPie packaging, then you are at the good place.
## About
You are looking at the HTTPie packaging documentation, where you will find valuable information about how we manage to release HTTPie to lots of OSes, including technical data that may be worth reading if you are a package maintainer.
The overall release process starts simple:
1. Do the [PyPi](https://pypi.org/project/httpie/) publication.
2. Then, handle company-related tasks.
3. Finally, follow OS-specific steps, described in documents below, to send patches downstream.
## First, PyPi
Let's do the release on [PyPi](https://pypi.org/project/httpie/).
That is done quite easily by manually triggering the [release workflow](https://github.com/httpie/httpie/actions/workflows/release.yml).
## Then, company-specific tasks
- Update the HTTPie version bundled into termible ([example](https://github.com/httpie/termible/pull/1)).
## Finally, spread dowstream
Find out how we do release new versions for each and every supported OS in the following table.
A more complete state of deployment can be found on [repology](https://repology.org/project/httpie/versions), including unofficial packages.
| OS | Maintainer |
| -------------------------------------------: | -------------- |
| [Alpine](linux-alpine/) | **HTTPie** |
| [Arch Linux, and derived](linux-arch/) | trusted person |
| :construction: [AOSC OS](linux-aosc/) | **HTTPie** |
| [CentOS, RHEL, and derived](linux-centos/) | trusted person |
| [Debian, Ubuntu, and derived](linux-debian/) | trusted person |
| [Fedora](linux-fedora/) | trusted person |
| [Gentoo](linux-gentoo/) | **HTTPie** |
| :construction: [Homebrew, Linuxbrew](brew/) | **HTTPie** |
| :construction: [MacPorts](mac-ports/) | **HTTPie** |
| [Snapcraft](snapcraft/) | **HTTPie** |
| [Spack](spack/) | **HTTPie** |
| [Void Linux](linux-void/) | **HTTPie** |
| [Windows — Chocolatey](windows-chocolatey/) | **HTTPie** |
:new: You do not find your system or you would like to see HTTPie supported on another OS? Then [let us know](https://github.com/httpie/httpie/issues/).

View File

@ -0,0 +1,33 @@
# HTTPie on Homebrew, and Linuxbrew
Welcome to the documentation about **packaging HTTPie for Homebrew**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Homebrew, then you can find them on [that page](https://httpie.io/docs#homebrew) ([that one](https://httpie.io/docs#linuxbrew) for Linuxbrew).
- If you are looking for technical information about the HTTPie packaging on Homebrew, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Homebrew. They apply to Linuxbrew as well.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
:construction: Work in progress.
First, update the current Formula:
```bash
make brew-deps
# Copy-paste content into downstream/mac/brew/httpie.rb
git add downstream/mac/brew/httpie.rb
git commit -s -m 'Update brew formula to XXX'
```
That [GitHub workflow](https://github.com/httpie/httpie/actions/workflows/test-package-mac-brew.yml) will test the formula when `downstream/mac/brew/httpie.rb` is changed in a pull request.
Then, open a pull request with those changes to the [downstream file]([ file](https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpie.rb)).
## Hacking
:construction: Work in progress.

View File

@ -12,24 +12,40 @@ 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': '3.2',
}
# Note: Keep that list sorted.
PACKAGES = [
'certifi',
'charset-normalizer',
'defusedxml',
'httpie',
'idna',
'Pygments',
'PySocks',
'requests',
'requests-toolbelt',
'certifi',
'urllib3',
'idna',
'chardet',
'PySocks',
]
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)

View File

@ -0,0 +1,74 @@
class Httpie < Formula
include Language::Python::Virtualenv
desc "User-friendly cURL replacement (command-line HTTP client)"
homepage "https://httpie.io/"
url "https://files.pythonhosted.org/packages/90/64/7ea8066309970f787653bdc8c5328272a5c4d06cbce3a07a6a5c3199c3d7/httpie-2.5.0.tar.gz"
sha256 "fe6a8bc50fb0635a84ebe1296a732e39357c3e1354541bf51a7057b4877e47f9"
license "BSD-3-Clause"
head "https://github.com/httpie/httpie.git"
bottle do
sha256 cellar: :any_skip_relocation, arm64_big_sur: "01115f69aff0399b3f73af09899a42a14343638a4624a35749059cc732c49cdc"
sha256 cellar: :any_skip_relocation, big_sur: "53f07157f00edf8193b7d4f74f247f53e1796fbc3e675cd2fbaa4b9dc2bad62c"
sha256 cellar: :any_skip_relocation, catalina: "7cf216fdee98208856d654060fdcad3968623d7ed27fcdeba27d3120354c9a9f"
sha256 cellar: :any_skip_relocation, mojave: "28adb5aed8c1c2b39c51789f242ff0dffde39073e161deb379c79184d787d063"
sha256 cellar: :any_skip_relocation, x86_64_linux: "91cb8c332c643bd8b1d0a8f3ec0acd4770b407991f6de1fd320d675f2b2e95ec"
end
depends_on "python@3.9"
resource "certifi" do
url "https://files.pythonhosted.org/packages/6d/78/f8db8d57f520a54f0b8a438319c342c61c22759d8f9a1cd2e2180b5e5ea9/certifi-2021.5.30.tar.gz"
sha256 "2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"
end
resource "charset-normalizer" do
url "https://files.pythonhosted.org/packages/e7/4e/2af0238001648ded297fb54ceb425ca26faa15b341b4fac5371d3938666e/charset-normalizer-2.0.4.tar.gz"
sha256 "f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"
end
resource "defusedxml" do
url "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz"
sha256 "1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"
end
resource "idna" do
url "https://files.pythonhosted.org/packages/cb/38/4c4d00ddfa48abe616d7e572e02a04273603db446975ab46bbcd36552005/idna-3.2.tar.gz"
sha256 "467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
end
resource "Pygments" do
url "https://files.pythonhosted.org/packages/b7/b3/5cba26637fe43500d4568d0ee7b7362de1fb29c0e158d50b4b69e9a40422/Pygments-2.10.0.tar.gz"
sha256 "f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"
end
resource "PySocks" do
url "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz"
sha256 "3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
end
resource "requests" do
url "https://files.pythonhosted.org/packages/e7/01/3569e0b535fb2e4a6c384bdbed00c55b9d78b5084e0fb7f4d0bf523d7670/requests-2.26.0.tar.gz"
sha256 "b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
end
resource "requests-toolbelt" do
url "https://files.pythonhosted.org/packages/28/30/7bf7e5071081f761766d46820e52f4b16c8a08fef02d2eb4682ca7534310/requests-toolbelt-0.9.1.tar.gz"
sha256 "968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"
end
resource "urllib3" do
url "https://files.pythonhosted.org/packages/4f/5a/597ef5911cb8919efe4d86206aa8b2658616d676a7088f0825ca08bd7cb8/urllib3-1.26.6.tar.gz"
sha256 "f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"
end
def install
virtualenv_install_with_resources
end
test do
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

View File

@ -0,0 +1,33 @@
# Contributor: Fabian Affolter <fabian@affolter-engineering.ch>
# Maintainer: Fabian Affolter <fabian@affolter-engineering.ch>
# Contributor: Daniel Isaksen <d@duniel.no>
# Contributor: Mickaël Schoentgen <mickael@apible.io>
pkgname=httpie
pkgver=2.5.0
pkgrel=0
pkgdesc="CLI, cURL-like tool"
url="https://httpie.org/"
arch="noarch"
license="BSD-3-Clause"
depends="python3 py3-setuptools py3-requests py3-pygments py3-requests-toolbelt py3-pysocks py3-defusedxml"
makedepends="py3-setuptools"
checkdepends="py3-pytest py3-pytest-httpbin py3-responses"
source="https://files.pythonhosted.org/packages/source/h/httpie/httpie-$pkgver.tar.gz"
# secfixes:
# 1.0.3-r0:
# - CVE-2019-10751
build() {
python3 setup.py build
}
check() {
python3 -m pytest ./httpie ./tests
}
package() {
python3 setup.py install --prefix=/usr --root="$pkgdir"
}
sha512sums="3bfe572b03bfde87d5a02f9ba238f9493b32e587c33fd30600a4dd6a45082eedcb2b507c7f1e3e75a423cbdcc1ff0556138897dffb7888d191834994eae9a2aa httpie-2.5.0.tar.gz"

View File

@ -0,0 +1,67 @@
# HTTPie on Alpine Linux
Welcome to the documentation about **packaging HTTPie for Alpine Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Alpine Linux, then you can find them on [that page](https://httpie.io/docs#alpine-linux).
- If you are looking for technical information about the HTTPie packaging on Alpine Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Alpine Linux.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/community/httpie/APKBUILD) ([example](https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/25075)).
Notes:
- The `pkgrel` value must be set to `0`.
- The commit message must be `community/httpie: upgrade to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull alpine
docker run -it --rm alpine
```
From inside the container:
```bash
# Install tools
apk add alpine-sdk sudo
# Add a user (password required)
adduser me
addgroup me abuild
echo "me ALL=(ALL) ALL" >> /etc/sudoers
# Switch user
su - me
# Create a private key (not used but required)
abuild-keygen -a -i
# Clone
git clone --depth=1 https://gitlab.alpinelinux.org/alpine/aports.git
cd aports/community/httpie
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-alpine/APKBUILD \
-o APKBUILD
# Build the package
abuild -r
# Install the package
sudo apk add --repository ~/packages/community httpie
# And test it!
http --version
https --version
```

View File

@ -0,0 +1,24 @@
# HTTPie on AOSC OS
Welcome to the documentation about **packaging HTTPie for AOSC OS**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for technical information about the HTTPie packaging on AOSC OS, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for AOSC OS.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/AOSC-Dev/aosc-os-abbs/blob/stable/extra-web/httpie/spec) ([example](https://github.com/AOSC-Dev/aosc-os-abbs/commit/d0d3ba0bcea347387bb582a1b0b1b4e518720c80)).
Notes:
- The commit message must be `httpie: update to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
:construction: Work in progress.

View File

@ -0,0 +1,5 @@
VER=2.5.0
SRCS="tbl::https://github.com/httpie/httpie/archive/$VER.tar.gz"
CHKSUMS="sha256::66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea"
REL=1
CHKUPDATE="anitya::id=1337"

View File

@ -0,0 +1,46 @@
# Maintainer: Jelle van der Waa <jelle@archlinux.org>
# Maintainer: daurnimator <daurnimator@archlinux.org>
# Contributor: Daniel Micay <danielmicay@gmail.com>
# Contributor: Thomas Weißschuh <thomas_weissschuh lavabit com>
pkgname=httpie
pkgver=2.5.0
pkgrel=1
pkgdesc="human-friendly CLI HTTP client for the API era"
url="https://github.com/httpie/httpie"
depends=('python-defusedxml'
'python-pygments'
'python-pysocks'
'python-requests'
'python-requests-toolbelt')
makedepends=('python-setuptools')
checkdepends=('python-pytest'
'python-pytest-httpbin'
'python-responses')
conflicts=(python-httpie)
replaces=(python-httpie python2-httpie)
license=('BSD')
arch=('any')
source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/httpie/archive/$pkgver.tar.gz")
sha256sums=('66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea')
build() {
cd $pkgname-$pkgver
python3 setup.py build
}
package() {
cd $pkgname-$pkgver
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/httpie/LICENSE"
python3 setup.py install --root="$pkgdir" --optimize=1
# Fix upstream, include them in MANIFEST.in and use data_files in setup.py to install them automatically
# TODO: add zsh support
install -Dm644 extras/httpie-completion.bash "$pkgdir"/usr/share/bash-completion/completions/http
install -Dm644 extras/httpie-completion.fish "$pkgdir"/usr/share/fish/vendor_completions.d/http.fish
}
check() {
cd $pkgname-$pkgver
PYTHONDONTWRITEBYTECODE=1 python3 setup.py test
}

View File

@ -0,0 +1,22 @@
# HTTPie on Arch Linux, and derived
Welcome to the documentation about **packaging HTTPie for Arch Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Arch Linux, then you can find them on [that page](https://httpie.io/docs#arch-linux).
- If you are looking for technical information about the HTTPie packaging on Arch Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Arch Linux. They apply to Arch-derived distributions as well, like ArcoLinux, EndeavourOS, Artix Linux, etc.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Note: Sending patches downstream does not seem easy. We failed to find where is located the package file on <https://gitlab.archlinux.org>. So we are relying on the last maintainer, daurnimator, and it works pretty well so far.
Check <https://archlinux.org/packages/community/any/httpie/> and if the version is outdated, simply [report it](https://archlinux.org/packages/community/any/httpie/flag/).
## Hacking
Left blank on purpose, we will fill that section when we will have access to the downstream repository.

View File

@ -0,0 +1,26 @@
# HTTPie on CentOS, RHEL, and derived
Welcome to the documentation about **packaging HTTPie for CentOS and RHEL**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on CentOS, then you can find them on [that page](https://httpie.io/docs#centos-and-rhel).
- If you are looking for technical information about the HTTPie packaging on CentOS, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for CentOS. They apply to RHEL as well, and any RHEL-derived distributions like ClearOS, Oracle Linux, etc.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
The current maintainer is [Mikel Olasagasti](https://github.com/kaxero).
## Overall process
Same as [Fedora](../linux-fedora/README.md#overall-process).
## Q/A with Mikel
Q: What should we do to help seeing a new version on CentOS?
A: When a new release is published Miro and I get notified by [release-monitoring](https://release-monitoring.org/project/1337/), that fills a BugZilla ticket reporting a new version being available.
The system also tries to create a simple patch to update the spec file, but in the case of CentOS it needs some manual revision. For example for 2.5.0 `defuxedxml` dep is required. Maybe with CentOS-9 and some new macros that are available now in Fedora it can be automated same way. But even the bump can be automated, maintainers should check for license changes, new binaries/docs/ and so on.

View File

@ -0,0 +1,29 @@
# HTTPie on Debian, Ubuntu, and derived
Welcome to the documentation about **packaging HTTPie for Debian GNU/Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Debian GNU/Linux, then you can find them on [that page](https://httpie.io/docs#debian-and-ubuntu).
- If you are looking for technical information about the HTTPie packaging on Debian GNU/Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Debian GNU/Linux. They apply to Ubuntu as well, and any Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
The current maintainer is Bartosz Fenski.
## Overall process
Open a new bug on the Debian Bug Tracking System by sending an email:
- To: `Debian Bug Tracking System <submit@bugs.debian.org>`
- Subject: `httpie: Version XXX available`
- Message template ([example](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993937)):
```email
Package: httpie
Severity: wishlist
<MESSAGE>
```

View File

@ -0,0 +1,48 @@
# HTTPie on Fedora
Welcome to the documentation about **packaging HTTPie for Fedora**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Fedora, then you can find them on [that page](https://httpie.io/docs#fedora).
- If you are looking for technical information about the HTTPie packaging on Fedora, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Fedora.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
The current maintainer is [Miro Hrončok](https://github.com/hroncok).
## Overall process
We added the [.packit.yaml](https://github.com/httpie/httpie/blob/master/.packit.yaml) local file.
It unlocks real-time Fedora checks on pull requests and new releases.
So there is nothing to do on our side: `Packit` will see the new release and open a pull request [there](https://src.fedoraproject.org/rpms/httpie). Then, the Fedora maintainer will review and merge.
It is also possible to follow [user feedbacks](https://bodhi.fedoraproject.org/updates/?packages=httpie) for all builds.
## Q/A with Miro
Q: What would the command to install the latest stable version look like?
A: Assuming the latest stable version is already propagated to Fedora:
```bash
# Note that yum is an alias to dnf.
$ sudo dnf install httpie
```
Q: Will dnf/yum upgrade then update to the latest?
A: Yes, assuming the same as above.
Q: Are new versions backported automatically?
A: No. The process is:
1. A new HTTPie release is created on Github.
2. A pull request for Fedora `rawhide` (the development version of Fedora, currently Fedora 35) is created.
3. A Fedora packager (usually Miro) sanity checks the pull request and merges, builds. HTTPie is updated in `rawhide` within 24 hours (sometimes more, for unrelated issues).
4. A Fedora packager decides whether the upgrade is suitable for stable Fedora releases (currently 34, 33), if so, merges the changes there.
5. (if the above is yes) The new version of HTTPie lands in `updates-testing` repo where it waits for user feedback and lands within ~1 week for broad availability.

View File

@ -0,0 +1,2 @@
DIST httpie-2.4.0.tar.gz 1772537 BLAKE2B 111451cc7dc353d5b586554f98ac715a3198f03e74d261944a5f021d2dcc948455500800222b323d182a2a067d0549bda7c318ab3a6c934b9a9beec64aff2db2 SHA512 44cc7ff4fe0f3d8c53a7dd750465f6b56c36f5bbac06d22b760579bd60949039e82313845699669a659ec91adc69dbeac22c06ddd63af64e6f2e0edecf3e732a
DIST httpie-2.5.0.tar.gz 1105177 BLAKE2B 6e16868c81522d4e6d2fc0a4e093c190f18ced720b35217930865ae3f8e168193cc33dfecc13c5d310f52647d6e79d17b247f56e56e8586d633a2d9502be66a7 SHA512 f14aa23fea7578181b9bd6ededea04de9ddf0b2f697b23f76d2d96e2c17b95617318c711750bad6af550400dbc03732ab17fdf84e59d577f33f073e600a55330

View File

@ -0,0 +1,78 @@
# HTTPie on Gentoo
Welcome to the documentation about **packaging HTTPie for Gentoo**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Gentoo, then you can find them on [that page](https://httpie.io/docs#gentoo).
- If you are looking for technical information about the HTTPie packaging on Gentoo, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Gentoo.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to create `httpie-XXX.ebuild` and update `Manifest`.
- Here is how to calculate the size and checksum (replace `2.5.0` with the correct version):
```bash
# Download
$ wget https://github.com/httpie/httpie/archive/2.5.0.tar.gz
# Size
$ stat --printf="%s\n" 2.5.0.tar.gz
1105177
# Checksum
$ openssl dgst -blake2b512 2.5.0.tar.gz
BLAKE2b512(2.5.0.tar.gz)= 6e16868c81522d4e6d2fc0a4e093c190f18ced720b35217930865ae3f8e168193cc33dfecc13c5d310f52647d6e79d17b247f56e56e8586d633a2d9502be66a7
```
- The commit message must be `net-misc/httpie: version bump to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull gentoo/stage3
docker run -it --rm gentoo/stage3
```
From inside the container:
```bash
# Install tools
emerge --sync
emerge pkgcheck repoman
# Go to the package location
cd /var/db/repos/gentoo/net-misc/httpie
# Retrieve the patch of the latest HTTPie version
# (only files that were modified since the previous release)
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/httpie-XXX.ebuild \
-o httpie-XXX.ebuild
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/Manifest \
-o Manifest
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/metadata.xml \
-o metadata.xml
# Basic checks
repoman manifest
repoman full -d -x
pkgcheck scan
# Build and install the package
emerge --with-test-deps httpie-XXX.ebuild
# Run the tests suite
ebuild httpie-XXX.ebuild clean test
# And test it!
http --version
https --version
```

View File

@ -0,0 +1,42 @@
# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=7
DISTUTILS_USE_SETUPTOOLS=rdepend
PYTHON_COMPAT=( python3_{8,9,10} )
PYTHON_REQ_USE="ssl(+)"
inherit bash-completion-r1 distutils-r1
DESCRIPTION="Modern command line HTTP client"
HOMEPAGE="https://httpie.io/ https://pypi.org/project/httpie/"
SRC_URI="https://github.com/httpie/httpie/archive/${PV}.tar.gz -> ${P}.tar.gz"
LICENSE="BSD"
SLOT="0"
KEYWORDS="~amd64 ~x86"
RDEPEND="
dev-python/defusedxml[${PYTHON_USEDEP}]
dev-python/pygments[${PYTHON_USEDEP}]
>=dev-python/requests-2.22.0[${PYTHON_USEDEP}]
>=dev-python/requests-toolbelt-0.9.1[${PYTHON_USEDEP}]
"
BDEPEND="
test? (
${RDEPEND}
dev-python/pyopenssl[${PYTHON_USEDEP}]
dev-python/pytest-httpbin[${PYTHON_USEDEP}]
dev-python/responses[${PYTHON_USEDEP}]
)
"
distutils_enable_tests pytest
python_install_all() {
newbashcomp extras/httpie-completion.bash http
insinto /usr/share/fish/vendor_completions.d
newins extras/httpie-completion.fish http.fish
distutils-r1_python_install_all
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<maintainer type="person" proxied="yes">
<email>mickael@apible.io</email>
<name>Mickaël Schoentgen</name>
</maintainer>
<maintainer type="project" proxied="proxy">
<email>proxy-maint@gentoo.org</email>
<name>Proxy Maintainers</name>
</maintainer>
<longdescription lang="en">
HTTPie (pronounced aitch-tee-tee-pie) is a command line HTTP
client. Its goal is to make CLI interaction with web services as
human-friendly as possible. It provides a simple http command
that allows for sending arbitrary HTTP requests using a simple
and natural syntax, and displays colorized output. HTTPie can be
used for testing, debugging, and generally interacting with HTTP
servers.
</longdescription>
<upstream>
<bugs-to>https://github.com/httpie/httpie/issues</bugs-to>
<changelog>https://raw.githubusercontent.com/httpie/httpie/master/CHANGELOG.md</changelog>
<doc>https://httpie.io/docs</doc>
<remote-id type="github">httpie/httpie</remote-id>
<remote-id type="pypi">httpie</remote-id>
</upstream>
</pkgmetadata>

View File

@ -0,0 +1,68 @@
# HTTPie on Void Linux
Welcome to the documentation about **packaging HTTPie for Void Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Void Linux, then you can find them on [that page](https://httpie.io/docs#void-linux).
- If you are looking for technical information about the HTTPie packaging on Void Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Void Linux.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/void-linux/void-packages/blob/master/srcpkgs/httpie/template) ([example](https://github.com/void-linux/void-packages/pull/32905)).
- The commit message must be `httpie: update to XXX.`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull voidlinux/voidlinux
docker run -it --rm voidlinux/voidlinux
```
From inside the container:
```bash
# Sync and upgrade once, assume error comes from xbps update
xbps-install -Syu
# Install tools
xbps-install -y git xtools file util-linux binutils bsdtar coreutils
# Clone
git clone --depth=1 git://github.com/void-linux/void-packages.git void-packages-src
cd void-packages-src
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-void/template \
-o srcpkgs/httpie/template
# Check the package
xlint srcpkgs/httpie/template
# Link / to /masterdir
ln -s / masterdir
# Enable ethereal chroot-style
export XBPS_ALLOW_CHROOT_BREAKOUT=yes
./xbps-src binary-bootstrap
./xbps-src chroot
# Build the package
cd void-packages
export SOURCE_DATE_EPOCH=0
./xbps-src pkg httpie
# Install the package
xbps-install --repository=hostdir/binpkgs httpie
# And finally test it!
http --version
https --version
```

View File

@ -0,0 +1,28 @@
# Template file for 'httpie'
pkgname=httpie
version=2.5.0
revision=1
build_style=python3-module
hostmakedepends="python3-setuptools"
depends="python3-setuptools python3-requests python3-requests-toolbelt
python3-Pygments python3-pysocks python3-defusedxml"
short_desc="Human-friendly command line HTTP client"
maintainer="Mickaël Schoentgen <mickael@apible.io>"
license="BSD-3-Clause"
homepage="https://httpie.io/"
changelog="https://raw.githubusercontent.com/httpie/httpie/${version}/CHANGELOG.md"
distfiles="https://github.com/httpie/httpie/archive/${version}.tar.gz"
checksum=66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea
make_check=no # needs pytest_httpbin which is not packaged
post_install() {
vcompletion extras/httpie-completion.bash bash http
vcompletion extras/httpie-completion.fish fish http
vlicense LICENSE
}
python3-httpie_package() {
build_style=meta
short_desc+=" (transitional dummy package)"
depends="httpie>=${version}_${revision}"
}

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8::et:sw=4:ts=4:sts=4
PortSystem 1.0
PortGroup github 1.0
PortGroup python 1.0
github.setup httpie httpie 2.5.0
maintainers {g5pw @g5pw} openmaintainer
categories net
description HTTPie is a command line HTTP client, a user-friendly cURL replacement.
long_description HTTPie (pronounced aych-tee-tee-pie) is a command line HTTP \
client. Its goal is to make CLI interaction with web \
services as human-friendly as possible. It provides a simple \
http command that allows for sending arbitrary HTTP requests \
using a simple and natural syntax, and displays colorized \
responses. HTTPie can be used for testing, debugging, and \
generally interacting with HTTP servers.
platforms darwin
license BSD
homepage https://httpie.io/
variant python36 conflicts python37 python38 python39 description "Use Python 3.6" {}
variant python37 conflicts python36 python38 python39 description "Use Python 3.7" {}
variant python38 conflicts python36 python37 python39 description "Use Python 3.8" {}
variant python39 conflicts python36 python37 python38 description "Use Python 3.9" {}
if {[variant_isset python36]} {
python.default_version 36
} elseif {[variant_isset python37]} {
python.default_version 37
} elseif {[variant_isset python39]} {
python.default_version 39
} else {
default_variants +python38
python.default_version 38
}
depends_lib-append port:py${python.version}-requests \
port:py${python.version}-requests-toolbelt \
port:py${python.version}-pygments \
port:py${python.version}-socks \
port:py${python.version}-defusedxml
checksums rmd160 88d227d52199c232c0ddf704a219d1781b1e77ee \
sha256 00c4b7bbe7f65abe1473f37b39d9d9f8f53f44069a430ad143a404c01c2179fc \
size 1105185
python.link_binaries_suffix

View File

@ -0,0 +1,40 @@
# HTTPie on MacPorts
Welcome to the documentation about **packaging HTTPie for MacPorts**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on MacPorts, then you can find them on [that page](https://httpie.io/docs#macports).
- If you are looking for technical information about the HTTPie packaging on MacPorts, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for MacPorts.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/macports/macports-ports/blob/master/net/httpie/Portfile) ([example](https://github.com/macports/macports-ports/pull/12167)).
- Here is how to calculate the size and checksums (replace `2.5.0` with the correct version):
```bash
# Download the archive
$ wget https://api.github.com/repos/httpie/httpie/tarball/2.5.0
# Size
$ stat --printf="%s\n" 2.5.0
1105185
# Checksums
$ openssl dgst -rmd160 2.5.0
RIPEMD160(2.5.0)= 88d227d52199c232c0ddf704a219d1781b1e77ee
$ openssl dgst -sha256 2.5.0
SHA256(2.5.0)= 00c4b7bbe7f65abe1473f37b39d9d9f8f53f44069a430ad143a404c01c2179fc
```
- The commit message must be `httpie: update to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
:construction: Work in progress.

View File

@ -0,0 +1,51 @@
# HTTPie on Snapcraft
Welcome to the documentation about **packaging HTTPie for Snapcraft**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Snapcraft, then you can find them on [that page](https://httpie.io/docs#snapcraft-linux) ([that one](https://httpie.io/docs#snapcraft-macos) for macOS).
- If you are looking for technical information about the HTTPie packaging on Snapcraft, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Snapcraft. They apply to Snapcraft on Linux, macOS, and Windows.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Trigger a new [build](https://snapcraft.io/httpie/builds), then [promote it](https://snapcraft.io/httpie/releases). If more management is needed: [revisions supervision](https://dashboard.snapcraft.io/snaps/httpie/revisions/).
## Hacking
Launch the docker image:
```bash
docker pull ubuntu/latest
docker run -it --rm ubuntu/latest
```
From inside the container:
```bash
# Clone
git clone --depth=1 https://github.com/httpie/httpie.git
cd httpie
# Build
export SNAPCRAFT_BUILD_ENVIRONMENT_CPU=8
export SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=16G
snapcraft --debug
# Install
sudo snap install --dangerous httpie_XXX_amd64.snap
# Test
httpie.http --version
httpie.https --version
# Auto-aliases cannot be tested when installing a snap outside the store.
# http --version
# https --version
# Remove
sudo snap remove httpie
```

View File

@ -0,0 +1,54 @@
# HTTPie on Spack
Welcome to the documentation about **packaging HTTPie for Spack**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Spack, then you can find them on [that page](https://httpie.io/docs#spack-linux) ([that one](https://httpie.io/docs#spack-macos) for macOS).
- If you are looking for technical information about the HTTPie packaging on Spack, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Spack. They apply to Spack on Linux, and macOS.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/httpie/package.py) ([example](https://github.com/spack/spack/pull/25888)).
- The commit message must be `httpie: add vXXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull spack/centos7
docker run -it --rm spack/centos7
```
From inside the container:
```bash
# Clone
git clone --depth=1 https://github.com/spack/spack.git
cd spack
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/spack/package.py \
-o var/spack/repos/builtin/packages/httpie/package.py
# Check the package
spack spec httpie
# Check available versions (it should show the new version)
spack versions httpie
# Install the package
spack install httpie@XXX
spack load httpie
# And test it!
http --version
https --version
```

View File

@ -0,0 +1,32 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class Httpie(PythonPackage):
"""Modern command line HTTP client."""
homepage = "https://httpie.io/"
pypi = "httpie/httpie-2.5.0.tar.gz"
version('2.5.0', sha256='fe6a8bc50fb0635a84ebe1296a732e39357c3e1354541bf51a7057b4877e47f9')
version('0.9.9', sha256='f1202e6fa60367e2265284a53f35bfa5917119592c2ab08277efc7fffd744fcb')
version('0.9.8', sha256='515870b15231530f56fe2164190581748e8799b66ef0fe36ec9da3396f0df6e1')
variant('socks', default=True,
description='Enable SOCKS proxy support')
depends_on('py-setuptools', type=('build', 'run'))
depends_on('py-defusedxml', type=('build', 'run'))
depends_on('py-pygments', type=('build', 'run'))
depends_on('py-requests', type=('build', 'run'))
depends_on('py-requests-toolbelt', type=('build', 'run'))
depends_on('py-pysocks', type=('build', 'run'), when="+socks")
# Concretization problem breaks this. Unconditional for now...
# https://github.com/spack/spack/issues/3628
# depends_on('py-argparse@1.2.1:', type=('build', 'run'),
# when='^python@:2.6,3.0:3.1')
depends_on('py-argparse@1.2.1:', type=('build', 'run'), when='^python@:2.6')

View File

@ -0,0 +1,45 @@
# HTTPie on Chocolatey
Welcome to the documentation about **packaging HTTPie for Chocolatey**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Chocolatey, then you can find them on [that page](https://httpie.io/docs#chocolatey).
- If you are looking for technical information about the HTTPie packaging on Chocolatey, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Chocolatey.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
After having successfully [built and tested](#hacking) the package, push it:
```bash
# Replace 2.5.0 with the correct version
choco push httpie.2.5.0.nupkg -s https://push.chocolatey.org/ --api-key=API_KEY
```
## Hacking
```bash
# Clone
git clone --depth=1 https://github.com/httpie/httpie.git
cd httpie/docs/packaging/windows-chocolatey
# Build
choco pack
# Check metadata
choco info httpie -s .
# Install
choco install httpie -y -dv -s "'.;https://community.chocolatey.org/api/v2/'"
# Test
http --version
https --version
# Remove
choco uninstall -y httpie
```

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>httpie</id>
<version>2.5.0</version>
<summary>Modern, user-friendly command-line HTTP client for the API era.</summary>
<description>
HTTPie *aitch-tee-tee-pie* is a user-friendly command-line HTTP client for the API era.
It comes with JSON support, syntax highlighting, persistent sessions, wget-like downloads, plugins, and more.
The project's goal is to make CLI interaction with web services as human-friendly as possible. HTTPie is designed for testing, debugging, and generally interacting with APIs and HTTP servers.
The `http` and `https` commands allow for creating and sending arbitrary HTTP requests. They use simple and natural syntax and provide formatted and colorized output.
Main features:
- Built-in JSON support
- Colorized and formatted terminal output
- Sensible defaults for the API era
- Persistent sessions
- Forms and file uploads
- HTTPS, proxies, and authentication support
- Support for arbitrary request data and headers
- Wget-like downloads
- Extensions API
- Expressive and intuitive syntax
- Linux, macOS, Windows, and FreeBSD support
- All that and more in 2 simple commands: `http` + `https`
</description>
<title>HTTPie</title>
<authors>HTTPie</authors>
<owners>Tiger-222</owners>
<copyright>2012-2021 Jakub Roztocil</copyright>
<licenseUrl>https://raw.githubusercontent.com/httpie/httpie/master/LICENSE</licenseUrl>
<iconUrl>https://pie-assets.s3.eu-central-1.amazonaws.com/LogoIcons/GB.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes>See the [changelog](https://github.com/httpie/httpie/blob/2.5.0/CHANGELOG.md).</releaseNotes>
<tags>httpie http https rest api client curl python ssl cli foss oss url</tags>
<projectUrl>https://httpie.io</projectUrl>
<packageSourceUrl>https://github.com/httpie/httpie</packageSourceUrl>
<projectSourceUrl>https://github.com/httpie/httpie</projectSourceUrl>
<docsUrl>https://httpie.io/docs</docsUrl>
<bugTrackerUrl>https://github.com/httpie/httpie/issues</bugTrackerUrl>
<dependencies>
<dependency id="python3" version="3.6" />
</dependencies>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>

View File

@ -0,0 +1,6 @@
$ErrorActionPreference = 'Stop';
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$nuspecPath = "$(Join-Path (Split-Path -parent $toolsDir) ($env:ChocolateyPackageName + ".nuspec"))"
[XML]$nuspec = Get-Content $nuspecPath
$pipVersion = $nuspec.package.metadata.version
py -m pip install "$($env:ChocolateyPackageName)==$($pipVersion)" --disable-pip-version-check

View File

@ -0,0 +1,2 @@
$ErrorActionPreference = 'Stop';
py -m pip uninstall -y $env:ChocolateyPackageName --disable-pip-version-check

View File

@ -1,11 +1,8 @@
#!/usr/bin/env bash
_http_complete() {
local cur_word=${COMP_WORDS[COMP_CWORD]}
local prev_word=${COMP_WORDS[COMP_CWORD - 1]}
if [[ "$cur_word" == -* ]]; then
if [[ "$cur_word" == -* ]]; then
_http_complete_options "$cur_word"
fi
}
@ -18,6 +15,6 @@ _http_complete_options() {
-v --verbose -h --headers -b --body -S --stream -o --output -d --download
-c --continue --session --session-read-only -a --auth --auth-type --proxy
--follow --verify --cert --cert-key --timeout --check-status --ignore-stdin
--help --version --traceback --debug"
--help --version --traceback --debug --raw"
COMPREPLY=( $( compgen -W "$options" -- "$cur_word" ) )
}

View File

@ -1,59 +1,137 @@
function __fish_httpie_auth_types
echo "basic"\t"Basic HTTP auth"
echo "digest"\t"Digest HTTP auth"
end
function __fish_httpie_styles
echo "autumn"
echo "borland"
echo "bw"
echo "colorful"
echo "default"
echo "emacs"
echo "friendly"
echo "fruity"
echo "igor"
echo "manni"
echo "monokai"
echo "murphy"
echo "native"
echo "paraiso-dark"
echo "paraiso-light"
echo "pastie"
echo "perldoc"
echo "rrt"
echo "solarized"
echo "tango"
echo "trac"
echo "vim"
echo "vs"
echo "xcode"
echo "
abap
algol
algol_nu
arduino
auto
autumn
borland
bw
colorful
default
emacs
friendly
fruity
gruvbox-dark
gruvbox-light
igor
inkpot
lovelace
manni
material
monokai
murphy
native
paraiso-dark
paraiso-light
pastie
perldoc
rainbow_dash
rrt
sas
solarized
solarized-dark
solarized-light
stata
stata-dark
stata-light
tango
trac
vim
vs
xcode
zenburn"
end
complete -x -c http -s s -l style -d 'Output coloring style (default is "monokai")' -A -a '(__fish_httpie_styles)'
complete -c http -s f -l form -d 'Data items from the command line are serialized as form fields'
complete -c http -s j -l json -d '(default) Data items from the command line are serialized as a JSON object'
complete -x -c http -l pretty -d 'Controls output processing' -a "all colors format none" -A
complete -x -c http -s p -l print -d 'String specifying what the output should contain'
complete -c http -s v -l verbose -d 'Print the whole request as well as the response'
complete -c http -s h -l headers -d 'Print only the response headers'
complete -c http -s b -l body -d 'Print only the response body'
complete -c http -s S -l stream -d 'Always stream the output by line'
complete -c http -s o -l output -d 'Save output to FILE'
complete -c http -s d -l download -d 'Do not print the response body to stdout'
complete -c http -s c -l continue -d 'Resume an interrupted download'
complete -x -c http -l session -d 'Create, or reuse and update a session'
complete -x -c http -s a -l auth -d 'If only the username is provided (-a username), HTTPie will prompt for the password'
complete -x -c http -l auth-type -d 'The authentication mechanism to be used' -a '(__fish_httpie_auth_types)' -A
complete -x -c http -l proxy -d 'String mapping protocol to the URL of the proxy'
complete -c http -l follow -d 'Allow full redirects'
complete -x -c http -l verify -d 'SSL cert verification'
complete -c http -l cert -d 'SSL cert'
complete -c http -l cert-key -d 'Private SSL cert key'
complete -x -c http -l timeout -d 'Connection timeout in seconds'
complete -c http -l check-status -d 'Error with non-200 HTTP status code'
complete -c http -l ignore-stdin -d 'Do not attempt to read stdin'
complete -c http -l help -d 'Show help'
complete -c http -l version -d 'Show version'
complete -c http -l traceback -d 'Prints exception traceback should one occur'
complete -c http -l debug -d 'Show debugging information'
function __fish_httpie_auth_types
echo -e "basic\tBasic HTTP auth"
echo -e "digest\tDigest HTTP auth"
end
function __fish_http_verify_options
echo -e "yes\tEnable cert verification"
echo -e "no\tDisable cert verification"
end
# Predefined Content Types
complete -c http -s j -l json -d 'Data items are serialized as a JSON object'
complete -c http -s f -l form -d 'Data items are serialized as form fields'
complete -c http -l multipart -d 'Always sends a multipart/form-data request'
complete -c http -l boundary -x -d 'Custom boundary string for multipart/form-data requests'
complete -c http -l raw -x -d 'Pass raw request data without extra processing'
# Content Processing Options
complete -c http -s x -l compress -d 'Content compressed with Deflate algorithm'
# Output Processing
complete -c http -l pretty -xa "all colors format none" -d 'Controls output processing'
complete -c http -s s -l style -xa "(__fish_httpie_styles)" -d 'Output coloring style'
complete -c http -l unsorted -d 'Disables all sorting while formatting output'
complete -c http -l sorted -d 'Re-enables all sorting options while formatting output'
complete -c http -l format-options -x -d 'Controls output formatting'
# Output Options
complete -c http -s p -l print -x -d 'String specifying what the output should contain'
complete -c http -s h -l headers -d 'Print only the response headers'
complete -c http -s b -l body -d 'Print only the response body'
complete -c http -s v -l verbose -d 'Print the whole request as well as the response'
complete -c http -l all -d 'Show any intermediary requests/responses'
complete -c http -s P -l history-print -x -d 'The same as --print but applies only to intermediary requests/responses'
complete -c http -s S -l stream -d 'Always stream the response body by line'
complete -c http -s o -l output -F -d 'Save output to FILE'
complete -c http -s d -l download -d 'Download a file'
complete -c http -s c -l continue -d 'Resume an interrupted download'
complete -c http -s q -l quiet -d 'Do not print to stdout or stderr'
# Sessions
complete -c http -l session -F -d 'Create, or reuse and update a session'
complete -c http -l session-read-only -F -d 'Create or read a session without updating it'
# Authentication
complete -c http -s a -l auth -x -d 'Username and password for authentication'
complete -c http -s A -l auth-type -xa "(__fish_httpie_auth_types)" -d 'The authentication mechanism to be used'
complete -c http -l ignore-netrc -d 'Ignore credentials from .netrc'
# Network
complete -c http -l offline -d 'Build the request and print it but don\'t actually send it'
complete -c http -l proxy -x -d 'String mapping protocol to the URL of the proxy'
complete -c http -s F -l follow -d 'Follow 30x Location redirects'
complete -c http -l max-redirects -x -d 'Set maximum number of redirects'
complete -c http -l max-headers -x -d 'Maximum number of response headers to be read before giving up'
complete -c http -l timeout -x -d 'Connection timeout in seconds'
complete -c http -l check-status -d 'Error with non-200 HTTP status code'
complete -c http -l path-as-is -d 'Bypass dot segment URL squashing'
complete -c http -l chunked -d ''
# SSL
complete -c http -l verify -xa "(__fish_http_verify_options)" -d 'Enable/disable cert verification'
complete -c http -l ssl -x -d 'Desired protocol version to use'
complete -c http -l ciphers -x -d 'String in the OpenSSL cipher list format'
complete -c http -l cert -F -d 'Client side SSL certificate'
complete -c http -l cert-key -F -d 'Private key to use with SSL'
# Troubleshooting
complete -c http -s I -l ignore-stdin -d 'Do not attempt to read stdin'
complete -c http -l help -d 'Show help'
complete -c http -l version -d 'Show version'
complete -c http -l traceback -d 'Prints exception traceback should one occur'
complete -c http -l default-scheme -x -d 'The default scheme to use'
complete -c http -l debug -d 'Show debugging output'

View File

@ -1,68 +0,0 @@
# The latest Homebrew formula as submitted to Homebrew/homebrew-core.
# Only useful for testing until it gets accepted by homebrew maintainers.
# (It will need to be updated from the repo version before next release.)
#
# https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpie.rb
#
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/37/6c/0d050f49e3b2bac589367d0c3aee9c078e23c6914b0210ffc0117218bdaf/httpie-2.2.0.tar.gz"
sha256 "31ac28088ee6a0b6f3ba7a53379000c4d1910c1708c9ff768f84b111c14405a0"
head "https://github.com/jakubroztocil/httpie.git"
bottle do
cellar :any_skip_relocation
sha256 "25f0e58f81a2cdd9cba772f07d67591533b4b31a2b970a356701aa046d4d9638" => :catalina
sha256 "be158ebb4cfd327ebea02f7b8b8d63d093e474cd303eafff4a2b56b0611983a2" => :mojave
sha256 "f331edb94183bfc5fa9de4b4abf148cc91a3a8b3c0e24cc1f5e6b0a4172dd34d" => :high_sierra
end
depends_on "python@3.8"
resource "Pygments" do
url "https://files.pythonhosted.org/packages/6e/4d/4d2fe93a35dfba417311a4ff627489a947b01dc0cc377a3673c00cf7e4b2/Pygments-2.6.1.tar.gz"
sha256 "647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"
end
resource "requests" do
url "https://files.pythonhosted.org/packages/da/67/672b422d9daf07365259958912ba533a0ecab839d4084c487a5fe9a5405f/requests-2.24.0.tar.gz"
sha256 "b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"
end
resource "certifi" do
url "https://files.pythonhosted.org/packages/b4/19/53433f37a31543364c8676f30b291d128cdf4cd5b31b755b7890f8e89ac8/certifi-2020.4.5.2.tar.gz"
sha256 "5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1"
end
resource "urllib3" do
url "https://files.pythonhosted.org/packages/05/8c/40cd6949373e23081b3ea20d5594ae523e681b6f472e600fbc95ed046a36/urllib3-1.25.9.tar.gz"
sha256 "3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"
end
resource "idna" do
url "https://files.pythonhosted.org/packages/cb/19/57503b5de719ee45e83472f339f617b0c01ad75cba44aba1e4c97c2b0abd/idna-2.9.tar.gz"
sha256 "7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"
end
resource "chardet" do
url "https://files.pythonhosted.org/packages/fc/bb/a5768c230f9ddb03acc9ef3f0d4a3cf93462473795d18e9535498c8f929d/chardet-3.0.4.tar.gz"
sha256 "84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
end
resource "PySocks" do
url "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz"
sha256 "3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
end
def install
virtualenv_install_with_resources
end
test do
raw_url = "https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Formula/httpie.rb"
assert_match "PYTHONPATH", shell_output("#{bin}/http --ignore-stdin #{raw_url}")
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 681 KiB

View File

@ -3,6 +3,6 @@ HTTPie: command-line HTTP client for the API era.
"""
__version__ = '2.3.0-dev'
__version__ = '2.6.0.dev0'
__author__ = 'Jakub Roztocil'
__licence__ = 'BSD'

View File

@ -1,20 +1,19 @@
#!/usr/bin/env python
"""The main entry point. Invoke as `http' or `python -m httpie'.
"""
import sys
def main():
try:
from .core import main
from httpie.core import main
exit_status = main()
except KeyboardInterrupt:
from httpie.status import ExitStatus
exit_status = ExitStatus.ERROR_CTRL_C
sys.exit(exit_status.value)
return exit_status.value
if __name__ == '__main__':
main()
if __name__ == '__main__': # pragma: nocover
import sys
sys.exit(main())

View File

@ -9,23 +9,23 @@ from urllib.parse import urlsplit
from requests.utils import get_netrc_auth
from httpie.cli.argtypes import (
from .argtypes import (
AuthCredentials, KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS,
parse_auth,
parse_format_options,
)
from httpie.cli.constants import (
from .constants import (
HTTP_GET, HTTP_POST, OUTPUT_OPTIONS, OUTPUT_OPTIONS_DEFAULT,
OUTPUT_OPTIONS_DEFAULT_OFFLINE, OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED,
OUT_RESP_BODY, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY, RequestType,
SEPARATOR_CREDENTIALS,
SEPARATOR_GROUP_ALL_ITEMS, SEPARATOR_GROUP_DATA_ITEMS, URL_SCHEME_RE,
)
from httpie.cli.exceptions import ParseError
from httpie.cli.requestitems import RequestItems
from httpie.context import Environment
from httpie.plugins.registry import plugin_manager
from httpie.utils import ExplicitNullAuth, get_content_type
from .exceptions import ParseError
from .requestitems import RequestItems
from ..context import Environment
from ..plugins.registry import plugin_manager
from ..utils import ExplicitNullAuth, get_content_type
class HTTPieHelpFormatter(RawDescriptionHelpFormatter):
@ -64,6 +64,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.env = None
self.args = None
self.has_stdin_data = False
self.has_input_data = False
# noinspection PyMethodOverriding
def parse_args(
@ -74,6 +75,8 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
) -> argparse.Namespace:
self.env = env
self.args, no_options = super().parse_known_args(args, namespace)
if self.args.prompt:
return self.args
if self.args.debug:
self.args.traceback = True
self.has_stdin_data = (
@ -81,6 +84,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
and not self.args.ignore_stdin
and not self.env.stdin_isatty
)
self.has_input_data = self.has_stdin_data or self.args.raw is not None
# Arguments processing and environment setup.
self._apply_no_options(no_options)
self._process_request_type()
@ -91,11 +95,14 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self._process_format_options()
self._guess_method()
self._parse_items()
if self.has_stdin_data:
self._body_from_file(self.env.stdin)
self._process_url()
self._process_auth()
if self.args.raw is not None:
self._body_from_input(self.args.raw)
elif self.has_stdin_data:
self._body_from_file(self.env.stdin)
if self.args.compress:
# TODO: allow --compress with --chunked / --multipart
if self.args.chunked:
@ -171,7 +178,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.args.output_file.seek(0)
try:
self.args.output_file.truncate()
except IOError as e:
except OSError as e:
if e.errno == errno.EINVAL:
# E.g. /dev/null on Linux.
pass
@ -279,21 +286,34 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
invalid.append(option)
if invalid:
msg = 'unrecognized arguments: %s'
self.error(msg % ' '.join(invalid))
self.error(f'unrecognized arguments: {" ".join(invalid)}')
def _body_from_file(self, fd):
"""There can only be one source of request data.
"""Read the data from a file-like object.
Bytes are always read.
"""
if self.args.data or self.args.files:
self.error('Request body (from stdin or a file) and request '
self._ensure_one_data_source(self.args.data, self.args.files)
self.args.data = getattr(fd, 'buffer', fd)
def _body_from_input(self, data):
"""Read the data from the CLI.
"""
self._ensure_one_data_source(self.has_stdin_data, self.args.data,
self.args.files)
self.args.data = data.encode()
def _ensure_one_data_source(self, *other_sources):
"""There can only be one source of input request data.
"""
if any(other_sources):
self.error('Request body (from stdin, --raw or a file) and request '
'data (key=value) cannot be mixed. Pass '
'--ignore-stdin to let key/value take priority. '
'See https://httpie.org/doc#scripting for details.')
self.args.data = getattr(fd, 'buffer', fd)
'See https://httpie.io/docs#scripting for details.')
def _guess_method(self):
"""Set `args.method` if not specified to either POST or GET
@ -303,7 +323,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
if self.args.method is None:
# Invoked as `http URL'.
assert not self.args.request_items
if self.has_stdin_data:
if self.has_input_data:
self.args.method = HTTP_POST
else:
self.args.method = HTTP_GET
@ -327,7 +347,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.args.url = self.args.method
# Infer the method
has_data = (
self.has_stdin_data
self.has_input_data
or any(
item.sep in SEPARATOR_GROUP_DATA_ITEMS
for item in self.args.request_items)
@ -358,13 +378,17 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
if self.args.files and not self.args.form:
# `http url @/path/to/file`
file_fields = list(self.args.files.keys())
if file_fields != ['']:
self.error(
'Invalid file fields (perhaps you meant --form?): %s'
% ','.join(file_fields))
request_file = None
for key, file in self.args.files.items():
if key != '':
self.error(
'Invalid file fields (perhaps you meant --form?):'
f' {",".join(self.args.files.keys())}')
if request_file is not None:
self.error("Can't read request from multiple files")
request_file = file
fn, fd, ct = self.args.files['']
fn, fd, ct = request_file
self.args.files = {}
self._body_from_file(fd)
@ -384,10 +408,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
def check_options(value, option):
unknown = set(value) - OUTPUT_OPTIONS
if unknown:
self.error('Unknown output options: {0}={1}'.format(
option,
','.join(unknown)
))
self.error(f'Unknown output options: {option}={",".join(unknown)}')
if self.args.verbose:
self.args.all = True
@ -438,7 +459,8 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.error('--continue requires --output to be specified')
def _process_format_options(self):
format_options = self.args.format_options or []
parsed_options = PARSED_DEFAULT_FORMAT_OPTIONS
for options_group in self.args.format_options or []:
for options_group in format_options:
parsed_options = parse_format_options(options_group, defaults=parsed_options)
self.args.format_options = parsed_options

View File

@ -5,8 +5,8 @@ import sys
from copy import deepcopy
from typing import List, Optional, Union
from httpie.cli.constants import DEFAULT_FORMAT_OPTIONS, SEPARATOR_CREDENTIALS
from httpie.sessions import VALID_SESSION_NAME_PATTERN
from .constants import DEFAULT_FORMAT_OPTIONS, SEPARATOR_CREDENTIALS
from ..sessions import VALID_SESSION_NAME_PATTERN
class KeyValueArg:
@ -180,8 +180,8 @@ def readable_file_arg(filename):
try:
with open(filename, 'rb'):
return filename
except IOError as ex:
raise argparse.ArgumentTypeError(f'{filename}: {ex.args[1]}')
except OSError as ex:
raise argparse.ArgumentTypeError(f'{ex.filename}: {ex.strerror}')
def parse_format_options(s: str, defaults: Optional[dict]) -> dict:
@ -242,3 +242,19 @@ PARSED_DEFAULT_FORMAT_OPTIONS = parse_format_options(
s=','.join(DEFAULT_FORMAT_OPTIONS),
defaults=None,
)
def response_charset_type(encoding: str) -> str:
try:
''.encode(encoding)
except LookupError:
raise argparse.ArgumentTypeError(
f'{encoding!r} is not a supported encoding')
return encoding
def response_mime_type(mime_type: str) -> str:
if mime_type.count('/') != 1:
raise argparse.ArgumentTypeError(
f'{mime_type!r} doesnt look like a mime type; use type/subtype')
return mime_type

View File

@ -5,15 +5,6 @@ import enum
import re
# TODO: Use MultiDict for headers once added to `requests`.
# <https://github.com/jakubroztocil/httpie/issues/130>
# ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
# <https://tools.ietf.org/html/rfc3986#section-3.1>
from enum import Enum
URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)
HTTP_POST = 'POST'
@ -99,6 +90,8 @@ DEFAULT_FORMAT_OPTIONS = [
'json.format:true',
'json.indent:4',
'json.sort_keys:true',
'xml.format:true',
'xml.indent:2',
]
SORTED_FORMAT_OPTIONS = [
'headers.sort:true',

View File

@ -2,16 +2,16 @@
CLI arguments definition.
"""
from argparse import (FileType, OPTIONAL, SUPPRESS, ZERO_OR_MORE)
from argparse import FileType, OPTIONAL, SUPPRESS, ZERO_OR_MORE
from textwrap import dedent, wrap
from httpie import __doc__, __version__
from httpie.cli.argparser import HTTPieArgumentParser
from httpie.cli.argtypes import (
from .. import __doc__, __version__
from .argparser import HTTPieArgumentParser
from .argtypes import (
KeyValueArgType, SessionNameValidator,
readable_file_arg,
readable_file_arg, response_charset_type, response_mime_type,
)
from httpie.cli.constants import (
from .constants import (
DEFAULT_FORMAT_OPTIONS, OUTPUT_OPTIONS,
OUTPUT_OPTIONS_DEFAULT, OUT_REQ_BODY, OUT_REQ_HEAD,
OUT_RESP_BODY, OUT_RESP_HEAD, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY,
@ -19,25 +19,25 @@ from httpie.cli.constants import (
SORTED_FORMAT_OPTIONS_STRING,
UNSORTED_FORMAT_OPTIONS_STRING,
)
from httpie.output.formatters.colors import (
from ..output.formatters.colors import (
AUTO_STYLE, AVAILABLE_STYLES, DEFAULT_STYLE,
)
from httpie.plugins.builtin import BuiltinAuthPlugin
from httpie.plugins.registry import plugin_manager
from httpie.sessions import DEFAULT_SESSIONS_DIR
from httpie.ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS
from ..plugins.builtin import BuiltinAuthPlugin
from ..plugins.registry import plugin_manager
from ..sessions import DEFAULT_SESSIONS_DIR
from ..ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS
parser = HTTPieArgumentParser(
prog='http',
description='%s <https://httpie.org>' % __doc__.strip(),
description=f'{__doc__.strip()} <https://httpie.io>',
epilog=dedent('''
For every --OPTION there is also a --no-OPTION that reverts OPTION
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/jakubroztocil/httpie/issues
https://github.com/httpie/httpie/issues
'''),
)
@ -73,6 +73,7 @@ positional.add_argument(
positional.add_argument(
dest='url',
metavar='URL',
nargs=OPTIONAL,
help='''
The scheme defaults to 'http://' if the URL does not include one.
(You can override this with: --default-scheme=https)
@ -96,7 +97,7 @@ positional.add_argument(
':' HTTP headers:
Referer:http://httpie.org Cookie:foo=bar User-Agent:bacon/1.0
Referer:https://httpie.io Cookie:foo=bar User-Agent:bacon/1.0
'==' URL parameters to be appended to the request URI:
@ -185,6 +186,25 @@ content_type.add_argument(
'''
)
content_type.add_argument(
'--raw',
help='''
This option allows you to pass raw request data without extra processing
(as opposed to the structured request items syntax):
$ http --raw='data' pie.dev/post
You can achieve the same by piping the data via stdin:
$ echo data | http pie.dev/post
Or have HTTPie load the raw data from a file:
$ http pie.dev/post @data.txt
'''
)
#######################################################################
@ -233,11 +253,11 @@ output_processing.add_argument(
dest='style',
metavar='STYLE',
default=DEFAULT_STYLE,
choices=AVAILABLE_STYLES,
choices=sorted(AVAILABLE_STYLES),
help='''
Output coloring style (default is "{default}"). It can be One of:
{available_styles}
{available_styles}
The "{auto_style}" style follows your terminal's ANSI color styles.
@ -248,7 +268,7 @@ output_processing.add_argument(
'''.format(
default=DEFAULT_STYLE,
available_styles='\n'.join(
'{0}{1}'.format(8 * ' ', line.strip())
f' {line.strip()}'
for line in wrap(', '.join(sorted(AVAILABLE_STYLES)), 60)
).strip(),
auto_style=AUTO_STYLE,
@ -290,6 +310,31 @@ output_processing.add_argument(
'''
)
output_processing.add_argument(
'--response-charset',
metavar='ENCODING',
type=response_charset_type,
help='''
Override the response encoding for terminal display purposes, e.g.:
--response-charset=utf8
--response-charset=big5
'''
)
output_processing.add_argument(
'--response-mime',
metavar='MIME_TYPE',
type=response_mime_type,
help='''
Override the response mime type for coloring and formatting for the terminal, e.g.:
--response-mime=application/json
--response-mime=text/xml
'''
)
output_processing.add_argument(
'--format-options',
@ -311,7 +356,7 @@ output_processing.add_argument(
'''.format(
option_list='\n'.join(
(8 * ' ') + option for option in DEFAULT_FORMAT_OPTIONS).strip()
f' {option}' for option in DEFAULT_FORMAT_OPTIONS).strip()
)
)
@ -364,12 +409,12 @@ output_options.add_argument(
'--verbose', '-v',
dest='verbose',
action='store_true',
help='''
help=f'''
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}
It's a shortcut for: --all --print={''.join(OUTPUT_OPTIONS)}
'''.format(''.join(OUTPUT_OPTIONS))
'''
)
output_options.add_argument(
'--all',
@ -543,7 +588,7 @@ auth.add_argument(
name=plugin.name,
package=(
'' if issubclass(plugin, BuiltinAuthPlugin)
else ' (provided by %s)' % plugin.package_name
else f' (provided by {plugin.package_name})'
),
description=(
'' if not plugin.description else
@ -667,9 +712,11 @@ network.add_argument(
'--chunked',
default=False,
action='store_true',
help="""
help='''
Enable streaming via chunked transfer encoding.
The Transfer-Encoding header is set to chunked.
"""
'''
)
#######################################################################
@ -690,7 +737,7 @@ ssl.add_argument(
ssl.add_argument(
'--ssl',
dest='ssl_version',
choices=list(sorted(AVAILABLE_SSL_VERSION_ARG_MAPPING.keys())),
choices=sorted(AVAILABLE_SSL_VERSION_ARG_MAPPING.keys()),
help='''
The desired protocol version to use. This will default to
SSL v2.3 which will negotiate the highest protocol that both
@ -794,3 +841,12 @@ troubleshooting.add_argument(
'''
)
troubleshooting.add_argument(
'--prompt',
action='store_true',
default=False,
help='''
Start the shell!
'''
)

View File

@ -1,22 +1,21 @@
import os
from io import BytesIO
from typing import Callable, Dict, IO, List, Optional, Tuple, Union
from httpie.cli.argtypes import KeyValueArg
from httpie.cli.constants import (
from .argtypes import KeyValueArg
from .constants import (
SEPARATORS_GROUP_MULTIPART, SEPARATOR_DATA_EMBED_FILE_CONTENTS,
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
SEPARATOR_DATA_RAW_JSON, SEPARATOR_DATA_STRING, SEPARATOR_FILE_UPLOAD,
SEPARATOR_FILE_UPLOAD_TYPE, SEPARATOR_HEADER, SEPARATOR_HEADER_EMPTY,
SEPARATOR_QUERY_PARAM,
)
from httpie.cli.dicts import (
from .dicts import (
MultipartRequestDataDict, RequestDataDict, RequestFilesDict,
RequestHeadersDict, RequestJSONDataDict,
RequestQueryParamsDict,
)
from httpie.cli.exceptions import ParseError
from httpie.utils import (get_content_type, load_json_preserve_order)
from .exceptions import ParseError
from ..utils import get_content_type, load_json_preserve_order_and_dupe_keys
class RequestItems:
@ -90,13 +89,11 @@ def process_header_arg(arg: KeyValueArg) -> Optional[str]:
def process_empty_header_arg(arg: KeyValueArg) -> str:
if arg.value:
raise ParseError(
'Invalid item "%s" '
'(to specify an empty header use `Header;`)'
% arg.orig
)
return arg.value
if not arg.value:
return arg.value
raise ParseError(
f'Invalid item {arg.orig!r} (to specify an empty header use `Header;`)'
)
def process_query_param_arg(arg: KeyValueArg) -> str:
@ -109,8 +106,8 @@ def process_file_upload_arg(arg: KeyValueArg) -> Tuple[str, IO, str]:
mime_type = parts[1] if len(parts) > 1 else None
try:
f = open(os.path.expanduser(filename), 'rb')
except IOError as e:
raise ParseError('"%s": %s' % (arg.orig, e))
except OSError as e:
raise ParseError(f'{arg.orig!r}: {e}')
return (
os.path.basename(filename),
f,
@ -142,18 +139,17 @@ def load_text_file(item: KeyValueArg) -> str:
try:
with open(os.path.expanduser(path), 'rb') as f:
return f.read().decode()
except IOError as e:
raise ParseError('"%s": %s' % (item.orig, e))
except OSError as e:
raise ParseError(f'{item.orig!r}: {e}')
except UnicodeDecodeError:
raise ParseError(
'"%s": cannot embed the content of "%s",'
' not a UTF8 or ASCII-encoded text file'
% (item.orig, item.value)
f'{item.orig!r}: cannot embed the content of {item.value!r},'
' not a UTF-8 or ASCII-encoded text file'
)
def load_json(arg: KeyValueArg, contents: str) -> JSONType:
try:
return load_json_preserve_order(contents)
return load_json_preserve_order_and_dupe_keys(contents)
except ValueError as e:
raise ParseError('"%s": %s' % (arg.orig, e))
raise ParseError(f'{arg.orig!r}: {e}')

View File

@ -10,21 +10,22 @@ from urllib.parse import urlparse, urlunparse
import requests
# noinspection PyPackageRequirements
import urllib3
from httpie import __version__
from httpie.cli.dicts import RequestHeadersDict
from httpie.plugins.registry import plugin_manager
from httpie.sessions import get_httpie_session
from httpie.ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, HTTPieHTTPSAdapter
from httpie.uploads import (
from . import __version__
from .cli.dicts import RequestHeadersDict
from .encoding import UTF8
from .plugins.registry import plugin_manager
from .sessions import get_httpie_session
from .ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, HTTPieHTTPSAdapter
from .uploads import (
compress_request, prepare_request_body,
get_multipart_data_and_content_type,
)
from httpie.utils import get_expired_cookies, repr_dict
from .utils import get_expired_cookies, repr_dict
urllib3.disable_warnings()
FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded; charset=utf-8'
FORM_CONTENT_TYPE = f'application/x-www-form-urlencoded; charset={UTF8}'
JSON_CONTENT_TYPE = 'application/json'
JSON_ACCEPT = f'{JSON_CONTENT_TYPE}, */*;q=0.5'
DEFAULT_UA = f'HTTPie/{__version__}'
@ -104,9 +105,8 @@ def collect_messages(
**send_kwargs,
)
# noinspection PyProtectedMember
expired_cookies += get_expired_cookies(
headers=response.raw._original_response.msg._headers
response.headers.get('Set-Cookie', '')
)
response_count += 1
@ -134,7 +134,7 @@ def collect_messages(
# noinspection PyProtectedMember
@contextmanager
def max_headers(limit):
# <https://github.com/jakubroztocil/httpie/issues/802>
# <https://github.com/httpie/httpie/issues/802>
# noinspection PyUnresolvedReferences
orig = http.client._MAXHEADERS
http.client._MAXHEADERS = limit or float('Inf')
@ -188,8 +188,8 @@ def finalize_headers(headers: RequestHeadersDict) -> RequestHeadersDict:
# Also, requests raises `InvalidHeader` for leading spaces.
value = value.strip()
if isinstance(value, str):
# See <https://github.com/jakubroztocil/httpie/issues/212>
value = value.encode('utf8')
# See <https://github.com/httpie/httpie/issues/212>
value = value.encode()
final_headers[name] = value
return final_headers
@ -213,11 +213,10 @@ def make_default_headers(args: argparse.Namespace) -> RequestHeadersDict:
def make_send_kwargs(args: argparse.Namespace) -> dict:
kwargs = {
return {
'timeout': args.timeout or None,
'allow_redirects': False,
}
return kwargs
def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
@ -226,7 +225,7 @@ def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
cert = args.cert
if args.cert_key:
cert = cert, args.cert_key
kwargs = {
return {
'proxies': {p.key: p.value for p in args.proxy},
'stream': True,
'verify': {
@ -237,7 +236,6 @@ def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
}.get(args.verify.lower(), args.verify),
'cert': cert,
}
return kwargs
def make_request_kwargs(
@ -279,7 +277,7 @@ def make_request_kwargs(
content_type=args.headers.get('Content-Type'),
)
kwargs = {
return {
'method': args.method.lower(),
'url': args.url,
'headers': headers,
@ -294,8 +292,6 @@ def make_request_kwargs(
'params': args.params.items(),
}
return kwargs
def ensure_path_as_is(orig_url: str, prepped_url: str) -> str:
"""
@ -304,7 +300,7 @@ def ensure_path_as_is(orig_url: str, prepped_url: str) -> str:
untouched because other (welcome) processing on the URL might have
taken place.
<https://github.com/jakubroztocil/httpie/issues/895>
<https://github.com/httpie/httpie/issues/895>
<https://ec.haxx.se/http/http-basics#path-as-is>
@ -320,5 +316,4 @@ def ensure_path_as_is(orig_url: str, prepped_url: str) -> str:
**parsed_prepped._asdict(),
'path': parsed_orig.path,
}
final_url = urlunparse(tuple(final_dict.values()))
return final_url
return urlunparse(tuple(final_dict.values()))

View File

@ -2,3 +2,53 @@ import sys
is_windows = 'win32' in str(sys.platform).lower()
try:
from functools import cached_property
except ImportError:
# Can be removed once we drop Python <3.8 support.
# Taken from `django.utils.functional.cached_property`.
class cached_property:
"""
Decorator that converts a method with a single self argument into a
property cached on the instance.
A cached property can be made out of an existing method:
(e.g. ``url = cached_property(get_absolute_url)``).
The optional ``name`` argument is obsolete as of Python 3.6 and will be
deprecated in Django 4.0 (#30127).
"""
name = None
@staticmethod
def func(instance):
raise TypeError(
'Cannot use cached_property instance without calling '
'__set_name__() on it.'
)
def __init__(self, func, name=None):
self.real_func = func
self.__doc__ = getattr(func, '__doc__')
def __set_name__(self, owner, name):
if self.name is None:
self.name = name
self.func = self.real_func
elif name != self.name:
raise TypeError(
"Cannot assign the same cached_property to two different names "
"(%r and %r)." % (self.name, name)
)
def __get__(self, instance, cls=None):
"""
Call the function and put the return value in instance.__dict__ so that
subsequent attribute access on the instance returns the cached value
instead of calling cached_property.__get__().
"""
if instance is None:
return self
res = instance.__dict__[self.name] = self.func(instance)
return res

View File

@ -1,11 +1,11 @@
import errno
import json
import os
from pathlib import Path
from typing import Union
from httpie import __version__
from httpie.compat import is_windows
from . import __version__
from .compat import is_windows
from .encoding import UTF8
ENV_XDG_CONFIG_HOME = 'XDG_CONFIG_HOME'
@ -72,11 +72,7 @@ class BaseConfigDict(dict):
self.path = path
def ensure_directory(self):
try:
self.path.parent.mkdir(mode=0o700, parents=True)
except OSError as e:
if e.errno != errno.EEXIST:
raise
self.path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
def is_new(self) -> bool:
return not self.path.exists()
@ -84,7 +80,7 @@ class BaseConfigDict(dict):
def load(self):
config_type = type(self).__name__.lower()
try:
with self.path.open('rt') as f:
with self.path.open(encoding=UTF8) as f:
try:
data = json.load(f)
except ValueError as e:
@ -92,11 +88,12 @@ class BaseConfigDict(dict):
f'invalid {config_type} file: {e} [{self.path}]'
)
self.update(data)
except IOError as e:
if e.errno != errno.ENOENT:
raise ConfigFileError(f'cannot read {config_type} file: {e}')
except FileNotFoundError:
pass
except OSError as e:
raise ConfigFileError(f'cannot read {config_type} file: {e}')
def save(self, fail_silently=False):
def save(self):
self['__meta__'] = {
'httpie': __version__
}
@ -114,18 +111,7 @@ class BaseConfigDict(dict):
sort_keys=True,
ensure_ascii=True,
)
try:
self.path.write_text(json_string + '\n')
except IOError:
if not fail_silently:
raise
def delete(self):
try:
self.path.unlink()
except OSError as e:
if e.errno != errno.ENOENT:
raise
self.path.write_text(json_string + '\n', encoding=UTF8)
class Config(BaseConfigDict):

View File

@ -9,10 +9,11 @@ try:
except ImportError:
curses = None # Compiled w/o curses
from httpie.compat import is_windows
from httpie.config import DEFAULT_CONFIG_DIR, Config, ConfigFileError
from .compat import is_windows
from .config import DEFAULT_CONFIG_DIR, Config, ConfigFileError
from .encoding import UTF8
from httpie.utils import repr_dict
from .utils import repr_dict
class Environment:
@ -70,10 +71,10 @@ class Environment:
self._orig_stderr = self.stderr
self._devnull = devnull
# Keyword arguments > stream.encoding > default utf8
# Keyword arguments > stream.encoding > default UTF-8
if self.stdin and self.stdin_encoding is None:
self.stdin_encoding = getattr(
self.stdin, 'encoding', None) or 'utf8'
self.stdin, 'encoding', None) or UTF8
if self.stdout_encoding is None:
actual_stdout = self.stdout
if is_windows:
@ -83,7 +84,7 @@ class Environment:
# noinspection PyUnresolvedReferences
actual_stdout = self.stdout.wrapped
self.stdout_encoding = getattr(
actual_stdout, 'encoding', None) or 'utf8'
actual_stdout, 'encoding', None) or UTF8
def __str__(self):
defaults = dict(type(self).__dict__)
@ -119,10 +120,6 @@ class Environment:
self._devnull = open(os.devnull, 'w+')
return self._devnull
@devnull.setter
def devnull(self, value):
self._devnull = value
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')

View File

@ -8,27 +8,18 @@ import requests
from pygments import __version__ as pygments_version
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.downloads import Downloader
from httpie.output.writer import (
write_message,
write_stream,
)
from httpie.plugins.registry import plugin_manager
from httpie.status import ExitStatus, http_status_to_exit_status
from . import __version__ as httpie_version
from .cli.constants import OUT_REQ_BODY, OUT_REQ_HEAD, OUT_RESP_BODY, OUT_RESP_HEAD
from .client import collect_messages
from .context import Environment
from .downloads import Downloader
from .output.writer import write_message, write_stream, MESSAGE_SEPARATOR_BYTES
from .plugins.registry import plugin_manager
from .status import ExitStatus, http_status_to_exit_status
# noinspection PyDefaultArgument
def main(
args: List[Union[str, bytes]] = sys.argv,
env=Environment(),
) -> ExitStatus:
def main(args: List[Union[str, bytes]] = sys.argv, env=Environment()) -> ExitStatus:
"""
The main function.
@ -38,12 +29,16 @@ def main(
Return exit status code.
"""
if '--prompt' in args:
from .prompt.cli import cli
return cli(sys.argv[2:])
program_name, *args = args
env.program_name = os.path.basename(program_name)
args = decode_raw_args(args, env.stdin_encoding)
plugin_manager.load_installed_plugins()
from httpie.cli.definition import parser
from .cli.definition import parser
if env.config.default_options:
args = env.config.default_options + args
@ -134,128 +129,95 @@ def get_output_options(
}[type(message)]
def program(
args: argparse.Namespace,
env: Environment,
) -> ExitStatus:
def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
"""
The main program without error handling.
"""
# TODO: Refactor and drastically simplify, especially so that the separator logic is elsewhere.
exit_status = ExitStatus.SUCCESS
downloader = None
initial_request: Optional[requests.PreparedRequest] = None
final_response: Optional[requests.Response] = None
def separate():
getattr(env.stdout, 'buffer', env.stdout).write(MESSAGE_SEPARATOR_BYTES)
def request_body_read_callback(chunk: bytes):
should_pipe_to_stdout = bool(
# Request body output desired
OUT_REQ_BODY in args.output_options
# & not `.read()` already pre-request (e.g., for compression)
and initial_request
# & non-EOF chunk
and chunk
)
if should_pipe_to_stdout:
msg = requests.PreparedRequest()
msg.is_body_upload_chunk = True
msg.body = chunk
msg.headers = initial_request.headers
write_message(requests_message=msg, env=env, args=args, with_body=True, with_headers=False)
try:
if args.download:
args.follow = True # --download implies --follow.
downloader = Downloader(
output_file=args.output_file,
progress_file=env.stderr,
resume=args.download_resume
)
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)
force_separator = False
prev_with_body = False
needs_separator = False
def maybe_separate():
nonlocal needs_separator
if env.stdout.isatty() and needs_separator:
needs_separator = False
getattr(env.stdout, 'buffer', env.stdout).write(b'\n\n')
initial_request: Optional[requests.PreparedRequest] = None
final_response: Optional[requests.Response] = None
def request_body_read_callback(chunk: bytes):
should_pipe_to_stdout = (
# Request body output desired
OUT_REQ_BODY in args.output_options
# & not `.read()` already pre-request (e.g., for compression)
and initial_request
# & non-EOF chunk
and chunk
)
if should_pipe_to_stdout:
msg = requests.PreparedRequest()
msg.is_body_upload_chunk = True
msg.body = chunk
msg.headers = initial_request.headers
write_message(
requests_message=msg,
env=env,
args=args,
with_body=True,
with_headers=False
)
messages = collect_messages(
args=args,
config_dir=env.config.directory,
request_body_read_callback=request_body_read_callback
)
# Process messages as theyre generated
for message in messages:
maybe_separate()
is_request = isinstance(message, requests.PreparedRequest)
with_headers, with_body = get_output_options(
args=args, message=message)
with_headers, with_body = get_output_options(args=args, message=message)
do_write_body = with_body
if prev_with_body and (with_headers or with_body) and (force_separator or not env.stdout_isatty):
# Separate after a previous message with body, if needed. See test_tokens.py.
separate()
force_separator = False
if is_request:
if not initial_request:
initial_request = message
is_streamed_upload = not isinstance(
message.body, (str, bytes))
if with_body:
with_body = not is_streamed_upload
needs_separator = is_streamed_upload
if with_body:
is_streamed_upload = not isinstance(message.body, (str, bytes))
do_write_body = not is_streamed_upload
force_separator = is_streamed_upload and env.stdout_isatty
else:
final_response = message
if args.check_status or downloader:
exit_status = http_status_to_exit_status(
http_status=message.status_code,
follow=args.follow
)
if (not env.stdout_isatty
and exit_status != ExitStatus.SUCCESS):
env.log_error(
f'HTTP {message.raw.status} {message.raw.reason}',
level='warning'
)
write_message(
requests_message=message,
env=env,
args=args,
with_headers=with_headers,
with_body=with_body,
)
maybe_separate()
exit_status = http_status_to_exit_status(http_status=message.status_code, follow=args.follow)
if exit_status != ExitStatus.SUCCESS and (not env.stdout_isatty or args.quiet):
env.log_error(f'HTTP {message.raw.status} {message.raw.reason}', level='warning')
write_message(requests_message=message, env=env, args=args, with_headers=with_headers,
with_body=do_write_body)
prev_with_body = with_body
# Cleanup
if force_separator:
separate()
if downloader and exit_status == ExitStatus.SUCCESS:
# Last response body download.
download_stream, download_to = downloader.start(
initial_url=initial_request.url,
final_response=final_response,
)
write_stream(
stream=download_stream,
outfile=download_to,
flush=False,
)
write_stream(stream=download_stream, outfile=download_to, flush=False)
downloader.finish()
if downloader.interrupted:
exit_status = ExitStatus.ERROR
env.log_error(
'Incomplete download: size=%d; downloaded=%d' % (
downloader.status.total_size,
downloader.status.downloaded
))
f'Incomplete download: size={downloader.status.total_size};'
f' downloaded={downloader.status.downloaded}'
)
return exit_status
finally:
if downloader and not downloader.finished:
downloader.failed()
if (not isinstance(args, list) and args.output_file
and args.output_file_specified):
if args.output_file and args.output_file_specified:
args.output_file.close()
@ -269,6 +231,8 @@ def print_debug_info(env: Environment):
])
env.stderr.write('\n\n')
env.stderr.write(repr(env))
env.stderr.write('\n\n')
env.stderr.write(repr(plugin_manager))
env.stderr.write('\n')
@ -283,6 +247,6 @@ def decode_raw_args(
"""
return [
arg.decode(stdin_encoding)
if type(arg) == bytes else arg
if type(arg) is bytes else arg
for arg in args
]

View File

@ -1,26 +1,22 @@
# coding=utf-8
"""
Download mode implementation.
"""
from __future__ import division
import errno
import mimetypes
import os
import re
import sys
import threading
from mailbox import Message
from time import sleep, time
from time import sleep, monotonic
from typing import IO, Optional, Tuple
from urllib.parse import urlsplit
import requests
from httpie.models import HTTPResponse
from httpie.output.streams import RawStream
from httpie.utils import humanize_bytes
from .models import HTTPResponse
from .output.streams import RawStream
from .utils import humanize_bytes
PARTIAL_CONTENT = 206
@ -64,7 +60,7 @@ def parse_content_range(content_range: str, resumed_from: int) -> int:
if not match:
raise ContentRangeError(
'Invalid Content-Range format %r' % content_range)
f'Invalid Content-Range format {content_range!r}')
content_range_dict = match.groupdict()
first_byte_pos = int(content_range_dict['first_byte_pos'])
@ -81,20 +77,19 @@ 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(
'Invalid Content-Range returned: %r' % content_range)
f'Invalid Content-Range returned: {content_range!r}')
if (first_byte_pos != resumed_from
or (instance_length is not None
and last_byte_pos + 1 != instance_length)):
# Not what we asked for.
raise ContentRangeError(
'Unexpected Content-Range returned (%r)'
' for the requested Range ("bytes=%d-")'
% (content_range, resumed_from)
f'Unexpected Content-Range returned ({content_range!r})'
f' for the requested Range ("bytes={resumed_from}-")'
)
return last_byte_pos + 1
@ -112,7 +107,7 @@ def filename_from_content_disposition(
"""
# attachment; filename=jakubroztocil-httpie-0.4.1-20-g40bd8f6.tar.gz
msg = Message('Content-Disposition: %s' % content_disposition)
msg = Message(f'Content-Disposition: {content_disposition}')
filename = msg.get_filename()
if filename:
# Basic sanitation.
@ -132,7 +127,7 @@ def filename_from_url(url: str, content_type: Optional[str]) -> str:
else:
ext = mimetypes.guess_extension(content_type)
if ext == '.htm': # Python 3
if ext == '.htm':
ext = '.html'
if ext:
@ -154,16 +149,8 @@ def trim_filename(filename: str, max_len: int) -> str:
def get_filename_max_length(directory: str) -> int:
max_len = 255
try:
pathconf = os.pathconf
except AttributeError:
pass # non-posix
else:
try:
max_len = pathconf(directory, 'PC_NAME_MAX')
except OSError as e:
if e.errno != errno.EINVAL:
raise
if hasattr(os, 'pathconf') and 'PC_NAME_MAX' in os.pathconf_names:
max_len = os.pathconf(directory, 'PC_NAME_MAX')
return max_len
@ -177,7 +164,7 @@ def trim_filename_if_needed(filename: str, directory='.', extra=0) -> str:
def get_unique_filename(filename: str, exists=os.path.exists) -> str:
attempt = 0
while True:
suffix = '-' + str(attempt) if attempt > 0 else ''
suffix = f'-{attempt}' if attempt > 0 else ''
try_filename = trim_filename_if_needed(filename, extra=len(suffix))
try_filename += suffix
if not exists(try_filename):
@ -226,7 +213,7 @@ class Downloader:
if bytes_have:
# Set ``Range`` header to resume the download
# TODO: Use "If-Range: mtime" to make sure it's fresh?
request_headers['Range'] = 'bytes=%d-' % bytes_have
request_headers['Range'] = f'bytes={bytes_have}-'
self._resumed_from = bytes_have
def start(
@ -247,7 +234,7 @@ class Downloader:
assert not self.status.time_started
# FIXME: some servers still might sent Content-Encoding: gzip
# <https://github.com/jakubroztocil/httpie/issues/423>
# <https://github.com/httpie/httpie/issues/423>
try:
total_size = int(final_response.headers['Content-Length'])
except (KeyError, ValueError, TypeError):
@ -271,7 +258,7 @@ class Downloader:
try:
self._output_file.seek(0)
self._output_file.truncate()
except IOError:
except OSError:
pass # stdout
self.status.started(
@ -288,12 +275,8 @@ class Downloader:
)
self._progress_reporter.output.write(
'Downloading %sto "%s"\n' % (
(humanize_bytes(total_size) + ' '
if total_size is not None
else ''),
self._output_file.name
)
f'Downloading {humanize_bytes(total_size) + " " if total_size is not None else ""}'
f'to "{self._output_file.name}"\n'
)
self._progress_reporter.start()
@ -358,7 +341,7 @@ class DownloadStatus:
assert self.time_started is None
self.total_size = total_size
self.downloaded = self.resumed_from = resumed_from
self.time_started = time()
self.time_started = monotonic()
def chunk_downloaded(self, size):
assert self.time_finished is None
@ -371,7 +354,7 @@ class DownloadStatus:
def finished(self):
assert self.time_started is not None
assert self.time_finished is None
self.time_finished = time()
self.time_finished = monotonic()
class ProgressReporterThread(threading.Thread):
@ -397,7 +380,7 @@ class ProgressReporterThread(threading.Thread):
self._spinner_pos = 0
self._status_line = ''
self._prev_bytes = 0
self._prev_time = time()
self._prev_time = monotonic()
self._should_stop = threading.Event()
def stop(self):
@ -414,16 +397,11 @@ class ProgressReporterThread(threading.Thread):
sleep(self._tick)
def report_speed(self):
now = time()
now = monotonic()
if now - self._prev_time >= self._update_interval:
downloaded = self.status.downloaded
try:
speed = ((downloaded - self._prev_bytes)
/ (now - self._prev_time))
except ZeroDivisionError:
speed = 0
speed = ((downloaded - self._prev_bytes)
/ (now - self._prev_time))
if not self.status.total_size:
self._status_line = PROGRESS_NO_CONTENT_LENGTH.format(
@ -431,10 +409,9 @@ class ProgressReporterThread(threading.Thread):
speed=humanize_bytes(speed),
)
else:
try:
percentage = downloaded / self.status.total_size * 100
except ZeroDivisionError:
percentage = 0
percentage = (downloaded / self.status.total_size * 100
if self.status.total_size
else 0)
if not speed:
eta = '-:--:--'
@ -442,7 +419,7 @@ class ProgressReporterThread(threading.Thread):
s = int((self.status.total_size - downloaded) / speed)
h, s = divmod(s, 60 * 60)
m, s = divmod(s, 60)
eta = '{0}:{1:0>2}:{2:0>2}'.format(h, m, s)
eta = f'{h}:{m:0>2}:{s:0>2}'
self._status_line = PROGRESS.format(
percentage=percentage,
@ -455,33 +432,20 @@ class ProgressReporterThread(threading.Thread):
self._prev_bytes = downloaded
self.output.write(
CLEAR_LINE
+ ' '
+ SPINNER[self._spinner_pos]
+ ' '
+ self._status_line
f'{CLEAR_LINE} {SPINNER[self._spinner_pos]} {self._status_line}'
)
self.output.flush()
self._spinner_pos = (self._spinner_pos + 1
if self._spinner_pos + 1 != len(SPINNER)
else 0)
self._spinner_pos = (self._spinner_pos + 1) % len(SPINNER)
def sum_up(self):
actually_downloaded = (
self.status.downloaded - self.status.resumed_from)
time_taken = self.status.time_finished - self.status.time_started
speed = actually_downloaded / time_taken if time_taken else actually_downloaded
self.output.write(CLEAR_LINE)
try:
speed = actually_downloaded / time_taken
except ZeroDivisionError:
# Either time is 0 (not all systems provide `time.time`
# with a better precision than 1 second), and/or nothing
# has been downloaded.
speed = actually_downloaded
self.output.write(SUMMARY.format(
downloaded=humanize_bytes(actually_downloaded),
total=(self.status.total_size

50
httpie/encoding.py Normal file
View File

@ -0,0 +1,50 @@
from typing import Union
from charset_normalizer import from_bytes
from charset_normalizer.constant import TOO_SMALL_SEQUENCE
UTF8 = 'utf-8'
ContentBytes = Union[bytearray, bytes]
def detect_encoding(content: ContentBytes) -> str:
"""
We default to UTF-8 if text too short, because the detection
can return a random encoding leading to confusing results
given the `charset_normalizer` version (< 2.0.5).
>>> too_short = ']"foo"'
>>> detected = from_bytes(too_short.encode()).best().encoding
>>> detected
'ascii'
>>> too_short.encode().decode(detected)
']"foo"'
"""
encoding = UTF8
if len(content) > TOO_SMALL_SEQUENCE:
match = from_bytes(bytes(content)).best()
if match:
encoding = match.encoding
return encoding
def smart_decode(content: ContentBytes, encoding: str) -> str:
"""Decode `content` using the given `encoding`.
If no `encoding` is provided, the best effort is to guess it from `content`.
Unicode errors are replaced.
"""
if not encoding:
encoding = detect_encoding(content)
return content.decode(encoding, 'replace')
def smart_encode(content: str, encoding: str) -> bytes:
"""Encode `content` using the given `encoding`.
Unicode errors are replaced.
"""
return content.encode(encoding, 'replace')

View File

@ -1,6 +1,9 @@
from typing import Iterable, Optional
from typing import Iterable
from urllib.parse import urlsplit
from .utils import split_cookies, parse_content_type_header
from .compat import cached_property
class HTTPMessage:
"""Abstract class for HTTP messages."""
@ -10,33 +13,28 @@ class HTTPMessage:
def iter_body(self, chunk_size: int) -> Iterable[bytes]:
"""Return an iterator over the body."""
raise NotImplementedError()
raise NotImplementedError
def iter_lines(self, chunk_size: int) -> Iterable[bytes]:
"""Return an iterator over the body yielding (`line`, `line_feed`)."""
raise NotImplementedError()
raise NotImplementedError
@property
def headers(self) -> str:
"""Return a `str` with the message's headers."""
raise NotImplementedError()
raise NotImplementedError
@property
def encoding(self) -> Optional[str]:
"""Return a `str` with the message's encoding, if known."""
raise NotImplementedError()
@property
def body(self) -> bytes:
"""Return a `bytes` with the message's body."""
raise NotImplementedError()
@cached_property
def encoding(self) -> str:
ct, params = parse_content_type_header(self.content_type)
return params.get('charset', '')
@property
def content_type(self) -> str:
"""Return the message content type."""
ct = self._orig.headers.get('Content-Type', '')
if not isinstance(ct, str):
ct = ct.decode('utf8')
ct = ct.decode()
return ct
@ -52,39 +50,32 @@ class HTTPResponse(HTTPMessage):
# noinspection PyProtectedMember
@property
def headers(self):
original = self._orig.raw._original_response
try:
raw_version = self._orig.raw._original_response.version
except AttributeError:
# Assume HTTP/1.1
raw_version = 11
version = {
9: '0.9',
10: '1.0',
11: '1.1',
20: '2',
}[original.version]
}[raw_version]
status_line = f'HTTP/{version} {original.status} {original.reason}'
original = self._orig
status_line = f'HTTP/{version} {original.status_code} {original.reason}'
headers = [status_line]
try:
# `original.msg` is a `http.client.HTTPMessage` on Python 3
# `_headers` is a 2-tuple
headers.extend(
'%s: %s' % header for header in original.msg._headers)
except AttributeError:
# and a `httplib.HTTPMessage` on Python 2.x
# `headers` is a list of `name: val<CRLF>`.
headers.extend(h.strip() for h in original.msg.headers)
headers.extend(
': '.join(header)
for header in original.headers.items()
if header[0] != 'Set-Cookie'
)
headers.extend(
f'Set-Cookie: {cookie}'
for cookie in split_cookies(original.headers.get('Set-Cookie'))
)
return '\r\n'.join(headers)
@property
def encoding(self):
return self._orig.encoding or 'utf8'
@property
def body(self):
# Only now the response body is fetched.
# Shouldn't be touched unless the body is actually needed.
return self._orig.content
class HTTPRequest(HTTPMessage):
"""A :class:`requests.models.Request` wrapper."""
@ -102,7 +93,7 @@ class HTTPRequest(HTTPMessage):
request_line = '{method} {path}{query} HTTP/1.1'.format(
method=self._orig.method,
path=url.path or '/',
query='?' + url.query if url.query else ''
query=f'?{url.query}' if url.query else ''
)
headers = dict(self._orig.headers)
@ -110,29 +101,18 @@ class HTTPRequest(HTTPMessage):
headers['Host'] = url.netloc.split('@')[-1]
headers = [
'%s: %s' % (
name,
value if isinstance(value, str) else value.decode('utf8')
)
f'{name}: {value if isinstance(value, str) else value.decode()}'
for name, value in headers.items()
]
headers.insert(0, request_line)
headers = '\r\n'.join(headers).strip()
if isinstance(headers, bytes):
# Python < 3
headers = headers.decode('utf8')
return headers
@property
def encoding(self):
return 'utf8'
@property
def body(self):
body = self._orig.body
if isinstance(body, str):
# Happens with JSON/form request data parsed from the command line.
body = body.encode('utf8')
body = body.encode()
return body or b''

View File

@ -1,5 +1,3 @@
from __future__ import absolute_import
import json
from typing import Optional, Type
@ -11,13 +9,15 @@ import pygments.token
from pygments.formatters.terminal import TerminalFormatter
from pygments.formatters.terminal256 import Terminal256Formatter
from pygments.lexer import Lexer
from pygments.lexers.data import JsonLexer
from pygments.lexers.special import TextLexer
from pygments.lexers.text import HttpLexer as PygmentsHttpLexer
from pygments.util import ClassNotFound
from httpie.compat import is_windows
from httpie.context import Environment
from httpie.plugins import FormatterPlugin
from ..lexers.json import EnhancedJsonLexer
from ...compat import is_windows
from ...context import Environment
from ...plugins import FormatterPlugin
AUTO_STYLE = 'auto' # Follows terminal ANSI color styles
@ -62,6 +62,7 @@ class ColorFormatter(FormatterPlugin):
http_lexer = PygmentsHttpLexer()
formatter = TerminalFormatter()
else:
from ..lexers.http import SimplifiedHTTPLexer
http_lexer = SimplifiedHTTPLexer()
formatter = Terminal256Formatter(
style=self.get_style_class(color_scheme)
@ -120,8 +121,8 @@ def get_lexer(
subtype_name, subtype_suffix = subtype.split('+', 1)
lexer_names.extend([subtype_name, subtype_suffix])
mime_types.extend([
'%s/%s' % (type_, subtype_name),
'%s/%s' % (type_, subtype_suffix)
f'{type_}/{subtype_name}',
f'{type_}/{subtype_suffix}',
])
# As a last resort, if no lexer feels responsible, and
@ -153,57 +154,14 @@ def get_lexer(
else:
lexer = pygments.lexers.get_lexer_by_name('json')
# Use our own JSON lexer: it supports JSON bodies preceded by non-JSON data
# as well as legit JSON bodies.
if isinstance(lexer, JsonLexer):
lexer = EnhancedJsonLexer()
return lexer
class SimplifiedHTTPLexer(pygments.lexer.RegexLexer):
"""Simplified HTTP lexer for Pygments.
It only operates on headers and provides a stronger contrast between
their names and values than the original one bundled with Pygments
(:class:`pygments.lexers.text import HttpLexer`), especially when
Solarized color scheme is used.
"""
name = 'HTTP'
aliases = ['http']
filenames = ['*.http']
tokens = {
'root': [
# Request-Line
(r'([A-Z]+)( +)([^ ]+)( +)(HTTP)(/)(\d+\.\d+)',
pygments.lexer.bygroups(
pygments.token.Name.Function,
pygments.token.Text,
pygments.token.Name.Namespace,
pygments.token.Text,
pygments.token.Keyword.Reserved,
pygments.token.Operator,
pygments.token.Number
)),
# Response Status-Line
(r'(HTTP)(/)(\d+\.\d+)( +)(\d{3})( +)(.+)',
pygments.lexer.bygroups(
pygments.token.Keyword.Reserved, # 'HTTP'
pygments.token.Operator, # '/'
pygments.token.Number, # Version
pygments.token.Text,
pygments.token.Number, # Status code
pygments.token.Text,
pygments.token.Name.Exception, # Reason
)),
# Header
(r'(.*?)( *)(:)( *)(.+)', pygments.lexer.bygroups(
pygments.token.Name.Attribute, # Name
pygments.token.Text,
pygments.token.Operator, # Colon
pygments.token.Text,
pygments.token.String # Value
))
]
}
class Solarized256Style(pygments.style.Style):
"""
solarized256

View File

@ -1,4 +1,4 @@
from httpie.plugins import FormatterPlugin
from ...plugins import FormatterPlugin
class HeadersFormatter(FormatterPlugin):

View File

@ -1,7 +1,6 @@
from __future__ import absolute_import
import json
from httpie.plugins import FormatterPlugin
from ...plugins import FormatterPlugin
class JSONFormatter(FormatterPlugin):
@ -18,15 +17,16 @@ class JSONFormatter(FormatterPlugin):
]
if (self.kwargs['explicit_json']
or any(token in mime for token in maybe_json)):
from ..utils import load_prefixed_json
try:
obj = json.loads(body)
data_prefix, json_obj = load_prefixed_json(body)
except ValueError:
pass # Invalid JSON, ignore.
else:
# Indent, sort keys by name, and avoid
# unicode escapes to improve readability.
body = json.dumps(
obj=obj,
body = data_prefix + json.dumps(
obj=json_obj,
sort_keys=self.format_options['json']['sort_keys'],
ensure_ascii=False,
indent=self.format_options['json']['indent']

View File

@ -0,0 +1,59 @@
import sys
from typing import TYPE_CHECKING, Optional
from ...encoding import UTF8
from ...plugins import FormatterPlugin
if TYPE_CHECKING:
from xml.dom.minidom import Document
def parse_xml(data: str) -> 'Document':
"""Parse given XML `data` string into an appropriate :class:`~xml.dom.minidom.Document` object."""
from defusedxml.minidom import parseString
return parseString(data)
def pretty_xml(document: 'Document',
encoding: Optional[str] = UTF8,
indent: int = 2,
standalone: Optional[bool] = None) -> str:
"""Render the given :class:`~xml.dom.minidom.Document` `document` into a prettified string."""
kwargs = {
'encoding': encoding or UTF8,
'indent': ' ' * indent,
}
if standalone is not None and sys.version_info >= (3, 9):
kwargs['standalone'] = standalone
body = document.toprettyxml(**kwargs).decode(kwargs['encoding'])
# Remove blank lines automatically added by `toprettyxml()`.
return '\n'.join(line for line in body.splitlines() if line.strip())
class XMLFormatter(FormatterPlugin):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.enabled = self.format_options['xml']['format']
def format_body(self, body: str, mime: str):
if 'xml' not in mime:
return body
from xml.parsers.expat import ExpatError
from defusedxml.common import DefusedXmlException
try:
parsed_body = parse_xml(body)
except ExpatError:
pass # Invalid XML, ignore.
except DefusedXmlException:
pass # Unsafe XML, ignore.
else:
body = pretty_xml(parsed_body,
encoding=parsed_body.encoding,
indent=self.format_options['xml']['indent'],
standalone=parsed_body.standalone)
return body

View File

View File

@ -0,0 +1,49 @@
import pygments
class SimplifiedHTTPLexer(pygments.lexer.RegexLexer):
"""Simplified HTTP lexer for Pygments.
It only operates on headers and provides a stronger contrast between
their names and values than the original one bundled with Pygments
(:class:`pygments.lexers.text import HttpLexer`), especially when
Solarized color scheme is used.
"""
name = 'HTTP'
aliases = ['http']
filenames = ['*.http']
tokens = {
'root': [
# Request-Line
(r'([A-Z]+)( +)([^ ]+)( +)(HTTP)(/)(\d+\.\d+)',
pygments.lexer.bygroups(
pygments.token.Name.Function,
pygments.token.Text,
pygments.token.Name.Namespace,
pygments.token.Text,
pygments.token.Keyword.Reserved,
pygments.token.Operator,
pygments.token.Number
)),
# Response Status-Line
(r'(HTTP)(/)(\d+\.\d+)( +)(\d{3})( +)(.+)',
pygments.lexer.bygroups(
pygments.token.Keyword.Reserved, # 'HTTP'
pygments.token.Operator, # '/'
pygments.token.Number, # Version
pygments.token.Text,
pygments.token.Number, # Status code
pygments.token.Text,
pygments.token.Name.Exception, # Reason
)),
# Header
(r'(.*?)( *)(:)( *)(.+)', pygments.lexer.bygroups(
pygments.token.Name.Attribute, # Name
pygments.token.Text,
pygments.token.Operator, # Colon
pygments.token.Text,
pygments.token.String # Value
))
]
}

View File

@ -0,0 +1,31 @@
import re
from pygments.lexer import bygroups, using, RegexLexer
from pygments.lexers.data import JsonLexer
from pygments.token import Token
PREFIX_TOKEN = Token.Error
PREFIX_REGEX = r'[^{\["]+'
class EnhancedJsonLexer(RegexLexer):
"""
Enhanced JSON lexer for Pygments.
It adds support for eventual data prefixing the actual JSON body.
"""
name = 'JSON'
flags = re.IGNORECASE | re.DOTALL
tokens = {
'root': [
# Eventual non-JSON data prefix followed by actual JSON body.
# FIX: data prefix + number (integer or float) are not correctly handled.
(
fr'({PREFIX_REGEX})' + r'((?:[{\["]|true|false|null).+)',
bygroups(PREFIX_TOKEN, using(JsonLexer))
),
# JSON body.
(r'.+', using(JsonLexer)),
],
}

View File

@ -1,9 +1,9 @@
import re
from typing import Optional, List
from httpie.plugins import ConverterPlugin
from httpie.plugins.registry import plugin_manager
from httpie.context import Environment
from ..plugins import ConverterPlugin
from ..plugins.registry import plugin_manager
from ..context import Environment
MIME_RE = re.compile(r'^[^/]+/[^/]+$')

View File

@ -1,9 +1,11 @@
from abc import ABCMeta, abstractmethod
from itertools import chain
from typing import Callable, Iterable, Union
from httpie.context import Environment
from httpie.models import HTTPMessage
from httpie.output.processing import Conversion, Formatting
from .processing import Conversion, Formatting
from ..context import Environment
from ..encoding import smart_decode, smart_encode, UTF8
from ..models import HTTPMessage
BINARY_SUPPRESSED_NOTICE = (
@ -24,7 +26,7 @@ class BinarySuppressedError(DataSuppressedError):
message = BINARY_SUPPRESSED_NOTICE
class BaseStream:
class BaseStream(metaclass=ABCMeta):
"""Base HTTP message output stream class."""
def __init__(
@ -48,11 +50,11 @@ class BaseStream:
def get_headers(self) -> bytes:
"""Return the headers' bytes."""
return self.msg.headers.encode('utf8')
return self.msg.headers.encode()
@abstractmethod
def iter_body(self) -> Iterable[bytes]:
"""Return an iterator over the message body."""
raise NotImplementedError()
def __iter__(self) -> Iterable[bytes]:
"""Return an iterator over `self.msg`."""
@ -96,23 +98,31 @@ class EncodedStream(BaseStream):
"""
CHUNK_SIZE = 1
def __init__(self, env=Environment(), **kwargs):
def __init__(
self,
env=Environment(),
mime_overwrite: str = None,
encoding_overwrite: str = None,
**kwargs
):
super().__init__(**kwargs)
self.mime = mime_overwrite or self.msg.content_type
self.encoding = encoding_overwrite or self.msg.encoding
if env.stdout_isatty:
# Use the encoding supported by the terminal.
output_encoding = env.stdout_encoding
else:
# Preserve the message encoding.
output_encoding = self.msg.encoding
# Default to utf8 when unsure.
self.output_encoding = output_encoding or 'utf8'
# Default to UTF-8 when unsure.
self.output_encoding = output_encoding or UTF8
def iter_body(self) -> Iterable[bytes]:
for line, lf in self.msg.iter_lines(self.CHUNK_SIZE):
if b'\0' in line:
raise BinarySuppressedError()
yield line.decode(self.msg.encoding) \
.encode(self.output_encoding, 'replace') + lf
line = smart_decode(line, self.encoding)
yield smart_encode(line, self.output_encoding) + lf
class PrettyStream(EncodedStream):
@ -134,7 +144,6 @@ class PrettyStream(EncodedStream):
super().__init__(**kwargs)
self.formatting = formatting
self.conversion = conversion
self.mime = self.msg.content_type.split(';')[0]
def get_headers(self) -> bytes:
return self.formatting.format_headers(
@ -165,9 +174,9 @@ class PrettyStream(EncodedStream):
if not isinstance(chunk, str):
# Text when a converter has been used,
# otherwise it will always be bytes.
chunk = chunk.decode(self.msg.encoding, 'replace')
chunk = smart_decode(chunk, self.encoding)
chunk = self.formatting.format_body(content=chunk, mime=self.mime)
return chunk.encode(self.output_encoding, 'replace')
return smart_encode(chunk, self.output_encoding)
class BufferedPrettyStream(PrettyStream):

37
httpie/output/utils.py Normal file
View File

@ -0,0 +1,37 @@
import json
import re
from typing import Tuple
from ..utils import load_json_preserve_order_and_dupe_keys
from .lexers.json import PREFIX_REGEX
def load_prefixed_json(data: str) -> Tuple[str, json.JSONDecoder]:
"""Simple JSON loading from `data`.
"""
# First, the full data.
try:
return '', load_json_preserve_order_and_dupe_keys(data)
except ValueError:
pass
# Then, try to find the start of the actual body.
data_prefix, body = parse_prefixed_json(data)
try:
return data_prefix, load_json_preserve_order_and_dupe_keys(body)
except ValueError:
raise ValueError('Invalid JSON')
def parse_prefixed_json(data: str) -> Tuple[str, str]:
"""Find the potential JSON body from `data`.
Sometimes the JSON body is prefixed with a XSSI magic string, specific to the server.
Return a tuple (data prefix, actual JSON body).
"""
matches = re.findall(PREFIX_REGEX, data)
data_prefix = matches[0] if matches else ''
body = data[len(data_prefix):]
return data_prefix, body

View File

@ -4,14 +4,18 @@ from typing import IO, TextIO, Tuple, Type, Union
import requests
from httpie.context import Environment
from httpie.models import HTTPRequest, HTTPResponse
from httpie.output.processing import Conversion, Formatting
from httpie.output.streams import (
from ..context import Environment
from ..models import HTTPRequest, HTTPResponse, HTTPMessage
from .processing import Conversion, Formatting
from .streams import (
BaseStream, BufferedPrettyStream, EncodedStream, PrettyStream, RawStream,
)
MESSAGE_SEPARATOR = '\n\n'
MESSAGE_SEPARATOR_BYTES = MESSAGE_SEPARATOR.encode()
def write_message(
requests_message: Union[requests.PreparedRequest, requests.Response],
env: Environment,
@ -35,10 +39,10 @@ def write_message(
}
try:
if env.is_windows and 'colors' in args.prettify:
write_stream_with_colors_win_py3(**write_stream_kwargs)
write_stream_with_colors_win(**write_stream_kwargs)
else:
write_stream(**write_stream_kwargs)
except IOError as e:
except OSError as e:
show_traceback = args.debug or args.traceback
if not show_traceback and e.errno == errno.EPIPE:
# Ignore broken pipes unless --traceback.
@ -54,7 +58,7 @@ def write_stream(
):
"""Write the output stream."""
try:
# Writing bytes so we use the buffer interface (Python 3).
# Writing bytes so we use the buffer interface.
buf = outfile.buffer
except AttributeError:
buf = outfile
@ -65,14 +69,14 @@ def write_stream(
outfile.flush()
def write_stream_with_colors_win_py3(
def write_stream_with_colors_win(
stream: 'BaseStream',
outfile: TextIO,
flush: bool
):
"""Like `write`, but colorized chunks are written as text
directly to `outfile` to ensure it gets processed by colorama.
Applies only to Windows with Python 3 and colorized terminal output.
Applies only to Windows and colorized terminal output.
"""
color = b'\x1b['
@ -93,16 +97,17 @@ def build_output_stream_for_message(
with_headers: bool,
with_body: bool,
):
stream_class, stream_kwargs = get_stream_type_and_kwargs(
env=env,
args=args,
)
message_class = {
message_type = {
requests.PreparedRequest: HTTPRequest,
requests.Response: HTTPResponse,
}[type(requests_message)]
stream_class, stream_kwargs = get_stream_type_and_kwargs(
env=env,
args=args,
message_type=message_type,
)
yield from stream_class(
msg=message_class(requests_message),
msg=message_type(requests_message),
with_headers=with_headers,
with_body=with_body,
**stream_kwargs,
@ -111,12 +116,13 @@ def build_output_stream_for_message(
and not getattr(requests_message, 'is_body_upload_chunk', False)):
# Ensure a blank line after the response body.
# For terminal output only.
yield b'\n\n'
yield MESSAGE_SEPARATOR_BYTES
def get_stream_type_and_kwargs(
env: Environment,
args: argparse.Namespace
args: argparse.Namespace,
message_type: Type[HTTPMessage],
) -> Tuple[Type['BaseStream'], dict]:
"""Pick the right stream type and kwargs for it based on `env` and `args`.
@ -130,23 +136,27 @@ def get_stream_type_and_kwargs(
else RawStream.CHUNK_SIZE
)
}
elif args.prettify:
stream_class = PrettyStream if args.stream else BufferedPrettyStream
stream_kwargs = {
'env': env,
'conversion': Conversion(),
'formatting': Formatting(
env=env,
groups=args.prettify,
color_scheme=args.style,
explicit_json=args.json,
format_options=args.format_options,
)
}
else:
stream_class = EncodedStream
stream_kwargs = {
'env': env
'env': env,
}
if message_type is HTTPResponse:
stream_kwargs.update({
'mime_overwrite': args.response_mime,
'encoding_overwrite': args.response_charset,
})
if args.prettify:
stream_class = PrettyStream if args.stream else BufferedPrettyStream
stream_kwargs.update({
'conversion': Conversion(),
'formatting': Formatting(
env=env,
groups=args.prettify,
color_scheme=args.style,
explicit_json=args.json,
format_options=args.format_options,
)
})
return stream_class, stream_kwargs

View File

@ -3,7 +3,9 @@ WARNING: The plugin API is still work in progress and will
probably be completely reworked in the future.
"""
from httpie.plugins.base import (
from .base import (
AuthPlugin, FormatterPlugin,
ConverterPlugin, TransportPlugin
)
__all__ = ('AuthPlugin', 'ConverterPlugin', 'FormatterPlugin', 'TransportPlugin')

View File

@ -1,5 +1,7 @@
class BasePlugin:
from typing import Tuple
class BasePlugin:
# The name of the plugin, eg. "My auth".
name = None
@ -53,7 +55,7 @@ class AuthPlugin(BasePlugin):
# then this is `None`.
raw_auth = None
def get_auth(self, username=None, password=None):
def get_auth(self, username: str = None, password: str = None):
"""
If `auth_parse` is set to `True`, then `username`
and `password` contain the parsed credentials.
@ -93,7 +95,7 @@ class TransportPlugin(BasePlugin):
class ConverterPlugin(BasePlugin):
"""
Possibly converts response data for prettified terminal display.
Possibly converts binary response data for prettified terminal display.
See httpie-msgpack for an example converter plugin:
@ -101,14 +103,21 @@ class ConverterPlugin(BasePlugin):
"""
def __init__(self, mime):
def __init__(self, mime: str):
self.mime = mime
def convert(self, content_bytes):
def convert(self, body: bytes) -> Tuple[str, str]:
"""
Convert a binary body to a textual representation for the terminal
and return a tuple containing the new Content-Type and content, e.g.:
('application/json', '{}')
"""
raise NotImplementedError
@classmethod
def supports(cls, mime):
def supports(cls, mime: str) -> bool:
raise NotImplementedError

View File

@ -2,7 +2,7 @@ from base64 import b64encode
import requests.auth
from httpie.plugins.base import AuthPlugin
from .base import AuthPlugin
# noinspection PyAbstractClass
@ -19,7 +19,7 @@ class HTTPBasicAuth(requests.auth.HTTPBasicAuth):
"""
Override username/password serialization to allow unicode.
See https://github.com/jakubroztocil/httpie/issues/212
See https://github.com/httpie/httpie/issues/212
"""
# noinspection PyTypeChecker
@ -29,9 +29,9 @@ class HTTPBasicAuth(requests.auth.HTTPBasicAuth):
@staticmethod
def make_header(username: str, password: str) -> str:
credentials = u'%s:%s' % (username, password)
token = b64encode(credentials.encode('utf8')).strip().decode('latin1')
return 'Basic %s' % token
credentials = f'{username}:{password}'
token = b64encode(credentials.encode()).strip().decode('latin1')
return f'Basic {token}'
class BasicAuthPlugin(BuiltinAuthPlugin):

View File

@ -4,8 +4,9 @@ from typing import Dict, List, Type
from pkg_resources import iter_entry_points
from httpie.plugins import AuthPlugin, ConverterPlugin, FormatterPlugin
from httpie.plugins.base import BasePlugin, TransportPlugin
from ..utils import repr_dict
from . import AuthPlugin, ConverterPlugin, FormatterPlugin
from .base import BasePlugin, TransportPlugin
ENTRY_POINT_NAMES = [
@ -65,5 +66,13 @@ class PluginManager(list):
def get_transport_plugins(self) -> List[Type[TransportPlugin]]:
return self.filter(TransportPlugin)
def __str__(self):
return repr_dict({
'adapters': self.get_transport_plugins(),
'auth': self.get_auth_plugins(),
'converters': self.get_converters(),
'formatters': self.get_formatters(),
})
def __repr__(self):
return f'<PluginManager: {list(self)}>'
return f'<{type(self).__name__} {self}>'

Some files were not shown because too many files have changed in this diff Show More