Compare commits

..

1 Commits

Author SHA1 Message Date
Jakub Roztocil
9d2e2afede Add failing reproduction test case 2022-06-07 14:50:56 +02:00
76 changed files with 915 additions and 1038 deletions

View File

@ -1,22 +1,28 @@
name: Update Generated Content
name: Update Autogenerated Files
on:
push:
branches:
- master
jobs:
update-content:
regen-autogenerated-files:
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == github.repository
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: 3.9
- run: make content
- run: make regen-all
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v4
with:
commit-message: "[automated] Update generated content"
title: "[automated] Update generated content"
commit-message: "[automated] Update auto-generated files"
title: "[automated] Update auto-generated files"
delete-branch: true
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: "3.9"

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: 3.9
- run: make venv

View File

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: "3.10"
- run: make install

View File

@ -17,6 +17,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install HTTPie
run: sudo pip 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

@ -18,7 +18,7 @@ jobs:
with:
ref: ${{ github.event.inputs.branch }}
- uses: mislav/bump-homebrew-formula-action@v2
- uses: mislav/bump-homebrew-formula-action@v1
with:
formula-name: httpie
tag-name: ${{ github.events.inputs.branch }}

View File

@ -24,7 +24,7 @@ jobs:
with:
ref: ${{ github.event.inputs.branch }}
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: 3.9
@ -52,7 +52,7 @@ jobs:
id: release_id
run: |
pip install httpie
export API_URL="api.github.com/repos/httpie/cli/releases/tags/${{ github.event.inputs.tag_name }}"
export API_URL="api.github.com/repos/httpie/httpie/releases/tags/${{ github.event.inputs.tag_name }}"
export UPLOAD_URL=`https --ignore-stdin GET $API_URL | jq -r ".upload_url"`
echo "::set-output name=UPLOAD_URL::$UPLOAD_URL"

View File

@ -17,7 +17,7 @@ jobs:
with:
ref: ${{ github.event.inputs.branch }}
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: 3.9

View File

@ -34,8 +34,7 @@ jobs:
id: build
- uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
with:
store_login: ${{ secrets.SNAP_STORE_LOGIN }}
snap: ${{ steps.build.outputs.snap }}
release: ${{ matrix.level }}

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
- uses: actions/stale@v5
with:
close-pr-message: 'Thanks for the pull request, but since it was stale for more than a 30 days we are closing it. If you want to work back on it, feel free to re-open it or create a new one.'
stale-pr-label: 'stale'

View File

@ -30,7 +30,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Windows setup

View File

@ -4,7 +4,7 @@
## Patches, features, ideas
[Complete list of contributors on GitHub](https://github.com/httpie/cli/graphs/contributors)
[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)

View File

@ -3,151 +3,143 @@
This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/).
## [3.3.0-dev](https://github.com/httpie/cli/compare/3.2.2...master) (unreleased)
## [3.2.1](https://github.com/httpie/httpie/compare/3.1.0...3.2.1) (2022-05-06)
- Make it possible to [unset](https://httpie.io/docs/cli/default-request-headers) the `User-Agent`, `Accept-Encoding`, and `Host` request headers. ([#1502](https://github.com/httpie/cli/issues/1502))
- Improved support for determining auto-streaming when the `Content-Type` header includes encoding information. ([#1383](https://github.com/httpie/httpie/pull/1383))
- Fixed the display of the crash happening in the secondary process for update checks. ([#1388](https://github.com/httpie/httpie/issues/1388))
## [3.2.2](https://github.com/httpie/cli/compare/3.2.1...3.2.2) (2022-05-19)
## [3.2.0](https://github.com/httpie/httpie/compare/3.1.0...3.2.0) (2022-05-05)
- Fixed compatibility with urllib3 2.0.0. ([#1499](https://github.com/httpie/cli/issues/1499))
- Added a warning for notifying the user about the new updates. ([#1336](https://github.com/httpie/httpie/pull/1336))
- Added support for single binary executables. ([#1330](https://github.com/httpie/httpie/pull/1330))
- Added support for man pages (and auto generation of them from the parser declaration). ([#1317](https://github.com/httpie/httpie/pull/1317))
- Added `http --manual` for man pages & regular manual with pager. ([#1343](https://github.com/httpie/httpie/pull/1343))
- Added support for session persistence of repeated headers with the same name. ([#1335](https://github.com/httpie/httpie/pull/1335))
- Added support for sending `Secure` cookies to the `localhost` (and `.local` suffixed domains). ([#1308](https://github.com/httpie/httpie/issues/1308))
- Improved UI for the progress bars. ([#1324](https://github.com/httpie/httpie/pull/1324))
- Fixed redundant creation of `Content-Length` header on `OPTIONS` requests. ([#1310](https://github.com/httpie/httpie/issues/1310))
- Fixed blocking of warning thread on some use cases. ([#1349](https://github.com/httpie/httpie/issues/1349))
- Changed `httpie plugins` to the new `httpie cli` namespace as `httpie cli plugins` (`httpie plugins` continues to work as a hidden alias). ([#1320](https://github.com/httpie/httpie/issues/1320))
- Soft deprecated the `--history-print`. ([#1380](https://github.com/httpie/httpie/pull/1380))
## [3.2.1](https://github.com/httpie/cli/compare/3.1.0...3.2.1) (2022-05-06)
## [3.1.0](https://github.com/httpie/httpie/compare/3.0.2...3.1.0) (2022-03-08)
- Improved support for determining auto-streaming when the `Content-Type` header includes encoding information. ([#1383](https://github.com/httpie/cli/pull/1383))
- Fixed the display of the crash happening in the secondary process for update checks. ([#1388](https://github.com/httpie/cli/issues/1388))
- **SECURITY** Fixed the [vulnerability](https://github.com/httpie/httpie/security/advisories/GHSA-9w4w-cpc8-h2fq) that caused exposure of cookies on redirects to third party hosts. ([#1312](https://github.com/httpie/httpie/pull/1312))
- Fixed escaping of integer indexes with multiple backslashes in the nested JSON builder. ([#1285](https://github.com/httpie/httpie/issues/1285))
- Fixed displaying of status code without a status message on non-`auto` themes. ([#1300](https://github.com/httpie/httpie/issues/1300))
- Fixed redundant issuance of stdin detection warnings on some rare cases due to underlying implementation. ([#1303](https://github.com/httpie/httpie/pull/1303))
- Fixed double `--quiet` so that it will now suppress all python level warnings. ([#1271](https://github.com/httpie/httpie/issues/1271))
- Added support for specifying certificate private key passphrases through `--cert-key-pass` and prompts. ([#946](https://github.com/httpie/httpie/issues/946))
- Added `httpie cli export-args` command for exposing the parser specification for the `http`/`https` commands. ([#1293](https://github.com/httpie/httpie/pull/1293))
- Improved regulation of top-level arrays. ([#1292](https://github.com/httpie/httpie/commit/225dccb2186f14f871695b6c4e0bfbcdb2e3aa28))
- Improved UI layout for standalone invocations. ([#1296](https://github.com/httpie/httpie/pull/1296))
## [3.2.0](https://github.com/httpie/cli/compare/3.1.0...3.2.0) (2022-05-05)
- Added a warning for notifying the user about the new updates. ([#1336](https://github.com/httpie/cli/pull/1336))
- Added support for single binary executables. ([#1330](https://github.com/httpie/cli/pull/1330))
- Added support for man pages (and auto generation of them from the parser declaration). ([#1317](https://github.com/httpie/cli/pull/1317))
- Added `http --manual` for man pages & regular manual with pager. ([#1343](https://github.com/httpie/cli/pull/1343))
- Added support for session persistence of repeated headers with the same name. ([#1335](https://github.com/httpie/cli/pull/1335))
- Added support for sending `Secure` cookies to the `localhost` (and `.local` suffixed domains). ([#1308](https://github.com/httpie/cli/issues/1308))
- Improved UI for the progress bars. ([#1324](https://github.com/httpie/cli/pull/1324))
- Fixed redundant creation of `Content-Length` header on `OPTIONS` requests. ([#1310](https://github.com/httpie/cli/issues/1310))
- Fixed blocking of warning thread on some use cases. ([#1349](https://github.com/httpie/cli/issues/1349))
- Changed `httpie plugins` to the new `httpie cli` namespace as `httpie cli plugins` (`httpie plugins` continues to work as a hidden alias). ([#1320](https://github.com/httpie/cli/issues/1320))
- Soft deprecated the `--history-print`. ([#1380](https://github.com/httpie/cli/pull/1380))
## [3.1.0](https://github.com/httpie/cli/compare/3.0.2...3.1.0) (2022-03-08)
- **SECURITY** Fixed the [vulnerability](https://github.com/httpie/cli/security/advisories/GHSA-9w4w-cpc8-h2fq) that caused exposure of cookies on redirects to third party hosts. ([#1312](https://github.com/httpie/cli/pull/1312))
- Fixed escaping of integer indexes with multiple backslashes in the nested JSON builder. ([#1285](https://github.com/httpie/cli/issues/1285))
- Fixed displaying of status code without a status message on non-`auto` themes. ([#1300](https://github.com/httpie/cli/issues/1300))
- Fixed redundant issuance of stdin detection warnings on some rare cases due to underlying implementation. ([#1303](https://github.com/httpie/cli/pull/1303))
- Fixed double `--quiet` so that it will now suppress all python level warnings. ([#1271](https://github.com/httpie/cli/issues/1271))
- Added support for specifying certificate private key passphrases through `--cert-key-pass` and prompts. ([#946](https://github.com/httpie/cli/issues/946))
- Added `httpie cli export-args` command for exposing the parser specification for the `http`/`https` commands. ([#1293](https://github.com/httpie/cli/pull/1293))
- Improved regulation of top-level arrays. ([#1292](https://github.com/httpie/cli/commit/225dccb2186f14f871695b6c4e0bfbcdb2e3aa28))
- Improved UI layout for standalone invocations. ([#1296](https://github.com/httpie/cli/pull/1296))
## [3.0.2](https://github.com/httpie/cli/compare/3.0.1...3.0.2) (2022-01-24)
## [3.0.2](https://github.com/httpie/httpie/compare/3.0.1...3.0.2) (2022-01-24)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Fixed usage of `httpie` when there is a presence of a config with `default_options`. ([#1280](https://github.com/httpie/cli/pull/1280))
- Fixed usage of `httpie` when there is a presence of a config with `default_options`. ([#1280](https://github.com/httpie/httpie/pull/1280))
## [3.0.1](https://github.com/httpie/cli/compare/3.0.0...3.0.1) (2022-01-23)
## [3.0.1](https://github.com/httpie/httpie/compare/3.0.0...3.0.1) (2022-01-23)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Changed the value shown as time elapsed from time-to-read-headers to total exchange time. ([#1277](https://github.com/httpie/cli/issues/1277))
- Changed the value shown as time elapsed from time-to-read-headers to total exchange time. ([#1277](https://github.com/httpie/httpie/issues/1277))
## [3.0.0](https://github.com/httpie/cli/compare/2.6.0...3.0.0) (2022-01-21)
## [3.0.0](https://github.com/httpie/httpie/compare/2.6.0...3.0.0) (2022-01-21)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Dropped support for Python 3.6. ([#1177](https://github.com/httpie/cli/issues/1177))
- Improved startup time by 40%. ([#1211](https://github.com/httpie/cli/pull/1211))
- Added support for nested JSON syntax. ([#1169](https://github.com/httpie/cli/issues/1169))
- Added `httpie plugins` interface for plugin management. ([#566](https://github.com/httpie/cli/issues/566))
- Added support for Bearer authentication via `--auth-type=bearer` ([#1215](https://github.com/httpie/cli/issues/1215)).
- Added support for quick conversions of pasted URLs into HTTPie calls by adding a space after the protocol name (`$ https ://pie.dev` → `https://pie.dev`). ([#1195](https://github.com/httpie/cli/issues/1195))
- Added support for _sending_ multiple HTTP header lines with the same name. ([#130](https://github.com/httpie/cli/issues/130))
- Added support for _receiving_ multiple HTTP headers lines with the same name. ([#1207](https://github.com/httpie/cli/issues/1207))
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/cli/issues/1212))
- Added support for automatically enabling `--stream` when `Content-Type` is `text/event-stream`. ([#376](https://github.com/httpie/cli/issues/376))
- Added support for displaying the total elapsed time through `--meta`/`-vv` or `--print=m`. ([#243](https://github.com/httpie/cli/issues/243))
- Added new `pie-dark`/`pie-light` (and `pie`) styles that match with [HTTPie for Web and Desktop](https://httpie.io/product). ([#1237](https://github.com/httpie/cli/issues/1237))
- Added support for better error handling on DNS failures. ([#1248](https://github.com/httpie/cli/issues/1248))
- Added support for storing prompted passwords in the local sessions. ([#1098](https://github.com/httpie/cli/issues/1098))
- Added warnings about the `--ignore-stdin`, when there is no incoming data from stdin. ([#1255](https://github.com/httpie/cli/issues/1255))
- Fixed crashing due to broken plugins. ([#1204](https://github.com/httpie/cli/issues/1204))
- Fixed auto addition of XML declaration to every formatted XML response. ([#1156](https://github.com/httpie/cli/issues/1156))
- Fixed highlighting when `Content-Type` specifies `charset`. ([#1242](https://github.com/httpie/cli/issues/1242))
- Fixed an unexpected crash when `--raw` is used with `--chunked`. ([#1253](https://github.com/httpie/cli/issues/1253))
- Changed the default Windows theme from `fruity` to `auto`. ([#1266](https://github.com/httpie/cli/issues/1266))
- Dropped support for Python 3.6. ([#1177](https://github.com/httpie/httpie/issues/1177))
- Improved startup time by 40%. ([#1211](https://github.com/httpie/httpie/pull/1211))
- Added support for nested JSON syntax. ([#1169](https://github.com/httpie/httpie/issues/1169))
- Added `httpie plugins` interface for plugin management. ([#566](https://github.com/httpie/httpie/issues/566))
- Added support for Bearer authentication via `--auth-type=bearer` ([#1215](https://github.com/httpie/httpie/issues/1215)).
- Added support for quick conversions of pasted URLs into HTTPie calls by adding a space after the protocol name (`$ https ://pie.dev` → `https://pie.dev`). ([#1195](https://github.com/httpie/httpie/issues/1195))
- Added support for _sending_ multiple HTTP header lines with the same name. ([#130](https://github.com/httpie/httpie/issues/130))
- Added support for _receiving_ multiple HTTP headers lines with the same name. ([#1207](https://github.com/httpie/httpie/issues/1207))
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/httpie/issues/1212))
- Added support for automatically enabling `--stream` when `Content-Type` is `text/event-stream`. ([#376](https://github.com/httpie/httpie/issues/376))
- Added support for displaying the total elapsed time through `--meta`/`-vv` or `--print=m`. ([#243](https://github.com/httpie/httpie/issues/243))
- Added new `pie-dark`/`pie-light` (and `pie`) styles that match with [HTTPie for Web and Desktop](https://httpie.io/product). ([#1237](https://github.com/httpie/httpie/issues/1237))
- Added support for better error handling on DNS failures. ([#1248](https://github.com/httpie/httpie/issues/1248))
- Added support for storing prompted passwords in the local sessions. ([#1098](https://github.com/httpie/httpie/issues/1098))
- Added warnings about the `--ignore-stdin`, when there is no incoming data from stdin. ([#1255](https://github.com/httpie/httpie/issues/1255))
- Fixed crashing due to broken plugins. ([#1204](https://github.com/httpie/httpie/issues/1204))
- Fixed auto addition of XML declaration to every formatted XML response. ([#1156](https://github.com/httpie/httpie/issues/1156))
- Fixed highlighting when `Content-Type` specifies `charset`. ([#1242](https://github.com/httpie/httpie/issues/1242))
- Fixed an unexpected crash when `--raw` is used with `--chunked`. ([#1253](https://github.com/httpie/httpie/issues/1253))
- Changed the default Windows theme from `fruity` to `auto`. ([#1266](https://github.com/httpie/httpie/issues/1266))
## [2.6.0](https://github.com/httpie/cli/compare/2.5.0...2.6.0) (2021-10-14)
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)
[Whats new in HTTPie for Terminal 2.6.0 →](https://httpie.io/blog/httpie-2.6.0)
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/cli/issues/1130))
- Added charset auto-detection when `Content-Type` doesnt include it. ([#1110](https://github.com/httpie/cli/issues/1110), [#1168](https://github.com/httpie/cli/issues/1168))
- Added `--response-charset` to allow overriding the response encoding for terminal display purposes. ([#1168](https://github.com/httpie/cli/issues/1168))
- Added `--response-mime` to allow overriding the response mime type for coloring and formatting for the terminal. ([#1168](https://github.com/httpie/cli/issues/1168))
- Added the ability to silence warnings through using `-q` or `--quiet` twice (e.g. `-qq`) ([#1175](https://github.com/httpie/cli/issues/1175))
- Added installed plugin list to `--debug` output. ([#1165](https://github.com/httpie/cli/issues/1165))
- Fixed duplicate keys preservation in JSON data. ([#1163](https://github.com/httpie/cli/issues/1163))
- 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 charset auto-detection when `Content-Type` doesnt include it. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
- 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))
- Added the ability to silence warnings through using `-q` or `--quiet` twice (e.g. `-qq`) ([#1175](https://github.com/httpie/httpie/issues/1175))
- Added installed plugin list to `--debug` output. ([#1165](https://github.com/httpie/httpie/issues/1165))
- Fixed duplicate keys preservation in JSON data. ([#1163](https://github.com/httpie/httpie/issues/1163))
## [2.5.0](https://github.com/httpie/cli/compare/2.4.0...2.5.0) (2021-09-06)
## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06)
[Whats new in HTTPie for Terminal 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/cli/issues/534))
- Added support for XML formatting. ([#1129](https://github.com/httpie/cli/issues/1129))
- Added internal support for file-like object responses to improve adapter plugin support. ([#1094](https://github.com/httpie/cli/issues/1094))
- Fixed `--continue --download` with a single byte to be downloaded left. ([#1032](https://github.com/httpie/cli/issues/1032))
- Fixed `--verbose` HTTP 307 redirects with streamed request body. ([#1088](https://github.com/httpie/cli/issues/1088))
- Fixed handling of session files with `Cookie:` followed by other headers. ([#1126](https://github.com/httpie/cli/issues/1126))
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/cli/compare/2.3.0...2.4.0) (2021-02-06)
## [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/cli/issues/1029))
- Show a `--check-status` warning with `--quiet` as well, not only when the output is redirected. ([#1026](https://github.com/httpie/cli/issues/1026))
- Fixed upload with `--session` ([#1020](https://github.com/httpie/cli/issues/1020)).
- Fixed a missing blank line between request and response ([#1006](https://github.com/httpie/cli/issues/1006)).
- 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/cli/compare/2.2.0...2.3.0) (2020-10-25)
## [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/cli/issues/201)).
- Added support for multipart upload streaming ([#684](https://github.com/httpie/cli/issues/684)).
- 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/cli/issues/753)).
- 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/cli/issues/903)).
- 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/cli/issues/932)).
- Added out of the box SOCKS support with no extra installation ([#904](https://github.com/httpie/cli/issues/904)).
- 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/cli/issues/963)).
- Removed Tox testing entirely ([#943](https://github.com/httpie/cli/issues/943)).
- 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/cli/compare/2.1.0...2.2.0) (2020-06-18)
## [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/cli/issues/668)).
- Added support for `$XDG_CONFIG_HOME` ([#920](https://github.com/httpie/cli/issues/920)).
- Added support for `Set-Cookie`-triggered cookie expiration ([#853](https://github.com/httpie/cli/issues/853)).
- Added `--format-options` to allow disabling sorting, etc. ([#128](https://github.com/httpie/cli/issues/128))
- Added `--sorted` and `--unsorted` shortcuts for (un)setting all sorting-related `--format-options`. ([#128](https://github.com/httpie/cli/issues/128))
- Added `--ciphers` to allow configuring OpenSSL ciphers ([#870](https://github.com/httpie/cli/issues/870)).
- 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/cli/issues/718), [#719](https://github.com/httpie/cli/issues/719), [#852](https://github.com/httpie/cli/issues/852), [#934](https://github.com/httpie/cli/issues/934)).
- Fixed built-in plugins-related circular imports ([#925](https://github.com/httpie/cli/issues/925)).
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/cli/compare/2.0.0...2.1.0) (2020-04-18)
## [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/cli/issues/895)).
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/cli/issues/488)).
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/cli/issues/840)).
([#840](https://github.com/httpie/httpie/issues/840)).
## [2.0.0](https://github.com/httpie/cli/compare/1.0.3...2.0.0) (2020-01-12)
## [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
@ -170,7 +162,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Fixed an error when `stdin` was a closed fd.
- Improved `--debug` output formatting.
## [1.0.3](https://github.com/httpie/cli/compare/1.0.2...1.0.3) (2019-08-26)
## [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
@ -196,15 +188,15 @@ This project adheres to [Semantic Versioning](https://semver.org/).
Reported by Raul Onitza and Giulio Comi.
## [1.0.2](https://github.com/httpie/cli/compare/1.0.1...1.0.2) (2018-11-14)
## [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/cli/compare/1.0.0...1.0.1) (2018-11-14)
## [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/cli/compare/0.9.9...1.0.0) (2018-11-02)
## [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`
@ -215,11 +207,11 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Fixed default headers being incorrectly case-sensitive.
- Removed Python 2.6 support.
## [0.9.9](https://github.com/httpie/cli/compare/0.9.8...0.9.9) (2016-12-08)
## [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/cli/compare/0.9.6...0.9.8) (2016-12-08)
## [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.
@ -228,7 +220,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Improved `CTRL-C` interrupt handling.
- Added the standard exit status code `130` for keyboard interrupts.
## [0.9.6](https://github.com/httpie/cli/compare/0.9.4...0.9.6) (2016-08-13)
## [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
@ -247,7 +239,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Changed the pre-processing of request HTTP headers so that any leading
and trailing whitespace is removed.
## [0.9.4](https://github.com/httpie/cli/compare/0.9.3...0.9.4) (2016-07-01)
## [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
@ -271,7 +263,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- 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/cli/compare/0.9.2...0.9.3) (2016-01-01)
## [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)
@ -281,19 +273,19 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Fixed colors and formatting on Windows
- Fixed `--auth` prompt on Windows
## [0.9.2](https://github.com/httpie/cli/compare/0.9.1...0.9.2) (2015-02-24)
## [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/cli/compare/0.9.0...0.9.1) (2015-02-07)
## [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/cli/compare/0.8.0...0.9.0) (2015-01-31)
## [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
@ -312,7 +304,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Fixed `--output=/dev/null` on Linux
- Miscellaneous bugfixes
## [0.8.0](https://github.com/httpie/cli/compare/0.7.1...0.8.0) (2014-01-25)
## [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
@ -320,7 +312,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- 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/cli/compare/0.6.0...0.7.1) (2013-09-24)
## [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
@ -328,27 +320,27 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Improved `Content-Disposition` parsing for `--download` mode
- Update to Requests 2.0.0
## [0.6.0](https://github.com/httpie/cli/compare/0.5.1...0.6.0) (2013-06-03)
## [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/cli/compare/0.5.0...0.5.1) (2013-05-13)
## [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/cli/compare/0.4.1...0.5.0) (2013-04-27)
## [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/cli/compare/0.4.0...0.4.1) (2013-02-26)
## [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/cli/compare/0.3.0...0.4.0) (2013-02-22)
## [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
@ -357,7 +349,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Mutually exclusive arguments can be specified multiple times. The
last value is used
## [0.3.0](https://github.com/httpie/cli/compare/0.2.7...0.3.0) (2012-09-21)
## [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
@ -372,7 +364,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
(`--pretty=all`, `--pretty=colors` and `--pretty=format`)
`--ugly` has bee removed in favor of `--pretty=none`
## [0.2.7](https://github.com/httpie/cli/compare/0.2.5...0.2.7) (2012-08-07)
## [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
@ -389,7 +381,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Fixed printing of `multipart/form-data` requests
- Renamed `--traceback` to `--debug`
## [0.2.6](https://github.com/httpie/cli/compare/0.2.5...0.2.6) (2012-07-26)
## [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`)
@ -404,7 +396,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Added query string parameters (`param==value`)
- Added support for terminal colors under Windows
## [0.2.5](https://github.com/httpie/cli/compare/0.2.2...0.2.5) (2012-07-17)
## [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
@ -415,20 +407,20 @@ This project adheres to [Semantic Versioning](https://semver.org/).
`--verbose`
- Fixed Content-Type for requests with no data
## [0.2.2](https://github.com/httpie/cli/compare/0.2.1...0.2.2) (2012-06-24)
## [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/cli/compare/0.2.0...0.2.1) (2012-06-13)
## [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/cli/compare/0.1.6...0.2.0) (2012-04-25)
## [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
@ -440,18 +432,18 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Added support for field name escaping
- Many bug fixes
## [0.1.6](https://github.com/httpie/cli/compare/0.1.5...0.1.6) (2012-03-04)
## [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/cli/compare/0.1.4...0.1.5) (2012-03-04)
## [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/cli/compare/b966efa...0.1.4) (2012-02-28)
## [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/cli/commit/b966efa) (2012-02-25)
## [0.1.0](https://github.com/httpie/httpie/commit/b966efa) (2012-02-25)
- Initial public release

View File

@ -19,7 +19,7 @@ $ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
## 2. Contributing Code and Docs
Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/cli/issues)
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
@ -38,13 +38,13 @@ 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/cli/blob/master/CHANGELOG.md) entry for your changes.
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/cli> and fork the project repository.
Go to <https://github.com/httpie/httpie> and fork the project repository.
```bash
# Clone your fork
@ -59,7 +59,7 @@ $ git checkout -b my_topical_branch
#### Setup
The [Makefile](https://github.com/httpie/cli/blob/master/Makefile) contains a bunch of tasks to get you started.
The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started.
You can run `$ make` to see all the available tasks.
To get started, run the command below, which:
@ -112,7 +112,7 @@ and that `make pycodestyle` passes.
Please add tests for any new features and bug fixes.
When you open a Pull Request, [GitHub Actions](https://github.com/httpie/cli/actions) will automatically run HTTPies [test suite](https://github.com/httpie/cli/tree/master/tests) against your code, so please make sure all checks pass.
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
@ -144,7 +144,7 @@ $ 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/cli/blob/master/Makefile) for additional development utilities.
See [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) for additional development utilities.
#### Running benchmarks
@ -154,7 +154,7 @@ with the master branch of your repository (or a fresh checkout of HTTPie master,
`--fresh`) and report the results back.
```bash
$ python extras/profiling/run.py
$ python extras/benchmarks/run.py
```
The benchmarks can also be run on the CI. Since it is a long process, it requires manual
@ -209,4 +209,4 @@ $ python -m pytest
______________________________________________________________________
Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/cli/blob/master/AUTHORS.md)!
Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/httpie/blob/master/AUTHORS.md)!

View File

@ -4,5 +4,5 @@ include CHANGELOG.md
include AUTHORS.md
include docs/README.md
# <https://github.com/httpie/cli/issues/182>
# <https://github.com/httpie/httpie/issues/182>
recursive-include tests/ *

View File

@ -34,7 +34,7 @@ default: list-tasks
list-tasks:
@echo Available tasks:
@echo ----------------
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | grep -E -v -e '^[^[:alnum:]]' -e '^$@$$'
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
@echo
@ -231,15 +231,15 @@ brew-test:
brew audit --strict httpie
###############################################################################
# Generated content
# Regeneration
###############################################################################
content: man installation-docs
regen-all: regen-man-pages regen-install-methods
man: install
regen-man-pages: install
@echo $(H1)Regenerate man pages$(H1END)
$(VENV_PYTHON) extras/scripts/generate_man_pages.py
installation-docs:
regen-install-methods:
@echo $(H1)Updating installation instructions in the docs$(H1END)
$(VENV_PYTHON) docs/installation/generate.py

View File

@ -1,31 +1,10 @@
<h2 align="center">
<a href="https://httpie.io" target="blank_">
<img height="100" alt="HTTPie" src="https://raw.githubusercontent.com/httpie/cli/master/docs/httpie-logo.svg" />
</a>
<br>
HTTPie CLI: human-friendly HTTP client for the API era
</h2>
<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/>
<div align="center">
[![HTTPie for Desktop](https://img.shields.io/static/v1?label=HTTPie&message=Desktop&color=4B78E6)](https://httpie.io/product)
[![](https://img.shields.io/static/v1?label=HTTPie&message=Web%20%26%20Mobile&color=73DC8C)](https://httpie.io/app)
[![](https://img.shields.io/static/v1?label=HTTPie&message=CLI&color=FA9BFA)](https://httpie.io/cli)
[![Twitter](https://img.shields.io/twitter/follow/httpie?style=flat&color=%234B78E6&logoColor=%234B78E6)](https://twitter.com/httpie)
[![Chat](https://img.shields.io/discord/725351238698270761?style=flat&label=Chat%20on%20Discord&color=%23FA9BFA)](https://httpie.io/discord)
</div>
<div align="center">
[![Docs](https://img.shields.io/badge/stable%20docs-httpie.io%2Fdocs%2Fcli-brightgreen?style=flat&color=%2373DC8C&label=Docs)](https://httpie.org/docs/cli)
[![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/actions/workflow/status/httpie/cli/tests.yml?branch=master&color=%23FA9BFA&label=Build)](https://github.com/httpie/cli/actions)
[![Coverage](https://img.shields.io/codecov/c/github/httpie/cli?style=flat&label=Coverage&color=%2373DC8C)](https://codecov.io/gh/httpie/cli)
[![PyPi downloads](https://img.shields.io/pepy/dt/httpie?style=flat&label=Downloads%20from%20PyPi%20only&color=4B78E6)](https://www.pepy.tech/projects/httpie)
</div>
# 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.
@ -33,14 +12,14 @@ HTTPie is designed for testing, debugging, and generally interacting with APIs &
The `http` & `https` commands allow for creating and sending arbitrary HTTP requests.
They use simple and natural syntax and provide formatted and colorized output.
<div align="center">
<img src="https://raw.githubusercontent.com/httpie/cli/master/docs/httpie-animation.gif" alt="HTTPie in action" width="100%"/>
</div>
[![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%"/>
## We lost 54k GitHub stars
@ -74,25 +53,25 @@ Please note we recently accidentally made this repo private for a moment, and Gi
Hello World:
```bash
https httpie.io/hello
$ 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
$ 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
$ 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/cli/issues/83) with [authentication](https://httpie.io/docs#authentication):
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/cli/issues/83/comments body='HTTPie is awesome! :heart:'
$ 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)
@ -103,11 +82,11 @@ http -a USERNAME POST https://api.github.com/repos/httpie/cli/issues/83/comments
- 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/cli/issues) for bug reports and feature requests.
- 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/cli/issues) and [Pull Requests](https://github.com/httpie/cli/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/cli/issues) using one of the templates provided.
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/cli/blob/master/CONTRIBUTING.md)
[See contribution guide →](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md)

View File

@ -19,7 +19,7 @@ This documentation is best viewed at [httpie.io/docs](https://httpie.org/docs).
You can select your corresponding HTTPie version as well as run examples directly from the browser using a [termible.io](https://termible.io?utm_source=httpie-readme) embedded terminal.
If you are reading this on GitHub, then this text covers the current *development* version.
You are invited to submit fixes and improvements to the docs by editing [this file](https://github.com/httpie/cli/blob/master/docs/README.md).
You are invited to submit fixes and improvements to the docs by editing [this file](https://github.com/httpie/httpie/blob/master/docs/README.md).
</div>
@ -126,66 +126,6 @@ $ choco upgrade httpie
### Linux
#### Debian and Ubuntu
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.
```bash
# Install httpie
$ curl -SsL https://packages.httpie.io/deb/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/httpie.gpg
$ sudo echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" > /etc/apt/sources.list.d/httpie.list
$ sudo apt update
$ sudo apt install httpie
```
```bash
# Upgrade httpie
$ sudo apt update && sudo apt upgrade httpie
```
#### Fedora
```bash
# Install httpie
$ dnf install httpie
```
```bash
# Upgrade httpie
$ dnf upgrade httpie
```
#### CentOS and RHEL
Also works for other RHEL-derived distributions like ClearOS, Oracle Linux, etc.
```bash
# Install httpie
$ yum install epel-release
$ yum install httpie
```
```bash
# Upgrade httpie
$ yum upgrade httpie
```
#### Single binary executables
Get the standalone HTTPie Linux executables when you don't want to go through the full installation process.
```bash
# Install httpie
$ https --download packages.httpie.io/binaries/linux/http-latest -o http
$ ln -ls ./http ./https
$ chmod +x ./http ./https
```
```bash
# Upgrade httpie
$ https --download packages.httpie.io/binaries/linux/http-latest -o http
```
#### Snapcraft (Linux)
To install [Snapcraft](https://snapcraft.io/), see [its installation](https://snapcraft.io/docs/installing-snapd).
@ -216,6 +156,51 @@ $ brew update
$ brew upgrade httpie
```
#### Debian and Ubuntu
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.
```bash
# Install httpie
$ curl -SsL https://packages.httpie.io/deb/KEY.gpg | apt-key add -
$ curl -SsL -o /etc/apt/sources.list.d/httpie.list https://packages.httpie.io/deb/httpie.list
$ apt update
$ apt install httpie
```
```bash
# Upgrade httpie
$ apt update
$ apt upgrade httpie
```
#### Fedora
```bash
# Install httpie
$ dnf install httpie
```
```bash
# Upgrade httpie
$ dnf upgrade httpie
```
#### CentOS and RHEL
Also works for other RHEL-derived distributions like ClearOS, Oracle Linux, etc.
```bash
# Install httpie
$ yum install epel-release
$ yum install httpie
```
```bash
# Upgrade httpie
$ yum upgrade httpie
```
#### Arch Linux
Also works for other Arch-derived distributions like ArcoLinux, EndeavourOS, Artix Linux, etc.
@ -230,6 +215,21 @@ $ pacman -Syu httpie
$ pacman -Syu
```
#### Single binary executables
Get the standalone HTTPie Linux executables when you don't want to go through the full installation process
```bash
# Install httpie
$ https --download packages.httpie.io/binaries/linux/http-latest -o http
$ chmod +x ./http
```
```bash
# Upgrade httpie
$ https --download packages.httpie.io/binaries/linux/http-latest -o http
```
### FreeBSD
#### FreshPorts
@ -250,39 +250,36 @@ $ pkg upgrade www/py-httpie
### Unstable version
If you want to try out the latest version of HTTPie that hasn't been officially released yet, you can install the development or unstable version directly from the master branch on GitHub. However, keep in mind that the development version is a work in progress and may not be as reliable as the stable version.
You can also install the latest unreleased development version directly from the `master` branch on GitHub.
It is a work-in-progress of a future stable release so the experience might be not as smooth.
You can use the following command to install the development version of HTTPie on Linux, macOS, Windows, or FreeBSD operating systems. With this command, the code present in the `master` branch is downloaded and installed using `pip`.
You can install it on Linux, macOS, Windows, or FreeBSD with `pip`:
```bash
$ python -m pip install --upgrade https://github.com/httpie/cli/archive/master.tar.gz
$ python -m pip install --upgrade https://github.com/httpie/httpie/archive/master.tar.gz
```
There are other ways to install the development version of HTTPie on macOS and Linux.
You can install it using Homebrew by running the following commands:
Or on macOS, and Linux, with Homebrew:
```bash
$ brew uninstall --force httpie
$ brew install --HEAD httpie
```
You can install it using Snapcraft by running the following commands:
And even on macOS, and Linux, with Snapcraft:
```bash
$ snap remove httpie
$ snap install httpie --edge
```
To verify the installation, you can compare the [version identifier on GitHub](https://github.com/httpie/cli/blob/master/httpie/__init__.py#L6) with the one available on your machine. You can check the version of HTTPie on your machine by using the command `http --version`.
Verify that now you have the [current development version identifier](https://github.com/httpie/httpie/blob/master/httpie/__init__.py#L6) with the `.dev0` suffix, for example:
```bash
$ http --version
# 3.X.X.dev0
```
Note that on your machine, the version name will have the `.dev0` suffix.
## Usage
Hello World:
@ -325,10 +322,10 @@ Build and print a request without sending it using [offline mode](#offline-mode)
$ 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/cli/issues/83) with [authentication](#authentication):
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](#authentication):
```bash
$ http -a USERNAME POST https://api.github.com/repos/httpie/cli/issues/83/comments body='HTTPie is awesome! :heart:'
$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:'
```
Upload a file using [redirected input](#redirected-input):
@ -915,8 +912,6 @@ http --offline --print=B pie.dev/post \
]
```
Sending scalar JSON types (a single `null`, `true`, `false`, string or number) as the top-level object is impossible using the key/value syntax. But you can still pass it via [`--raw='<value>'`](#raw-request-body).
##### Escaping behavior
Nested JSON syntax uses the same [escaping rules](#escaping-rules) as
@ -1176,11 +1171,11 @@ User-Agent: HTTPie/<version>
Host: <taken-from-URL>
```
All of these can be overwritten or unset (see below).
Any of these can be overwritten and some of them unset (see below).
### Reading headers from a file
You can read headers from a file by using the `:@` operator. This would also effectively strip the newlines from the end. See [file based separators](#file-based-separators) for more examples.
You can read headers from a file by using the `:@` operator. This would also effectively strip the newlines from the end. See [#file-based-separators] for more examples.
```bash
$ http pie.dev/headers X-Data:@files/text.txt
@ -1458,8 +1453,7 @@ $ http --proxy=http:http://user:pass@10.10.1.10:3128 example.org
### Environment variables
You can also configure proxies by environment variables `ALL_PROXY`, `HTTP_PROXY` and `HTTPS_PROXY`, and the underlying
[Requests library](https://requests.readthedocs.io/en/latest/) will pick them up.
You can also configure proxies by environment variables `ALL_PROXY`, `HTTP_PROXY` and `HTTPS_PROXY`, and the underlying [Requests library](https://python-requests.org/) will pick them up.
If you want to disable proxies configured through the environment variables for certain hosts, you can specify them in `NO_PROXY`.
In your `~/.bash_profile`:
@ -1754,7 +1748,7 @@ $ http pie.dev/post <<<'{"name": "John"}'
You can even pipe web services together using HTTPie:
```bash
$ http GET https://api.github.com/repos/httpie/cli | http POST pie.dev/post
$ http GET https://api.github.com/repos/httpie/httpie | http POST pie.dev/post
```
You can use `cat` to enter multiline data on the terminal:
@ -2002,7 +1996,7 @@ HTTPie features a download mode in which it acts similarly to `wget`.
When enabled using the `--download, -d` flag, response headers are printed to the terminal (`stderr`), and a progress bar is shown while the response body is being saved to a file.
```bash
$ http --download https://github.com/httpie/cli/archive/master.tar.gz
$ http --download https://github.com/httpie/httpie/archive/master.tar.gz
```
```http
@ -2031,7 +2025,7 @@ To prevent data loss by overwriting, HTTPie adds a unique numerical suffix to th
You can also redirect the response body to another program while the response headers and progress are still shown in the terminal:
```bash
$ http -d https://github.com/httpie/cli/archive/master.tar.gz | tar zxf -
$ http -d https://github.com/httpie/httpie/archive/master.tar.gz | tar zxf -
```
### Resuming downloads
@ -2313,7 +2307,7 @@ These flags are available for both `sessions upgrade` and `sessions upgrade-all`
| Option | Description |
|------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--bind-cookies` | Bind all previously [unbound cookies](#host-based-cookie-policy) to the sessions host ([context](https://github.com/httpie/cli/security/advisories/GHSA-9w4w-cpc8-h2fq)). |
| `--bind-cookies` | Bind all previously [unbound cookies](#host-based-cookie-policy) to the sessions host ([context](https://github.com/httpie/httpie/security/advisories/GHSA-9w4w-cpc8-h2fq)). |
## Config
@ -2400,13 +2394,16 @@ fi
The default behavior of automatically reading `stdin` is typically not desirable during non-interactive invocations.
You most likely want to use the `--ignore-stdin` option to disable it.
It's important to note that without the `--ignore-stdin` option, HTTPie may appear to have stopped working (hang). This happens because, in situations where HTTPie is invoked outside of an interactive session, such as from a cron job, `stdin` is not connected to a terminal. This means that the rules for [redirected input](#redirected-input) will be followed. When `stdin` is redirected, HTTPie assumes that the input will contain the request body, and it waits for the input to be provided. But, since there is neither any input data nor an end-of-file (`EOF`) signal, HTTPie gets stuck. To avoid this problem, the `--ignore-stdin` flag should be used in scripts, unless data is being piped to HTTPie.
It is a common *gotcha* that without this option HTTPie seemingly hangs.
What happens is that when HTTPie is invoked, for example, from a cron job, `stdin` is not connected to a terminal.
Therefore, the rules for [redirected input](#redirected-input) apply, i.e. HTTPie starts to read it expecting that the request body will be passed through.
And since theres neither data nor `EOF`, it will get stuck. So unless youre piping some data to HTTPie, the `--ignore-stdin` flag should be used in scripts.
To prevent your program from becoming unresponsive when the server fails to respond, it's a good idea to use the `--timeout` option to set a connection timeout limit.
Also, it might be good to set a connection `--timeout` limit to prevent your program from hanging if the server never responds.
## Plugin manager
HTTPie offers extensibility through a [plugin API](https://github.com/httpie/cli/blob/master/httpie/plugins/base.py),
HTTPie offers extensibility through a [plugin API](https://github.com/httpie/httpie/blob/master/httpie/plugins/base.py),
and there are dozens of plugins available to try!
They add things like new authentication methods ([akamai/httpie-edgegrid](https://github.com/akamai/httpie-edgegrid)),
transport mechanisms ([httpie/httpie-unixsocket](https://github.com/httpie/httpie-unixsocket)),
@ -2546,7 +2543,7 @@ All changes are recorded in the [change log](#change-log).
HTTPie has the following community channels:
- [GitHub Issues](https://github.com/httpie/cli/issues) for bug reports and feature requests
- [GitHub Issues](https://github.com/httpie/httpie/issues) for bug reports and feature requests
- [Discord server](https://httpie.io/discord) to ask questions, discuss features, and for general API development discussion
- [StackOverflow](https://stackoverflow.com) to ask questions (make sure to use the [httpie](https://stackoverflow.com/questions/tagged/httpie) tag)
@ -2556,7 +2553,7 @@ HTTPie has the following community channels:
Under the hood, HTTPie uses these two amazing libraries:
- [Requests](https://requests.readthedocs.io/en/latest/) — Python HTTP library for humans
- [Requests](https://python-requests.org) — Python HTTP library for humans
- [Pygments](https://pygments.org/) — Python syntax highlighter
#### HTTPie friends
@ -2577,25 +2574,24 @@ Helpers to convert from other client tools:
### Contributing
See [CONTRIBUTING](https://github.com/httpie/cli/blob/master/CONTRIBUTING.md).
See [CONTRIBUTING](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md).
### Security policy
See [github.com/httpie/cli/security/policy](https://github.com/httpie/cli/security/policy).
See [github.com/httpie/httpie/security/policy](https://github.com/httpie/httpie/security/policy).
### Change log
See [CHANGELOG](https://github.com/httpie/cli/blob/master/CHANGELOG.md).
See [CHANGELOG](https://github.com/httpie/httpie/blob/master/CHANGELOG.md).
### Artwork
- [README Animation](https://github.com/httpie/cli/blob/master/docs/httpie-animation.gif) by [Allen Smith](https://github.com/loranallensmith).
- [README Animation](https://github.com/httpie/httpie/blob/master/docs/httpie-animation.gif) by [Allen Smith](https://github.com/loranallensmith).
### Licence
BSD-3-Clause: [LICENSE](https://github.com/httpie/cli/blob/master/LICENSE).
BSD-3-Clause: [LICENSE](https://github.com/httpie/httpie/blob/master/LICENSE).
### Authors
[Jakub Roztocil](https://roztocil.co) ([@jakubroztocil](https://twitter.com/jakubroztocil)) created HTTPie and [these fine people](https://github.com/httpie/cli/blob/master/AUTHORS.md) have contributed.
[Jakub Roztocil](https://roztocil.co) ([@jakubroztocil](https://twitter.com/jakubroztocil)) created HTTPie and [these fine people](https://github.com/httpie/httpie/blob/master/AUTHORS.md) have contributed.

View File

@ -1,3 +1,3 @@
Here we maintain a database of contributors, from which we generate credits on release blog posts and social media.
Here we maintain a database of contributors, from which we generate credits on release blog posts and social medias.
For the HTTPie blog see: <https://httpie.io/blog>.

View File

@ -55,7 +55,7 @@ def build_docs_structure(database: Database):
tree = database[KEY_DOC_STRUCTURE]
structure = []
for platform, tools_ids in tree.items():
assert platform.isalnum(), f'{platform=} must be alphanumeric for generated links to work'
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

View File

@ -37,13 +37,13 @@ tools:
package: https://packages.debian.org/sid/web/httpie
commands:
install:
- curl -SsL https://packages.httpie.io/deb/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/httpie.gpg
# - curl -SsL -o /etc/apt/sources.list.d/httpie.list https://packages.httpie.io/deb/httpie.list
- sudo echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" > /etc/apt/sources.list.d/httpie.list
- sudo apt update
- sudo apt install httpie
- curl -SsL https://packages.httpie.io/deb/KEY.gpg | apt-key add -
- curl -SsL -o /etc/apt/sources.list.d/httpie.list https://packages.httpie.io/deb/httpie.list
- apt update
- apt install httpie
upgrade:
- sudo apt update && sudo apt upgrade httpie
- apt update
- apt upgrade httpie
brew-mac:
title: Homebrew

View File

@ -3,7 +3,7 @@
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/cli/issues/).
- 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
@ -25,7 +25,7 @@ The overall release process starts simple:
## Company-specific tasks
- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/cli/blob/master/docs/config.json).
- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/httpie/blob/master/docs/config.json).
- Update the [contributors list](../contributors).
- Update the HTTPie version bundled into [Termible](https://termible.io/) ([example](https://github.com/httpie/termible/pull/1)).
@ -44,4 +44,4 @@ A more complete state of deployment can be found on [repology](https://repology.
| [Snapcraft](snapcraft/) | **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/cli/issues/).
: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

@ -13,7 +13,7 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
The brew deployment is completely automated, and only requires a trigger to [`Release on Homebrew`](https://github.com/httpie/cli/actions/workflows/release-brew.yml) action
The brew deployment is completely automated, and only requires a trigger to [`Release on Homebrew`](https://github.com/httpie/httpie/actions/workflows/release-brew.yml) action
from the release manager.
If it is needed to be done manually, the following command can be used:
@ -26,6 +26,6 @@ which will bump the formula, and create a PR against the package index.
## Hacking
Make your changes, test the formula through the [`Test Brew Package`](https://github.com/httpie/cli/actions/workflows/test-package-mac-brew.yml) action
Make your changes, test the formula through the [`Test Brew Package`](https://github.com/httpie/httpie/actions/workflows/test-package-mac-brew.yml) action
and then finally submit your patch to [`homebrew-core`](https://github.com/Homebrew/homebrew-core`)

View File

@ -6,7 +6,7 @@ class Httpie < Formula
url "https://files.pythonhosted.org/packages/32/85/bb095699be20cc98731261cb80884e9458178f8fef2a38273530ce77c0a5/httpie-3.1.0.tar.gz"
sha256 "2e4a2040b84a912e65c01fb34f7aafe88cad2a3af2da8c685ca65080f376feda"
license "BSD-3-Clause"
head "https://github.com/httpie/cli.git", branch: "master"
head "https://github.com/httpie/httpie.git", branch: "master"
bottle do
sha256 cellar: :any_skip_relocation, arm64_monterey: "9bb6e8c1ef5ba8b019ddedd7e908dd2174da695351aa9a238dfb28b0f57ef005"

View File

@ -7,7 +7,7 @@ pkgname=httpie
pkgver=2.6.0
pkgrel=1
pkgdesc="human-friendly CLI HTTP client for the API era"
url="https://github.com/httpie/cli"
url="https://github.com/httpie/httpie"
depends=('python-defusedxml'
'python-pygments'
'python-pysocks'
@ -22,7 +22,7 @@ conflicts=(python-httpie)
replaces=(python-httpie python2-httpie)
license=('BSD')
arch=('any')
source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/cli/archive/$pkgver.tar.gz")
source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/httpie/archive/$pkgver.tar.gz")
sha256sums=('3bcd9a8cb2b11299da12d3af36c095c6d4b665e41c395898a07f1ae4d99fc14a')
build() {

View File

@ -17,7 +17,7 @@ command (due to the underlying `httpie cli plugins` interface) explicitly depend
## Overall process
The [`Release as Standalone Linux Binary`](https://github.com/httpie/cli/actions/workflows/release-linux-standalone.yml) will be automatically
The [`Release as Standalone Linux Binary`](https://github.com/httpie/httpie/actions/workflows/release-linux-standalone.yml) will be automatically
triggered when a new release is created, and it will submit the `.deb` package as a release asset.
For making that asset available for all debian users, the release manager needs to go to the [`httpie/debian.httpie.io`](https://github.com/httpie/debian.httpie.io) repo

View File

@ -15,7 +15,7 @@ The current maintainer is [Miro Hrončok](https://github.com/hroncok).
## Overall process
We added the [.packit.yaml](https://github.com/httpie/cli/blob/master/.packit.yaml) local file.
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.

View File

@ -5,7 +5,7 @@ Summary: A Curl-like tool for humans
License: BSD
URL: https://httpie.org/
Source0: https://github.com/httpie/cli/archive/%{version}/%{name}-%{version}.tar.gz
Source0: https://github.com/httpie/httpie/archive/%{version}/%{name}-%{version}.tar.gz
BuildArch: noarch

View File

@ -19,7 +19,7 @@ Open a pull request to update the [downstream file](https://github.com/macports/
```bash
# Download the archive
$ wget https://api.github.com/repos/httpie/cli/tarball/2.5.0
$ wget https://api.github.com/repos/httpie/httpie/tarball/2.5.0
# Size
$ stat --printf="%s\n" 2.5.0

View File

@ -13,7 +13,7 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
Trigger the [`Release on Snap`](https://github.com/httpie/cli/actions/workflows/release-snap.yml) action, which will
Trigger the [`Release on Snap`](https://github.com/httpie/httpie/actions/workflows/release-snap.yml) action, which will
create a snap package for HTTPie and then push it to Snap Store in the following channels:
- Edge
@ -37,7 +37,7 @@ From inside the container:
```bash
# Clone
git clone --depth=1 https://github.com/httpie/cli.git
git clone --depth=1 https://github.com/httpie/httpie.git
cd httpie
# Build

View File

@ -14,7 +14,7 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
After having successfully [built and tested](#hacking) the package, either trigger the
[`Release on Chocolatey`](https://github.com/httpie/cli/actions/workflows/release-choco.yml) action
[`Release on Chocolatey`](https://github.com/httpie/httpie/actions/workflows/release-choco.yml) action
to push it to the `Chocolatey` store or use the CLI:
```bash
@ -29,7 +29,7 @@ sets of reviews (some of them are done manually).
```bash
# Clone
git clone --depth=1 https://github.com/httpie/cli.git
git clone --depth=1 https://github.com/httpie/httpie.git
cd httpie/docs/packaging/windows-chocolatey
# Build

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>httpie</id>
<version>3.2.2</version>
<version>3.2.1</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.
@ -30,16 +30,16 @@ Main features:
<authors>HTTPie</authors>
<owners>jakubroztocil</owners>
<copyright>2012-2022 Jakub Roztocil</copyright>
<licenseUrl>https://raw.githubusercontent.com/httpie/cli/master/LICENSE</licenseUrl>
<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/cli/releases/tag/3.2.2).</releaseNotes>
<releaseNotes>See the [changelog](https://github.com/httpie/httpie/releases/tag/3.2.0).</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/cli/tree/master/docs/packaging/windows-chocolatey</packageSourceUrl>
<projectSourceUrl>https://github.com/httpie/cli</projectSourceUrl>
<packageSourceUrl>https://github.com/httpie/httpie/tree/master/docs/packaging/windows-chocolatey</packageSourceUrl>
<projectSourceUrl>https://github.com/httpie/httpie</projectSourceUrl>
<docsUrl>https://httpie.io/docs</docsUrl>
<bugTrackerUrl>https://github.com/httpie/cli/issues</bugTrackerUrl>
<bugTrackerUrl>https://github.com/httpie/httpie/issues</bugTrackerUrl>
<dependencies>
<dependency id="python3" version="3.7" />
</dependencies>

View File

@ -1,5 +1,5 @@
.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py.
.TH http 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.TH http 1 "2022-05-06" "HTTPie 3.2.1" "HTTPie Manual"
.SH NAME
http
.SH SYNOPSIS
@ -399,7 +399,7 @@ The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
\[dq]bearer\[dq]: Bearer HTTP Auth
To see all available auth types on your system, including ones installed via plugins, run:
For finding out all available authentication types in your system, try:
$ http \fB\,--auth-type\/\fR
@ -510,12 +510,10 @@ are shown here).
A string in the OpenSSL cipher list format.
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
A string in the OpenSSL cipher list format. By default, the following
is used:
ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDH+AESGCM:DH+AESGCM:ECDH+AES:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!eNULL:!MD5:!DSS
@ -597,4 +595,4 @@ For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/httpie/cli/issues
https://github.com/httpie/httpie/issues

View File

@ -1,5 +1,5 @@
.\" This file is auto-generated from the parser declaration in httpie/manager/cli.py by extras/scripts/generate_man_pages.py.
.TH httpie 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.TH httpie 1 "2022-05-06" "HTTPie 3.2.1" "HTTPie Manual"
.SH NAME
httpie
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py.
.TH https 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.TH https 1 "2022-05-06" "HTTPie 3.2.1" "HTTPie Manual"
.SH NAME
https
.SH SYNOPSIS
@ -399,7 +399,7 @@ The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
\[dq]bearer\[dq]: Bearer HTTP Auth
To see all available auth types on your system, including ones installed via plugins, run:
For finding out all available authentication types in your system, try:
$ http \fB\,--auth-type\/\fR
@ -510,12 +510,10 @@ are shown here).
A string in the OpenSSL cipher list format.
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
A string in the OpenSSL cipher list format. By default, the following
is used:
ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDH+AESGCM:DH+AESGCM:ECDH+AES:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!eNULL:!MD5:!DSS
@ -597,4 +595,4 @@ For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/httpie/cli/issues
https://github.com/httpie/httpie/issues

View File

@ -7,13 +7,13 @@ This directory contains the build scripts for creating:
- A self-contained binary executable for the HTTPie itself
- `httpie.deb` and `httpie.rpm` packages for Debian and Fedora.
The process of constructing them are fully automated, and can be easily done through the [`Release as Standalone Linux Package`](https://github.com/httpie/cli/actions/workflows/release-linux-standalone.yml)
The process of constructing them are fully automated, and can be easily done through the [`Release as Standalone Linux Package`](https://github.com/httpie/httpie/actions/workflows/release-linux-standalone.yml)
action. Once it finishes, the release artifacts will be attached in the summary page of the triggered run.
## Hacking
The main entry point for the package builder is the [`build.py`](https://github.com/httpie/cli/blob/master/extras/packaging/linux/build.py). It
The main entry point for the package builder is the [`build.py`](https://github.com/httpie/httpie/blob/master/extras/packaging/linux/build.py). It
contains 2 major methods:
- `build_binaries`, for the self-contained executables
@ -39,7 +39,7 @@ Since the `httpie` depends on having a pip executable, we explicitly depend on t
### Docker Image
This directory also contains a [docker image](https://github.com/httpie/cli/blob/master/extras/packaging/linux/Dockerfile) which helps
This directory also contains a [docker image](https://github.com/httpie/httpie/blob/master/extras/packaging/linux/Dockerfile) which helps
building our standalone binaries in an isolated environment with the lowest possible library versions. This is important, since even though
the executables are standalone they still depend on some main system C libraries (like `glibc`) so we need to create our executables inside
an environment with a very old (but not deprecated) glibc version. It makes us soundproof for all active Ubuntu/Debian versions.

View File

@ -10,7 +10,7 @@ Ensure the following requirements are satisfied:
- Python 3.7+
- `pyperf`
Then, run the `extras/profiling/run.py`:
Then, run the `extras/benchmarks/run.py`:
```console
$ python extras/profiling/run.py
@ -28,7 +28,7 @@ on both of them. It will compare the results and print it as a markdown table:
| Geometric mean | (ref) | 1.10x faster |
If your `master` branch is not up-to-date, you can get a fresh clone by passing
`--fresh` option. This way, the benchmark runner will clone the `httpie/cli`
`--fresh` option. This way, the benchmark runner will clone the `httpie/httpie`
repo from `GitHub` and use it as the baseline.
You can customize these branches by passing `--local-repo`/`--target-branch`,

View File

@ -9,11 +9,11 @@ timings.
The benchmarks are run through 'pyperf', which allows to
do get very precise results. For micro-benchmarks like startup,
please run `pyperf system tune` to get even more accurate results.
please run `pyperf system tune` to get even more acurrate results.
Examples:
# Run everything as usual, the default is that we do 3 warm-up runs
# Run everything as usual, the default is that we do 3 warmup runs
# and 5 actual runs.
$ python extras/profiling/benchmarks.py
@ -188,7 +188,7 @@ DownloadRunner('download', '`http --download :/big_file.txt` (3GB)', '3G')
def main() -> None:
# PyPerf will bring it's own argument parser, so configure the script.
# The somewhat fast and also precise enough configuration is this. We run
# benchmarks 3 times to warm up (e.g especially for download benchmark, this
# benchmarks 3 times to warmup (e.g especially for download benchmark, this
# is important). And then 5 actual runs where we record.
sys.argv.extend(
['--worker', '--loops=1', '--warmup=3', '--values=5', '--processes=2']

View File

@ -19,19 +19,19 @@ which would include additional dependencies like pyOpenSSL.
Examples:
# Run everything as usual, and compare last commit with master
$ python extras/profiling/run.py
$ python extras/benchmarks/run.py
# Include complex environments
$ python extras/profiling/run.py --complex
$ python extras/benchmarks/run.py --complex
# Compare against a fresh copy
$ python extras/profiling/run.py --fresh
$ python extras/benchmarks/run.py --fresh
# Compare against a custom branch of a custom repo
$ python extras/profiling/run.py --target-repo my_repo --target-branch my_branch
$ python extras/benchmarks/run.py --target-repo my_repo --target-branch my_branch
# Debug changes made on this script (only run benchmarks once)
$ python extras/profiling/run.py --debug
$ python extras/benchmarks/run.py --debug
"""
import dataclasses
@ -50,7 +50,7 @@ from typing import (IO, Dict, Generator, Iterable, List, Optional,
BENCHMARK_SCRIPT = Path(__file__).parent / 'benchmarks.py'
CURRENT_REPO = Path(__file__).parent.parent.parent
GITHUB_URL = 'https://github.com/httpie/cli.git'
GITHUB_URL = 'https://github.com/httpie/httpie.git'
TARGET_BRANCH = 'master'
# Additional dependencies for --complex

View File

@ -1,25 +1,20 @@
import os
import re
from contextlib import contextmanager
from pathlib import Path
from typing import Optional, Iterator, Iterable
# So that httpie.cli.definition can provide man-page-specific output. Must be set before importing httpie.
os.environ['HTTPIE_BUILDING_MAN_PAGES'] = '1'
import httpie
from httpie.cli.definition import options as core_options, IS_MAN_PAGE
from httpie.cli.definition import options as core_options
from httpie.cli.options import ParserSpec
from httpie.manager.cli import options as manager_options
from httpie.output.ui.rich_help import OptionsHighlighter, to_usage
from httpie.output.ui.rich_utils import render_as_string
from httpie.utils import split
assert IS_MAN_PAGE, 'CLI definition does not understand were building man pages'
# Escape certain characters, so they are rendered properly on all terminals.
# <https://man7.org/linux/man-pages/man7/groff_char.7.html>
# Escape certain characters so they are rendered properly on
# all terminals.
# https://man7.org/linux/man-pages/man7/groff_char.7.html
ESCAPE_MAP = {
'"': '\[dq]',
"'": '\[aq]',
@ -37,7 +32,6 @@ OPTION_HIGHLIGHT_RE = re.compile(
OptionsHighlighter.highlights[0]
)
class ManPageBuilder:
def __init__(self):
self.source = []
@ -131,7 +125,7 @@ def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool =
with builder.section('SYNOPSIS'):
# `http` and `https` are commands that can be directly used, so they can have
# a valid usage. But `httpie` is a top-level command with multiple sub commands,
# have a valid usage. But `httpie` is a top-level command with multiple sub commands,
# so for the synopsis we'll only reference the `httpie` name.
if is_top_level_cmd:
synopsis = program_name
@ -159,7 +153,7 @@ def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool =
if raw_arg.get('is_positional'):
# In case of positional arguments, metavar is always equal
# to the list of options (e.g `METHOD`).
metavar = None
metavar = None
builder.add_options(raw_arg['options'], metavar=metavar)
desc = builder.format_desc(raw_arg.get('description', ''))
@ -184,5 +178,6 @@ def main() -> None:
stream.write(to_man_page(program_name, spec, **config))
if __name__ == '__main__':
main()

View File

@ -3,7 +3,7 @@ HTTPie: modern, user-friendly command-line HTTP client for the API era.
"""
__version__ = '3.2.2'
__version__ = '3.2.1'
__date__ = '2022-05-06'
__author__ = 'Jakub Roztocil'
__licence__ = 'BSD'

View File

@ -1,6 +1,5 @@
from __future__ import annotations
import os
import textwrap
from argparse import FileType
@ -21,13 +20,7 @@ from httpie.output.formatters.colors import (AUTO_STYLE, DEFAULT_STYLE, BUNDLED_
get_available_styles)
from httpie.plugins.builtin import BuiltinAuthPlugin
from httpie.plugins.registry import plugin_manager
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
# Man pages are static (built when making a release).
# We use this check to not include generated, system-specific information there (e.g., default --ciphers).
IS_MAN_PAGE = bool(os.environ.get('HTTPIE_BUILDING_MAN_PAGES'))
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS
options = ParserSpec(
'http',
@ -37,11 +30,12 @@ options = ParserSpec(
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/httpie/cli/issues
https://github.com/httpie/httpie/issues
""",
source_file=__file__
)
#######################################################################
# Positional arguments.
#######################################################################
@ -240,7 +234,6 @@ processing_options.add_argument(
""",
)
#######################################################################
# Output processing
#######################################################################
@ -617,7 +610,6 @@ sessions.add_argument(
""",
)
#######################################################################
# Authentication
#######################################################################
@ -638,7 +630,7 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
if issubclass(auth_plugin, BuiltinAuthPlugin)
]
text += '\n'
text += 'To see all available auth types on your system, including ones installed via plugins, run:\n\n'
text += 'For finding out all available authentication types in your system, try:\n\n'
text += ' $ http --auth-type'
auth_types = '\n\n '.join(
@ -654,7 +646,7 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
''
if not plugin.description
else '\n '
+ ('\n '.join(textwrap.wrap(plugin.description)))
+ ('\n '.join(textwrap.wrap(plugin.description)))
),
)
for plugin in auth_plugins
@ -834,36 +826,23 @@ ssl.add_argument(
""",
)
CIPHERS_CURRENT_DEFAULTS = (
"""
See `http --help` for the default ciphers list on you system.
"""
if IS_MAN_PAGE else
f"""
By default, the following ciphers are used on your system:
{DEFAULT_SSL_CIPHERS_STRING}
"""
)
ssl.add_argument(
'--ciphers',
short_help='A string in the OpenSSL cipher list format.',
help=f"""
A string in the OpenSSL cipher list format.
A string in the OpenSSL cipher list format. By default, the following
is used:
{CIPHERS_CURRENT_DEFAULTS}
{DEFAULT_SSL_CIPHERS}
"""
""",
)
ssl.add_argument(
'--cert',
default=None,
type=readable_file_arg,
short_help='Specifies a local cert to use as the client-side SSL certificate.',
short_help='Specifys a local cert to use as client side SSL certificate.',
help="""
You can specify a local cert to use as client side SSL certificate.
This file may either contain both private key and certificate or you may

View File

@ -92,3 +92,7 @@ class MultipartRequestDataDict(MultiValueOrderedDict):
class RequestFilesDict(RequestDataDict):
pass
class NestedJSONArray(list):
"""Denotes a top-level JSON array."""

404
httpie/cli/nested_json.py Normal file
View File

@ -0,0 +1,404 @@
from enum import Enum, auto
from typing import (
Any,
Iterator,
NamedTuple,
Optional,
List,
NoReturn,
Type,
Union,
)
from .dicts import NestedJSONArray
EMPTY_STRING = ''
HIGHLIGHTER = '^'
OPEN_BRACKET = '['
CLOSE_BRACKET = ']'
BACKSLASH = '\\'
class HTTPieSyntaxError(ValueError):
def __init__(
self,
source: str,
token: Optional['Token'],
message: str,
message_kind: str = 'Syntax',
) -> None:
self.source = source
self.token = token
self.message = message
self.message_kind = message_kind
def __str__(self):
lines = [f'HTTPie {self.message_kind} Error: {self.message}']
if self.token is not None:
lines.append(self.source)
lines.append(
' ' * self.token.start
+ HIGHLIGHTER * (self.token.end - self.token.start)
)
return '\n'.join(lines)
class TokenKind(Enum):
TEXT = auto()
NUMBER = auto()
LEFT_BRACKET = auto()
RIGHT_BRACKET = auto()
def to_name(self) -> str:
for key, value in OPERATORS.items():
if value is self:
return repr(key)
else:
return 'a ' + self.name.lower()
OPERATORS = {
OPEN_BRACKET: TokenKind.LEFT_BRACKET,
CLOSE_BRACKET: TokenKind.RIGHT_BRACKET,
}
SPECIAL_CHARS = OPERATORS.keys() | {BACKSLASH}
LITERAL_TOKENS = [
TokenKind.TEXT,
TokenKind.NUMBER,
]
class Token(NamedTuple):
kind: TokenKind
value: Union[str, int]
start: int
end: int
def assert_cant_happen() -> NoReturn:
raise ValueError('Unexpected value')
def check_escaped_int(value: str) -> str:
if not value.startswith(BACKSLASH):
raise ValueError('Not an escaped int')
try:
int(value[1:])
except ValueError as exc:
raise ValueError('Not an escaped int') from exc
else:
return value[1:]
def tokenize(source: str) -> Iterator[Token]:
cursor = 0
backslashes = 0
buffer = []
def send_buffer() -> Iterator[Token]:
nonlocal backslashes
if not buffer:
return None
value = ''.join(buffer)
kind = TokenKind.TEXT
if not backslashes:
for variation, kind in [
(int, TokenKind.NUMBER),
(check_escaped_int, TokenKind.TEXT),
]:
try:
value = variation(value)
except ValueError:
continue
else:
break
yield Token(
kind, value, start=cursor - (len(buffer) + backslashes), end=cursor
)
buffer.clear()
backslashes = 0
def can_advance() -> bool:
return cursor < len(source)
while can_advance():
index = source[cursor]
if index in OPERATORS:
yield from send_buffer()
yield Token(OPERATORS[index], index, cursor, cursor + 1)
elif index == BACKSLASH and can_advance():
if source[cursor + 1] in SPECIAL_CHARS:
backslashes += 1
else:
buffer.append(index)
buffer.append(source[cursor + 1])
cursor += 1
else:
buffer.append(index)
cursor += 1
yield from send_buffer()
class PathAction(Enum):
KEY = auto()
INDEX = auto()
APPEND = auto()
# Pseudo action, used by the interpreter
SET = auto()
def to_string(self) -> str:
return self.name.lower()
class Path:
def __init__(
self,
kind: PathAction,
accessor: Optional[Union[str, int]] = None,
tokens: Optional[List[Token]] = None,
is_root: bool = False,
):
self.kind = kind
self.accessor = accessor
self.tokens = tokens or []
self.is_root = is_root
def reconstruct(self) -> str:
if self.kind is PathAction.KEY:
if self.is_root:
return str(self.accessor)
return OPEN_BRACKET + self.accessor + CLOSE_BRACKET
elif self.kind is PathAction.INDEX:
return OPEN_BRACKET + str(self.accessor) + CLOSE_BRACKET
elif self.kind is PathAction.APPEND:
return OPEN_BRACKET + CLOSE_BRACKET
else:
assert_cant_happen()
def parse(source: str) -> Iterator[Path]:
"""
start: root_path path*
root_path: (literal | index_path | append_path)
literal: TEXT | NUMBER
path:
key_path
| index_path
| append_path
key_path: LEFT_BRACKET TEXT RIGHT_BRACKET
index_path: LEFT_BRACKET NUMBER RIGHT_BRACKET
append_path: LEFT_BRACKET RIGHT_BRACKET
"""
tokens = list(tokenize(source))
cursor = 0
def can_advance():
return cursor < len(tokens)
def expect(*kinds):
nonlocal cursor
assert len(kinds) > 0
if can_advance():
token = tokens[cursor]
cursor += 1
if token.kind in kinds:
return token
elif tokens:
token = tokens[-1]._replace(
start=tokens[-1].end + 0, end=tokens[-1].end + 1
)
else:
token = None
if len(kinds) == 1:
suffix = kinds[0].to_name()
else:
suffix = ', '.join(kind.to_name() for kind in kinds[:-1])
suffix += ' or ' + kinds[-1].to_name()
message = f'Expecting {suffix}'
raise HTTPieSyntaxError(source, token, message)
def parse_root():
tokens = []
if not can_advance():
return Path(
PathAction.KEY,
EMPTY_STRING,
is_root=True
)
# (literal | index_path | append_path)?
token = expect(*LITERAL_TOKENS, TokenKind.LEFT_BRACKET)
tokens.append(token)
if token.kind in LITERAL_TOKENS:
action = PathAction.KEY
value = str(token.value)
elif token.kind is TokenKind.LEFT_BRACKET:
token = expect(TokenKind.NUMBER, TokenKind.RIGHT_BRACKET)
tokens.append(token)
if token.kind is TokenKind.NUMBER:
action = PathAction.INDEX
value = token.value
tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.RIGHT_BRACKET:
action = PathAction.APPEND
value = None
else:
assert_cant_happen()
else:
assert_cant_happen()
return Path(
action,
value,
tokens=tokens,
is_root=True
)
yield parse_root()
# path*
while can_advance():
path_tokens = []
path_tokens.append(expect(TokenKind.LEFT_BRACKET))
token = expect(
TokenKind.TEXT, TokenKind.NUMBER, TokenKind.RIGHT_BRACKET
)
path_tokens.append(token)
if token.kind is TokenKind.RIGHT_BRACKET:
path = Path(PathAction.APPEND, tokens=path_tokens)
elif token.kind is TokenKind.TEXT:
path = Path(PathAction.KEY, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.NUMBER:
path = Path(PathAction.INDEX, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
else:
assert_cant_happen()
yield path
JSON_TYPE_MAPPING = {
dict: 'object',
list: 'array',
int: 'number',
float: 'number',
str: 'string',
}
def interpret(context: Any, key: str, value: Any) -> Any:
cursor = context
paths = list(parse(key))
paths.append(Path(PathAction.SET, value))
def type_check(index: int, path: Path, expected_type: Type[Any]) -> None:
if not isinstance(cursor, expected_type):
if path.tokens:
pseudo_token = Token(
None, None, path.tokens[0].start, path.tokens[-1].end
)
else:
pseudo_token = None
cursor_type = JSON_TYPE_MAPPING.get(
type(cursor), type(cursor).__name__
)
required_type = JSON_TYPE_MAPPING[expected_type]
message = f"Can't perform {path.kind.to_string()!r} based access on "
message += repr(
''.join(path.reconstruct() for path in paths[:index])
)
message += (
f' which has a type of {cursor_type!r} but this operation'
)
message += f' requires a type of {required_type!r}.'
raise HTTPieSyntaxError(
key, pseudo_token, message, message_kind='Type'
)
def object_for(kind: str) -> Any:
if kind is PathAction.KEY:
return {}
elif kind in {PathAction.INDEX, PathAction.APPEND}:
return []
else:
assert_cant_happen()
for index, (path, next_path) in enumerate(zip(paths, paths[1:])):
# If there is no context yet, set it.
if cursor is None:
context = cursor = object_for(path.kind)
if path.kind is PathAction.KEY:
type_check(index, path, dict)
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
cursor = cursor.setdefault(
path.accessor, object_for(next_path.kind)
)
elif path.kind is PathAction.INDEX:
type_check(index, path, list)
if path.accessor < 0:
raise HTTPieSyntaxError(
key,
path.tokens[1],
'Negative indexes are not supported.',
message_kind='Value',
)
cursor.extend([None] * (path.accessor - len(cursor) + 1))
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
if cursor[path.accessor] is None:
cursor[path.accessor] = object_for(next_path.kind)
cursor = cursor[path.accessor]
elif path.kind is PathAction.APPEND:
type_check(index, path, list)
if next_path.kind is PathAction.SET:
cursor.append(next_path.accessor)
break
cursor.append(object_for(next_path.kind))
cursor = cursor[-1]
else:
assert_cant_happen()
return context
def wrap_with_dict(context):
if context is None:
return {}
elif isinstance(context, list):
return {EMPTY_STRING: NestedJSONArray(context)}
else:
assert isinstance(context, dict)
return context
def interpret_nested_json(pairs):
context = None
for key, value in pairs:
context = interpret(context, key, value)
return wrap_with_dict(context)

View File

@ -1,20 +0,0 @@
"""
A library for parsing the HTTPie nested JSON key syntax and constructing the resulting objects.
<https://httpie.io/docs/cli/nested-json>
It has no dependencies.
"""
from .interpret import interpret_nested_json, unwrap_top_level_list_if_needed
from .errors import NestedJSONSyntaxError
from .tokens import EMPTY_STRING, NestedJSONArray
__all__ = [
'interpret_nested_json',
'unwrap_top_level_list_if_needed',
'EMPTY_STRING',
'NestedJSONArray',
'NestedJSONSyntaxError'
]

View File

@ -1,27 +0,0 @@
from typing import Optional
from .tokens import Token, HIGHLIGHTER
class NestedJSONSyntaxError(ValueError):
def __init__(
self,
source: str,
token: Optional[Token],
message: str,
message_kind: str = 'Syntax',
) -> None:
self.source = source
self.token = token
self.message = message
self.message_kind = message_kind
def __str__(self):
lines = [f'HTTPie {self.message_kind} Error: {self.message}']
if self.token is not None:
lines.append(self.source)
lines.append(
' ' * self.token.start
+ HIGHLIGHTER * (self.token.end - self.token.start)
)
return '\n'.join(lines)

View File

@ -1,129 +0,0 @@
from typing import Type, Union, Any, Iterable, Tuple
from .parse import parse, assert_cant_happen
from .errors import NestedJSONSyntaxError
from .tokens import EMPTY_STRING, TokenKind, Token, PathAction, Path, NestedJSONArray
__all__ = [
'interpret_nested_json',
'unwrap_top_level_list_if_needed',
]
JSONType = Type[Union[dict, list, int, float, str]]
JSON_TYPE_MAPPING = {
dict: 'object',
list: 'array',
int: 'number',
float: 'number',
str: 'string',
}
def interpret_nested_json(pairs: Iterable[Tuple[str, str]]) -> dict:
context = None
for key, value in pairs:
context = interpret(context, key, value)
return wrap_with_dict(context)
def interpret(context: Any, key: str, value: Any) -> Any:
cursor = context
paths = list(parse(key))
paths.append(Path(PathAction.SET, value))
# noinspection PyShadowingNames
def type_check(index: int, path: Path, expected_type: JSONType):
if not isinstance(cursor, expected_type):
if path.tokens:
pseudo_token = Token(
kind=TokenKind.PSEUDO,
value='',
start=path.tokens[0].start,
end=path.tokens[-1].end,
)
else:
pseudo_token = None
cursor_type = JSON_TYPE_MAPPING.get(type(cursor), type(cursor).__name__)
required_type = JSON_TYPE_MAPPING[expected_type]
message = f'Cannot perform {path.kind.to_string()!r} based access on '
message += repr(''.join(path.reconstruct() for path in paths[:index]))
message += f' which has a type of {cursor_type!r} but this operation'
message += f' requires a type of {required_type!r}.'
raise NestedJSONSyntaxError(
source=key,
token=pseudo_token,
message=message,
message_kind='Type',
)
def object_for(kind: PathAction) -> Any:
if kind is PathAction.KEY:
return {}
elif kind in {PathAction.INDEX, PathAction.APPEND}:
return []
else:
assert_cant_happen()
for index, (path, next_path) in enumerate(zip(paths, paths[1:])):
# If there is no context yet, set it.
if cursor is None:
context = cursor = object_for(path.kind)
if path.kind is PathAction.KEY:
type_check(index, path, dict)
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
cursor = cursor.setdefault(path.accessor, object_for(next_path.kind))
elif path.kind is PathAction.INDEX:
type_check(index, path, list)
if path.accessor < 0:
raise NestedJSONSyntaxError(
source=key,
token=path.tokens[1],
message='Negative indexes are not supported.',
message_kind='Value',
)
cursor.extend([None] * (path.accessor - len(cursor) + 1))
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
if cursor[path.accessor] is None:
cursor[path.accessor] = object_for(next_path.kind)
cursor = cursor[path.accessor]
elif path.kind is PathAction.APPEND:
type_check(index, path, list)
if next_path.kind is PathAction.SET:
cursor.append(next_path.accessor)
break
cursor.append(object_for(next_path.kind))
cursor = cursor[-1]
else:
assert_cant_happen()
return context
def wrap_with_dict(context):
if context is None:
return {}
elif isinstance(context, list):
return {
EMPTY_STRING: NestedJSONArray(context),
}
else:
assert isinstance(context, dict)
return context
def unwrap_top_level_list_if_needed(data: dict):
"""
Propagate the top-level list, if thats what we got.
"""
if len(data) == 1:
key, value = list(data.items())[0]
if isinstance(value, NestedJSONArray):
assert key == EMPTY_STRING
return value
return data

View File

@ -1,193 +0,0 @@
from typing import Iterator
from .errors import NestedJSONSyntaxError
from .tokens import (
EMPTY_STRING,
BACKSLASH,
TokenKind,
OPERATORS,
SPECIAL_CHARS,
LITERAL_TOKENS,
Token,
PathAction,
Path,
)
__all__ = [
'parse',
'assert_cant_happen',
]
def parse(source: str) -> Iterator[Path]:
"""
start: root_path path*
root_path: (literal | index_path | append_path)
literal: TEXT | NUMBER
path:
key_path
| index_path
| append_path
key_path: LEFT_BRACKET TEXT RIGHT_BRACKET
index_path: LEFT_BRACKET NUMBER RIGHT_BRACKET
append_path: LEFT_BRACKET RIGHT_BRACKET
"""
tokens = list(tokenize(source))
cursor = 0
def can_advance():
return cursor < len(tokens)
# noinspection PyShadowingNames
def expect(*kinds):
nonlocal cursor
assert kinds
if can_advance():
token = tokens[cursor]
cursor += 1
if token.kind in kinds:
return token
elif tokens:
token = tokens[-1]._replace(
start=tokens[-1].end + 0,
end=tokens[-1].end + 1,
)
else:
token = None
if len(kinds) == 1:
suffix = kinds[0].to_name()
else:
suffix = ', '.join(kind.to_name() for kind in kinds[:-1])
suffix += ' or ' + kinds[-1].to_name()
message = f'Expecting {suffix}'
raise NestedJSONSyntaxError(source, token, message)
# noinspection PyShadowingNames
def parse_root():
tokens = []
if not can_advance():
return Path(
kind=PathAction.KEY,
accessor=EMPTY_STRING,
is_root=True
)
# (literal | index_path | append_path)?
token = expect(*LITERAL_TOKENS, TokenKind.LEFT_BRACKET)
tokens.append(token)
if token.kind in LITERAL_TOKENS:
action = PathAction.KEY
value = str(token.value)
elif token.kind is TokenKind.LEFT_BRACKET:
token = expect(TokenKind.NUMBER, TokenKind.RIGHT_BRACKET)
tokens.append(token)
if token.kind is TokenKind.NUMBER:
action = PathAction.INDEX
value = token.value
tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.RIGHT_BRACKET:
action = PathAction.APPEND
value = None
else:
assert_cant_happen()
else:
assert_cant_happen()
# noinspection PyUnboundLocalVariable
return Path(
kind=action,
accessor=value,
tokens=tokens,
is_root=True
)
yield parse_root()
# path*
while can_advance():
path_tokens = [expect(TokenKind.LEFT_BRACKET)]
token = expect(TokenKind.TEXT, TokenKind.NUMBER, TokenKind.RIGHT_BRACKET)
path_tokens.append(token)
if token.kind is TokenKind.RIGHT_BRACKET:
path = Path(PathAction.APPEND, tokens=path_tokens)
elif token.kind is TokenKind.TEXT:
path = Path(PathAction.KEY, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.NUMBER:
path = Path(PathAction.INDEX, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
else:
assert_cant_happen()
# noinspection PyUnboundLocalVariable
yield path
def tokenize(source: str) -> Iterator[Token]:
cursor = 0
backslashes = 0
buffer = []
def send_buffer() -> Iterator[Token]:
nonlocal backslashes
if not buffer:
return None
value = ''.join(buffer)
kind = TokenKind.TEXT
if not backslashes:
for variation, kind in [
(int, TokenKind.NUMBER),
(check_escaped_int, TokenKind.TEXT),
]:
try:
value = variation(value)
except ValueError:
continue
else:
break
yield Token(
kind=kind,
value=value,
start=cursor - (len(buffer) + backslashes),
end=cursor,
)
buffer.clear()
backslashes = 0
def can_advance() -> bool:
return cursor < len(source)
while can_advance():
index = source[cursor]
if index in OPERATORS:
yield from send_buffer()
yield Token(OPERATORS[index], index, cursor, cursor + 1)
elif index == BACKSLASH and can_advance():
if source[cursor + 1] in SPECIAL_CHARS:
backslashes += 1
else:
buffer.append(index)
buffer.append(source[cursor + 1])
cursor += 1
else:
buffer.append(index)
cursor += 1
yield from send_buffer()
def check_escaped_int(value: str) -> str:
if not value.startswith(BACKSLASH):
raise ValueError('Not an escaped int')
try:
int(value[1:])
except ValueError as exc:
raise ValueError('Not an escaped int') from exc
else:
return value[1:]
def assert_cant_happen():
raise ValueError('Unexpected value')

View File

@ -1,80 +0,0 @@
from enum import Enum, auto
from typing import NamedTuple, Union, Optional, List
EMPTY_STRING = ''
HIGHLIGHTER = '^'
OPEN_BRACKET = '['
CLOSE_BRACKET = ']'
BACKSLASH = '\\'
class TokenKind(Enum):
TEXT = auto()
NUMBER = auto()
LEFT_BRACKET = auto()
RIGHT_BRACKET = auto()
PSEUDO = auto() # Not a real token, use when representing location only.
def to_name(self) -> str:
for key, value in OPERATORS.items():
if value is self:
return repr(key)
else:
return 'a ' + self.name.lower()
OPERATORS = {
OPEN_BRACKET: TokenKind.LEFT_BRACKET,
CLOSE_BRACKET: TokenKind.RIGHT_BRACKET,
}
SPECIAL_CHARS = OPERATORS.keys() | {BACKSLASH}
LITERAL_TOKENS = [
TokenKind.TEXT,
TokenKind.NUMBER,
]
class Token(NamedTuple):
kind: TokenKind
value: Union[str, int]
start: int
end: int
class PathAction(Enum):
KEY = auto()
INDEX = auto()
APPEND = auto()
# Pseudo action, used by the interpreter
SET = auto()
def to_string(self) -> str:
return self.name.lower()
class Path:
def __init__(
self,
kind: PathAction,
accessor: Optional[Union[str, int]] = None,
tokens: Optional[List[Token]] = None,
is_root: bool = False,
):
self.kind = kind
self.accessor = accessor
self.tokens = tokens or []
self.is_root = is_root
def reconstruct(self) -> str:
if self.kind is PathAction.KEY:
if self.is_root:
return str(self.accessor)
return OPEN_BRACKET + self.accessor + CLOSE_BRACKET
elif self.kind is PathAction.INDEX:
return OPEN_BRACKET + str(self.accessor) + CLOSE_BRACKET
elif self.kind is PathAction.APPEND:
return OPEN_BRACKET + CLOSE_BRACKET
class NestedJSONArray(list):
"""Denotes a top-level JSON array."""

View File

@ -18,7 +18,7 @@ from .dicts import (
)
from .exceptions import ParseError
from .nested_json import interpret_nested_json
from ..utils import get_content_type, load_json_preserve_order_and_dupe_keys, split_iterable
from ..utils import get_content_type, load_json_preserve_order_and_dupe_keys, split
class RequestItems:
@ -78,28 +78,25 @@ class RequestItems:
instance.data,
),
SEPARATOR_DATA_RAW_JSON: (
convert_json_value_to_form_if_needed(
in_json_mode=instance.is_json,
processor=process_data_raw_json_embed_arg
),
json_only(instance, process_data_raw_json_embed_arg),
instance.data,
),
SEPARATOR_DATA_EMBED_RAW_JSON_FILE: (
convert_json_value_to_form_if_needed(
in_json_mode=instance.is_json,
processor=process_data_embed_raw_json_file_arg,
),
json_only(instance, process_data_embed_raw_json_file_arg),
instance.data,
),
}
if instance.is_json:
json_item_args, request_item_args = split_iterable(
iterable=request_item_args,
key=lambda arg: arg.sep in SEPARATOR_GROUP_NESTED_JSON_ITEMS
json_item_args, request_item_args = split(
request_item_args,
lambda arg: arg.sep in SEPARATOR_GROUP_NESTED_JSON_ITEMS
)
if json_item_args:
pairs = [(arg.key, rules[arg.sep][0](arg)) for arg in json_item_args]
pairs = [
(arg.key, rules[arg.sep][0](arg))
for arg in json_item_args
]
processor_func, target_dict = rules[SEPARATOR_GROUP_NESTED_JSON_ITEMS]
value = processor_func(pairs)
target_dict.update(value)
@ -162,30 +159,6 @@ def process_file_upload_arg(arg: KeyValueArg) -> Tuple[str, IO, str]:
)
def convert_json_value_to_form_if_needed(in_json_mode: bool, processor: Callable[[KeyValueArg], JSONType]) -> Callable[[], str]:
"""
We allow primitive values to be passed to forms via JSON key/value syntax.
But complex values lead to an error because theres no clear way to serialize them.
"""
if in_json_mode:
return processor
@functools.wraps(processor)
def wrapper(*args, **kwargs) -> str:
try:
output = processor(*args, **kwargs)
except ParseError:
output = None
if isinstance(output, (str, int, float)):
return str(output)
else:
raise ParseError('Cannot use complex JSON value types with --form/--multipart.')
return wrapper
def process_data_item_arg(arg: KeyValueArg) -> str:
return arg.value
@ -194,6 +167,29 @@ def process_data_embed_file_contents_arg(arg: KeyValueArg) -> str:
return load_text_file(arg)
def json_only(items: RequestItems, func: Callable[[KeyValueArg], JSONType]) -> str:
if items.is_json:
return func
@functools.wraps(func)
def wrapper(*args, **kwargs) -> str:
try:
ret = func(*args, **kwargs)
except ParseError:
ret = None
# If it is a basic type, then allow it
if isinstance(ret, (str, int, float)):
return str(ret)
else:
raise ParseError(
'Can\'t use complex JSON value types with '
'--form/--multipart.'
)
return wrapper
def process_data_embed_raw_json_file_arg(arg: KeyValueArg) -> JSONType:
contents = load_text_file(arg)
value = load_json(arg, contents)

View File

@ -10,14 +10,12 @@ from urllib.parse import urlparse, urlunparse
import requests
# noinspection PyPackageRequirements
import urllib3
from urllib3.util import SKIP_HEADER, SKIPPABLE_HEADERS
from . import __version__
from .adapters import HTTPieHTTPAdapter
from .cli.constants import HTTP_OPTIONS
from .cli.dicts import HTTPHeadersDict
from .cli.nested_json import unwrap_top_level_list_if_needed
from .context import Environment
from .cli.constants import HTTP_OPTIONS
from .cli.nested_json import EMPTY_STRING
from .cli.dicts import HTTPHeadersDict, NestedJSONArray
from .encoding import UTF8
from .models import RequestsMessage
from .plugins.registry import plugin_manager
@ -143,7 +141,7 @@ def collect_messages(
# noinspection PyProtectedMember
@contextmanager
def max_headers(limit):
# <https://github.com/httpie/cli/issues/802>
# <https://github.com/httpie/httpie/issues/802>
# noinspection PyUnresolvedReferences
orig = http.client._MAXHEADERS
http.client._MAXHEADERS = limit or float('Inf')
@ -199,12 +197,8 @@ def finalize_headers(headers: HTTPHeadersDict) -> HTTPHeadersDict:
# Also, requests raises `InvalidHeader` for leading spaces.
value = value.strip()
if isinstance(value, str):
# See <https://github.com/httpie/cli/issues/212>
# See <https://github.com/httpie/httpie/issues/212>
value = value.encode()
elif name.lower() in SKIPPABLE_HEADERS:
# Some headers get overwritten by urllib3 when set to `None`
# and should be replaced with the `SKIP_HEADER` constant.
value = SKIP_HEADER
final_headers.add(name, value)
return final_headers
@ -312,13 +306,21 @@ def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
def json_dict_to_request_body(data: Dict[str, Any]) -> str:
data = unwrap_top_level_list_if_needed(data)
# Propagate the top-level list if there is only one
# item in the object, with an en empty key.
if len(data) == 1:
[(key, value)] = data.items()
if isinstance(value, NestedJSONArray):
assert key == EMPTY_STRING
data = value
if data:
data = json.dumps(data)
else:
# We need to set data to an empty string to prevent requests
# from assigning an empty list to `response.request.data`.
data = ''
return data
@ -381,7 +383,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/httpie/cli/issues/895>
<https://github.com/httpie/httpie/issues/895>
<https://ec.haxx.se/http/http-basics#path-as-is>

View File

@ -145,7 +145,7 @@ class Environment:
try:
config.load()
except ConfigFileError as e:
self.log_error(e, level=LogLevel.WARNING)
self.log_error(e, level='warning')
return config
@property
@ -174,7 +174,7 @@ class Environment:
stderr = self._orig_stderr
rich_console = self._make_rich_console(file=stderr, force_terminal=stderr.isatty())
rich_console.print(
f'\n{self.program_name}: {level.value}: {msg}\n\n',
f'\n{self.program_name}: {level}: {msg}\n\n',
style=LOG_LEVEL_COLORS[level],
markup=False,
highlight=False,

View File

@ -11,7 +11,7 @@ from requests import __version__ as requests_version
from . import __version__ as httpie_version
from .cli.constants import OUT_REQ_BODY
from .cli.nested_json import NestedJSONSyntaxError
from .cli.nested_json import HTTPieSyntaxError
from .client import collect_messages
from .context import Environment, LogLevel
from .downloads import Downloader
@ -78,7 +78,7 @@ def raw_main(
args=args,
env=env,
)
except NestedJSONSyntaxError as exc:
except HTTPieSyntaxError as exc:
env.stderr.write(str(exc) + "\n")
if include_traceback:
raise

View File

@ -217,7 +217,7 @@ class Downloader:
assert not self.status.time_started
# FIXME: some servers still might sent Content-Encoding: gzip
# <https://github.com/httpie/cli/issues/423>
# <https://github.com/httpie/httpie/issues/423>
try:
total_size = int(final_response.headers['Content-Length'])
except (KeyError, ValueError, TypeError):

View File

@ -52,6 +52,7 @@ def program():
try:
exit_status = main()
except KeyboardInterrupt:
from httpie.status import ExitStatus
exit_status = ExitStatus.ERROR_CTRL_C
return exit_status

View File

@ -43,6 +43,7 @@ def _discover_system_pip() -> List[str]:
def _run_pip_subprocess(pip_executable: List[str], args: List[str]) -> bytes:
import subprocess
cmd = [*pip_executable, *args]
try:

View File

@ -1,7 +1,6 @@
from time import monotonic
import requests
from urllib3.util import SKIP_HEADER, SKIPPABLE_HEADERS
from enum import Enum, auto
from typing import Iterable, Union, NamedTuple
@ -17,6 +16,7 @@ from .cli.constants import (
from .compat import cached_property
from .utils import split_cookies, parse_content_type_header
ELAPSED_TIME_LABEL = 'Elapsed time'
@ -67,10 +67,27 @@ class HTTPResponse(HTTPMessage):
def iter_lines(self, chunk_size):
return ((line, b'\n') for line in self._orig.iter_lines(chunk_size))
# noinspection PyProtectedMember
@property
def headers(self):
try:
raw = self._orig.raw
if getattr(raw, '_original_response', None):
raw_version = raw._original_response.version
else:
raw_version = raw.version
except AttributeError:
# Assume HTTP/1.1
raw_version = 11
version = {
9: '0.9',
10: '1.0',
11: '1.1',
20: '2.0',
}[raw_version]
original = self._orig
status_line = f'HTTP/{self.version} {original.status_code} {original.reason}'
status_line = f'HTTP/{version} {original.status_code} {original.reason}'
headers = [status_line]
headers.extend(
': '.join(header)
@ -100,32 +117,6 @@ class HTTPResponse(HTTPMessage):
for key, value in data.items()
)
@property
def version(self) -> str:
"""
Return the HTTP version used by the server, e.g. '1.1'.
Assume HTTP/1.1 if version is not available.
"""
mapping = {
9: '0.9',
10: '1.0',
11: '1.1',
20: '2.0',
}
fallback = 11
version = None
try:
raw = self._orig.raw
if getattr(raw, '_original_response', None):
version = raw._original_response.version
else:
version = raw.version
except AttributeError:
pass
return mapping[version or fallback]
class HTTPRequest(HTTPMessage):
"""A :class:`requests.models.Request` wrapper."""
@ -153,7 +144,6 @@ class HTTPRequest(HTTPMessage):
headers = [
f'{name}: {value if isinstance(value, str) else value.decode()}'
for name, value in headers.items()
if not (name.lower() in SKIPPABLE_HEADERS and value == SKIP_HEADER)
]
headers.insert(0, request_line)

View File

@ -4,22 +4,23 @@ import subprocess
import os
from httpie.context import Environment
MAN_COMMAND = 'man'
NO_MAN_PAGES = os.getenv('HTTPIE_NO_MAN_PAGES', False)
# On some systems, HTTP(n) might exist, but we are only interested in HTTP(1).
# For more information on man page sections: <https://unix.stackexchange.com/a/138643>
# On some systems, HTTP(n) might exist but we are only
# interested in HTTP(1).
#
# For more information on man page sections: https://unix.stackexchange.com/a/138643
MAN_PAGE_SECTION = '1'
def is_available(program: str) -> bool:
"""
Check whether `program`'s man pages are available on this system.
"""Check whether HTTPie's man pages are available in this system."""
"""
if NO_MAN_PAGES or os.system == 'nt':
return False
try:
process = subprocess.run(
[MAN_COMMAND, MAN_PAGE_SECTION, program],
@ -28,7 +29,7 @@ def is_available(program: str) -> bool:
stderr=subprocess.DEVNULL
)
except Exception:
# There might be some errors outside the process, e.g
# There might be some errors outside of the process, e.g
# a permission error to execute something that is not an
# executable.
return False
@ -37,10 +38,8 @@ def is_available(program: str) -> bool:
def display_for(env: Environment, program: str) -> None:
"""
Open the system man page for the given command (http/https/httpie).
"""Display the man page for the given command (http/https)."""
"""
subprocess.run(
[MAN_COMMAND, MAN_PAGE_SECTION, program],
stdout=env.stdout,

View File

@ -24,7 +24,7 @@ def enable_highlighter(
console: Console,
highlighter: Highlighter,
) -> Iterator[Console]:
"""Enable a highlighter temporarily."""
"""Enable a higlighter temporarily."""
original_highlighter = console.highlighter
try:

View File

@ -19,7 +19,7 @@ class HTTPBasicAuth(requests.auth.HTTPBasicAuth):
"""
Override username/password serialization to allow unicode.
See https://github.com/httpie/cli/issues/212
See https://github.com/httpie/httpie/issues/212
"""
# noinspection PyTypeChecker

View File

@ -4,11 +4,12 @@ from typing import NamedTuple, Optional
from httpie.adapters import HTTPAdapter
# noinspection PyPackageRequirements
from urllib3.util.ssl_ import (
create_urllib3_context,
DEFAULT_CIPHERS, create_urllib3_context,
resolve_ssl_version,
)
DEFAULT_SSL_CIPHERS = DEFAULT_CIPHERS
SSL_VERSION_ARG_MAPPING = {
'ssl2.3': 'PROTOCOL_SSLv23',
'ssl3': 'PROTOCOL_SSLv3',
@ -80,10 +81,6 @@ class HTTPieHTTPSAdapter(HTTPAdapter):
cert_reqs=ssl.CERT_REQUIRED if verify else ssl.CERT_NONE
)
@classmethod
def get_default_ciphers_names(cls):
return [cipher['name'] for cipher in cls._create_ssl_context(verify=False).get_ciphers()]
def _is_key_file_encrypted(key_file):
"""Detects if a key file is encrypted or not.
@ -97,9 +94,3 @@ def _is_key_file_encrypted(key_file):
return True
return False
# We used to import the default set of TLS ciphers from urllib3, but they removed it.
# Instead, now urllib3 uses the list of ciphers configured by the system.
# <https://github.com/httpie/cli/pull/1501>
DEFAULT_SSL_CIPHERS_STRING = ':'.join(HTTPieHTTPSAdapter.get_default_ciphers_names())

View File

@ -245,7 +245,7 @@ def get_site_paths(path: Path) -> Iterable[Path]:
yield as_site(path)
def split_iterable(iterable: Iterable[T], key: Callable[[T], bool]) -> Tuple[List[T], List[T]]:
def split(iterable: Iterable[T], key: Callable[[T], bool]) -> Tuple[List[T], List[T]]:
left, right = [], []
for item in iterable:
if key(item):

View File

@ -1,6 +1,6 @@
# Please keep all characters in this file in ASCII
# distutils uses system's locale to interpret it and not everybody
# uses UTF-8. See https://github.com/httpie/cli/issues/1039
# uses UTF-8. See https://github.com/httpie/httpie/issues/1039
# for an example
[wheel]

View File

@ -77,7 +77,7 @@ setup(
long_description=long_description(),
long_description_content_type='text/markdown',
url='https://httpie.io/',
download_url=f'https://github.com/httpie/cli/archive/{httpie.__version__}.tar.gz',
download_url=f'https://github.com/httpie/httpie/archive/{httpie.__version__}.tar.gz',
author=httpie.__author__,
author_email='jakub@roztocil.co',
license=httpie.__licence__,
@ -108,7 +108,7 @@ setup(
'Topic :: Utilities'
],
project_urls={
'GitHub': 'https://github.com/httpie/cli',
'GitHub': 'https://github.com/httpie/httpie',
'Twitter': 'https://twitter.com/httpie',
'Discord': 'https://httpie.io/discord',
'Documentation': 'https://httpie.io/docs',

View File

@ -31,7 +31,7 @@ description: |
Links
- Documentation: https://httpie.io/docs
- Try in browser: https://httpie.io/run
- GitHub: https://github.com/httpie/cli
- GitHub: https://github.com/httpie/httpie
- Twitter: https://twitter.com/httpie
- Discord: https://httpie.io/chat
license: BSD-3-Clause-LBNL

View File

@ -1,3 +1,3 @@
# HTTPie Test Suite
Please see [CONTRIBUTING](https://github.com/httpie/cli/blob/master/CONTRIBUTING.md) for contribution and testing guidelines.
Please see [CONTRIBUTING](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md) for contribution and testing guidelines.

View File

@ -71,7 +71,7 @@ def test_credentials_in_url_auth_flag_has_priority(httpbin_both):
])
def test_only_username_in_url(url):
"""
https://github.com/httpie/cli/issues/242
https://github.com/httpie/httpie/issues/242
"""
args = httpie.cli.definition.parser.parse_args(args=[url], env=MockEnvironment())

View File

@ -11,7 +11,7 @@ from .fixtures import FILE_PATH
def test_default_headers_case_insensitive(httpbin):
"""
<https://github.com/httpie/cli/issues/644>
<https://github.com/httpie/httpie/issues/644>
"""
r = http(
'--debug',
@ -68,7 +68,7 @@ class TestAutoContentTypeAndAcceptHeaders:
"""
def test_GET_no_data_no_auto_headers(self, httpbin):
# https://github.com/httpie/cli/issues/62
# https://github.com/httpie/httpie/issues/62
r = http('GET', httpbin.url + '/headers')
assert HTTP_OK in r
assert r.json['headers']['Accept'] == '*/*'
@ -99,7 +99,7 @@ class TestAutoContentTypeAndAcceptHeaders:
assert HTTP_OK in r
assert r.json['headers']['Accept'] == JSON_ACCEPT
# Make sure Content-Type gets set even with no data.
# https://github.com/httpie/cli/issues/137
# https://github.com/httpie/httpie/issues/137
assert 'application/json' in r.json['headers']['Content-Type']
def test_GET_explicit_JSON_explicit_headers(self, httpbin):

View File

@ -36,7 +36,7 @@ def test_debug():
def test_help():
r = http('--help', tolerate_error_exit_status=True)
assert r.exit_status == ExitStatus.SUCCESS
assert 'https://github.com/httpie/cli/issues' in r
assert 'https://github.com/httpie/httpie/issues' in r
def test_version():
@ -124,7 +124,7 @@ def test_POST_file(httpbin_both):
def test_form_POST_file_redirected_stdin(httpbin):
"""
<https://github.com/httpie/cli/issues/840>
<https://github.com/httpie/httpie/issues/840>
"""
with open(FILE_PATH, encoding=UTF8):
@ -196,14 +196,6 @@ def test_unset_host_header(httpbin_both):
assert 'Host' not in r.json['headers'] # default Host unset
def test_unset_useragent_header(httpbin_both):
r = http('GET', httpbin_both + '/headers')
assert 'User-Agent' in r.json['headers'] # default User-Agent present
r = http('GET', httpbin_both + '/headers', 'User-Agent:')
assert 'User-Agent' not in r.json['headers'] # default User-Agent unset
def test_headers_empty_value(httpbin_both):
r = http('GET', httpbin_both + '/headers')
assert r.json['headers']['Accept'] # default Accept has value

View File

@ -5,7 +5,7 @@ import responses
from httpie.cli.constants import PRETTY_MAP
from httpie.cli.exceptions import ParseError
from httpie.cli.nested_json import NestedJSONSyntaxError
from httpie.cli.nested_json import HTTPieSyntaxError
from httpie.output.formatters.colors import ColorFormatter
from httpie.utils import JsonDictPreservingDuplicateKeys
@ -157,7 +157,7 @@ def test_complex_json_arguments_with_non_json(httpbin, request_type, value):
f'option:={json.dumps(value)}',
)
cm.match('Cannot use complex JSON value types')
cm.match("Can't use complex JSON value types")
@pytest.mark.parametrize(
@ -508,23 +508,23 @@ def test_nested_json_syntax(input_json, expected_json, httpbin):
),
(
['foo=1', 'foo[key]:=2'],
"HTTPie Type Error: Cannot perform 'key' based access on 'foo' which has a type of 'string' but this operation requires a type of 'object'.\nfoo[key]\n ^^^^^",
"HTTPie Type Error: Can't perform 'key' based access on 'foo' which has a type of 'string' but this operation requires a type of 'object'.\nfoo[key]\n ^^^^^",
),
(
['foo=1', 'foo[0]:=2'],
"HTTPie Type Error: Cannot perform 'index' based access on 'foo' which has a type of 'string' but this operation requires a type of 'array'.\nfoo[0]\n ^^^",
"HTTPie Type Error: Can't perform 'index' based access on 'foo' which has a type of 'string' but this operation requires a type of 'array'.\nfoo[0]\n ^^^",
),
(
['foo=1', 'foo[]:=2'],
"HTTPie Type Error: Cannot perform 'append' based access on 'foo' which has a type of 'string' but this operation requires a type of 'array'.\nfoo[]\n ^^",
"HTTPie Type Error: Can't perform 'append' based access on 'foo' which has a type of 'string' but this operation requires a type of 'array'.\nfoo[]\n ^^",
),
(
['data[key]=value', 'data[key 2]=value 2', 'data[0]=value'],
"HTTPie Type Error: Cannot perform 'index' based access on 'data' which has a type of 'object' but this operation requires a type of 'array'.\ndata[0]\n ^^^",
"HTTPie Type Error: Can't perform 'index' based access on 'data' which has a type of 'object' but this operation requires a type of 'array'.\ndata[0]\n ^^^",
),
(
['data[key]=value', 'data[key 2]=value 2', 'data[]=value'],
"HTTPie Type Error: Cannot perform 'append' based access on 'data' which has a type of 'object' but this operation requires a type of 'array'.\ndata[]\n ^^",
"HTTPie Type Error: Can't perform 'append' based access on 'data' which has a type of 'object' but this operation requires a type of 'array'.\ndata[]\n ^^",
),
(
[
@ -532,7 +532,7 @@ def test_nested_json_syntax(input_json, expected_json, httpbin):
'foo[bar][baz][5][]:=4',
'foo[bar][baz][key][]:=5',
],
"HTTPie Type Error: Cannot perform 'key' based access on 'foo[bar][baz]' which has a type of 'array' but this operation requires a type of 'object'.\nfoo[bar][baz][key][]\n ^^^^^",
"HTTPie Type Error: Can't perform 'key' based access on 'foo[bar][baz]' which has a type of 'array' but this operation requires a type of 'object'.\nfoo[bar][baz][key][]\n ^^^^^",
),
(
['foo[-10]:=[1,2]'],
@ -540,32 +540,32 @@ def test_nested_json_syntax(input_json, expected_json, httpbin):
),
(
['foo[0]:=1', 'foo[]:=2', 'foo[\\2]:=3'],
"HTTPie Type Error: Cannot perform 'key' based access on 'foo' which has a type of 'array' but this operation requires a type of 'object'.\nfoo[\\2]\n ^^^^",
"HTTPie Type Error: Can't perform 'key' based access on 'foo' which has a type of 'array' but this operation requires a type of 'object'.\nfoo[\\2]\n ^^^^",
),
(
['foo[\\1]:=2', 'foo[5]:=3'],
"HTTPie Type Error: Cannot perform 'index' based access on 'foo' which has a type of 'object' but this operation requires a type of 'array'.\nfoo[5]\n ^^^",
"HTTPie Type Error: Can't perform 'index' based access on 'foo' which has a type of 'object' but this operation requires a type of 'array'.\nfoo[5]\n ^^^",
),
(
['x=y', '[]:=2'],
"HTTPie Type Error: Cannot perform 'append' based access on '' which has a type of 'object' but this operation requires a type of 'array'.",
"HTTPie Type Error: Can't perform 'append' based access on '' which has a type of 'object' but this operation requires a type of 'array'.",
),
(
['[]:=2', 'x=y'],
"HTTPie Type Error: Cannot perform 'key' based access on '' which has a type of 'array' but this operation requires a type of 'object'.",
"HTTPie Type Error: Can't perform 'key' based access on '' which has a type of 'array' but this operation requires a type of 'object'.",
),
(
[':=[1,2,3]', '[]:=4'],
"HTTPie Type Error: Cannot perform 'append' based access on '' which has a type of 'object' but this operation requires a type of 'array'.",
"HTTPie Type Error: Can't perform 'append' based access on '' which has a type of 'object' but this operation requires a type of 'array'.",
),
(
['[]:=4', ':=[1,2,3]'],
"HTTPie Type Error: Cannot perform 'key' based access on '' which has a type of 'array' but this operation requires a type of 'object'.",
"HTTPie Type Error: Can't perform 'key' based access on '' which has a type of 'array' but this operation requires a type of 'object'.",
),
],
)
def test_nested_json_errors(input_json, expected_error, httpbin):
with pytest.raises(NestedJSONSyntaxError) as exc:
with pytest.raises(HTTPieSyntaxError) as exc:
http(httpbin + '/post', *input_json)
exc_lines = str(exc.value).splitlines()

View File

@ -199,7 +199,7 @@ class TestVerboseFlag:
assert 'foo bar' in r
def test_verbose_form(self, httpbin):
# https://github.com/httpie/cli/issues/53
# https://github.com/httpie/httpie/issues/53
r = http('--verbose', '--form', 'POST', httpbin.url + '/post',
'A=B', 'C=D')
assert HTTP_OK in r

View File

@ -117,8 +117,6 @@ def test_plugins_double_uninstall(httpie_plugins, httpie_plugins_success, dummy_
)
# TODO: Make this work on CI (stopped working at some point)
@pytest.mark.skip(reason='Doesnt work in CI')
@pytest.mark.requires_installation
def test_plugins_upgrade(httpie_plugins, httpie_plugins_success, dummy_plugin):
httpie_plugins_success("install", dummy_plugin.path)

View File

@ -26,7 +26,7 @@ def test_follow_without_all_redirects_hidden(httpbin, follow_flag):
assert HTTP_OK in r
@pytest.mark.xfail(True, reason="https://github.com/httpie/cli/issues/1082")
@pytest.mark.xfail(True, reason="https://github.com/httpie/httpie/issues/1082")
def test_follow_output_options_used_for_redirects(httpbin):
r = http('--follow', '--print=H', httpbin.url + '/redirect/2')
assert r.count('GET /') == 1

View File

@ -1,14 +1,17 @@
"""Miscellaneous regression tests"""
import pytest
from httpie.cli.argtypes import KeyValueArgType
from httpie.cli.constants import SEPARATOR_HEADER, SEPARATOR_QUERY_PARAM, SEPARATOR_DATA_STRING
from httpie.cli.requestitems import RequestItems
from httpie.compat import is_windows
from .utils.matching import assert_output_matches, Expect
from .utils import HTTP_OK, MockEnvironment, http
from .utils.matching import assert_output_matches, Expect
def test_Host_header_overwrite(httpbin):
"""
https://github.com/httpie/cli/issues/235
https://github.com/httpie/httpie/issues/235
"""
host = 'pie.dev'
@ -22,7 +25,7 @@ def test_Host_header_overwrite(httpbin):
@pytest.mark.skipif(is_windows, reason='Unix-only')
def test_output_devnull(httpbin):
"""
https://github.com/httpie/cli/issues/252
https://github.com/httpie/httpie/issues/252
"""
http('--output=/dev/null', httpbin + '/get')
@ -31,7 +34,7 @@ def test_output_devnull(httpbin):
def test_verbose_redirected_stdout_separator(httpbin):
"""
<https://github.com/httpie/cli/issues/1006>
<https://github.com/httpie/httpie/issues/1006>
"""
r = http(
'-v',
@ -47,3 +50,21 @@ def test_verbose_redirected_stdout_separator(httpbin):
Expect.RESPONSE_HEADERS,
Expect.BODY,
])
@pytest.mark.parametrize(['separator', 'target'], [
(SEPARATOR_HEADER, 'headers'),
(SEPARATOR_QUERY_PARAM, 'params'),
(SEPARATOR_DATA_STRING, 'data'),
])
def test_initial_backslash_number(separator, target):
"""
<https://github.com/httpie/httpie/issues/1408>
"""
back_digit = r'\0'
raw_arg = back_digit + separator + back_digit
expected_parsed_data = {back_digit: back_digit}
parsed_arg = KeyValueArgType(separator)(raw_arg)
items = RequestItems.from_args([parsed_arg])
parsed_data = getattr(items, target)
assert parsed_data == expected_parsed_data

View File

@ -203,7 +203,7 @@ class TestSession(SessionTestBase):
def test_session_with_cookie_followed_by_another_header(self, httpbin):
"""
Make sure headers dont get mutated <https://github.com/httpie/cli/issues/1126>
Make sure headers dont get mutated <https://github.com/httpie/httpie/issues/1126>
"""
self.start_session(httpbin)
session_data = {
@ -239,7 +239,7 @@ class TestSession(SessionTestBase):
def test_session_default_header_value_overwritten(self, httpbin):
self.start_session(httpbin)
# https://github.com/httpie/cli/issues/180
# https://github.com/httpie/httpie/issues/180
r1 = http('--session=test',
httpbin.url + '/headers', 'User-Agent:custom',
env=self.env())
@ -251,7 +251,7 @@ class TestSession(SessionTestBase):
assert r2.json['headers']['User-Agent'] == 'custom'
def test_download_in_session(self, tmp_path, httpbin):
# https://github.com/httpie/cli/issues/412
# https://github.com/httpie/httpie/issues/412
self.start_session(httpbin)
cwd = os.getcwd()
os.chdir(tmp_path)
@ -335,7 +335,7 @@ class TestSession(SessionTestBase):
assert HTTP_OK in r1
assert HTTP_OK in r2
# additional test for issue: https://github.com/httpie/cli/issues/1098
# additional test for issue: https://github.com/httpie/httpie/issues/1098
with open(session_path) as session_file:
session_file_lines = ''.join(session_file.readlines())
assert "\"type\": \"test-prompted\"" in session_file_lines
@ -427,7 +427,7 @@ class TestExpiredCookies(CookieTestBase):
),
(
# Checks we gracefully ignore expires date in invalid format.
# <https://github.com/httpie/cli/issues/963>
# <https://github.com/httpie/httpie/issues/963>
'pfg=; Expires=Sat, 19-Sep-2020 06:58:14 GMT+0000; Max-Age=0; path=/; domain=.tumblr.com; secure; HttpOnly',
None,
[]
@ -446,7 +446,7 @@ class TestExpiredCookies(CookieTestBase):
class TestCookieStorage(CookieTestBase):
@pytest.mark.parametrize(
['specified_cookie_header', 'new_cookies_dict', 'expected_effective_cookie_header'],
'new_cookies, new_cookies_dict, expected',
[(
'new=bar',
{'new': 'bar'},
@ -463,9 +463,9 @@ class TestCookieStorage(CookieTestBase):
'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
),
(
'new=bar; chocolate=milk',
'new=bar;; chocolate=milk;;;',
{'new': 'bar', 'chocolate': 'milk'},
'cookie1=foo; cookie2=foo; new=bar; chocolate=milk'
'cookie1=foo; cookie2=foo; new=bar'
),
(
'new=bar; chocolate=milk;;;',
@ -474,35 +474,20 @@ class TestCookieStorage(CookieTestBase):
)
]
)
def test_existing_and_new_cookies_sent_in_request(
self,
specified_cookie_header,
new_cookies_dict,
expected_effective_cookie_header,
httpbin,
):
def test_existing_and_new_cookies_sent_in_request(self, new_cookies, new_cookies_dict, expected, httpbin):
r = http(
'--session', str(self.session_path),
'--print=H',
httpbin.url,
'Cookie:' + specified_cookie_header,
'Cookie:' + new_cookies,
)
parsed_request_headers = { # noqa
name: value for name, value in [
line.split(': ', 1)
for line in r.splitlines()
if line and ':' in line
]
}
# Note: cookies in the request are in an undefined order.
expected_request_cookie_set = set(expected_effective_cookie_header.split('; '))
actual_request_cookie_set = set(parsed_request_headers['Cookie'].split('; '))
assert actual_request_cookie_set == expected_request_cookie_set
# Note: cookies in response are in alphabetical order
assert f'Cookie: {expected}' in r
updated_session = json.loads(self.session_path.read_text(encoding=UTF8))
assert 'Cookie' not in updated_session['headers']
for name, value in new_cookies_dict.items():
assert updated_session['cookies'][name]['value'] == value
assert name, value in updated_session['cookies']
assert 'Cookie' not in updated_session['headers']
@pytest.mark.parametrize(
'cli_cookie, set_cookie, expected',

View File

@ -7,7 +7,7 @@ import urllib3
from unittest import mock
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS
from httpie.status import ExitStatus
from .utils import HTTP_OK, TESTS_ROOT, IS_PYOPENSSL, http
@ -15,7 +15,7 @@ from .utils import HTTP_OK, TESTS_ROOT, IS_PYOPENSSL, http
try:
# Handle OpenSSL errors, if installed.
# See <https://github.com/httpie/cli/issues/729>
# See <https://github.com/httpie/httpie/issues/729>
# noinspection PyUnresolvedReferences
import OpenSSL.SSL
ssl_errors = (
@ -146,7 +146,7 @@ def test_ciphers(httpbin_secure):
r = http(
httpbin_secure.url + '/get',
'--ciphers',
DEFAULT_SSL_CIPHERS_STRING,
DEFAULT_SSL_CIPHERS,
)
assert HTTP_OK in r