diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 560835dab2..dd168f0114 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -13,8 +13,8 @@ jobs: if: github.event.label.name == 'benchmark' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: "3.9" @@ -30,7 +30,7 @@ jobs: echo "::set-output name=body::$body" - name: Find Comment - uses: peter-evans/find-comment@v1 + uses: peter-evans/find-comment@v2 id: fc with: issue-number: ${{ github.event.pull_request.number }} @@ -38,7 +38,7 @@ jobs: body-includes: '# Benchmarks' - name: Create or update comment - uses: peter-evans/create-or-update-comment@v1 + uses: peter-evans/create-or-update-comment@v2 with: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/code-style.yml b/.github/workflows/code-style.yml index 3d220d72f0..779bf09b8b 100644 --- a/.github/workflows/code-style.yml +++ b/.github/workflows/code-style.yml @@ -13,8 +13,8 @@ jobs: code-style: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: 3.9 - run: make venv diff --git a/.github/workflows/content.yml b/.github/workflows/content.yml new file mode 100644 index 0000000000..d5d6dbcfa4 --- /dev/null +++ b/.github/workflows/content.yml @@ -0,0 +1,22 @@ +name: Update Generated Content +on: + push: + branches: + - master +jobs: + update-content: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: 3.9 + - run: make content + - 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" + delete-branch: true + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5edb47fa46..f4a21794d1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -12,8 +12,8 @@ jobs: coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: "3.10" - run: make install diff --git a/.github/workflows/docs-check-markdown.yml b/.github/workflows/docs-check-markdown.yml index f019bf7017..a19c25916a 100644 --- a/.github/workflows/docs-check-markdown.yml +++ b/.github/workflows/docs-check-markdown.yml @@ -10,7 +10,7 @@ jobs: doc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index 62df9c0c0d..797bdc56e0 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -17,6 +17,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Install HTTPie - run: sudo snap install --edge httpie + run: sudo pip install httpie - name: Trigger new documentation build run: http --ignore-stdin POST ${{ secrets.DOCS_UPDATE_VERCEL_HOOK }} diff --git a/.github/workflows/docs-update-install.yml b/.github/workflows/docs-update-install.yml deleted file mode 100644 index 3a22aaa0bb..0000000000 --- a/.github/workflows/docs-update-install.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Update & Install Docs - -on: - push: - branches: - - master - paths: - - .github/workflows/docs-update-install.yml - - docs/installation/* - - # Allow to call the workflow manually - workflow_dispatch: - -jobs: - doc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - run: make install - - run: make doc-update-install - - uses: Automattic/action-commit-to-branch@master - with: - branch: master - commit_message: | - Auto-update install docs - - Via .github/workflows/docs-update-install.yml - - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-brew.yml b/.github/workflows/release-brew.yml new file mode 100644 index 0000000000..d58e6b6e3d --- /dev/null +++ b/.github/workflows/release-brew.yml @@ -0,0 +1,26 @@ +name: Release on Homebrew + +on: + workflow_dispatch: + inputs: + branch: + description: "The branch, tag or SHA to release from" + required: true + default: "master" + +jobs: + brew-release: + name: Release the Homebrew Package + runs-on: macos-latest + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.branch }} + + - uses: mislav/bump-homebrew-formula-action@v2 + with: + formula-name: httpie + tag-name: ${{ github.events.inputs.branch }} + env: + COMMITTER_TOKEN: ${{ secrets.BREW_UPDATE_TOKEN }} diff --git a/.github/workflows/release-choco.yml b/.github/workflows/release-choco.yml new file mode 100644 index 0000000000..01e0c40642 --- /dev/null +++ b/.github/workflows/release-choco.yml @@ -0,0 +1,61 @@ +name: Release on Chocolatey + +on: + workflow_dispatch: + inputs: + branch: + description: "The branch, tag or SHA to release from" + required: true + default: "master" + +jobs: + brew-release: + name: Release the Chocolatey + runs-on: windows-2019 + env: + package-dir: docs\packaging\windows-chocolatey + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.branch }} + + # Chocolatey comes already installed on the Windows GHA image + - name: Build the Choco package + shell: cmd + run: choco pack -v + working-directory: ${{ env.package-dir }} + + - name: Check the Choco package + run: choco info httpie -s . + working-directory: ${{ env.package-dir }} + + - name: Local installation + run: | + choco install httpie -y -dv -s "'.;https://community.chocolatey.org/api/v2/'" + working-directory: ${{ env.package-dir }} + + - name: Test the locally installed binaries + run: | + # Source: https://stackoverflow.com/a/46760714/15330941 + + # Make `refreshenv` available right away, by defining the $env:ChocolateyInstall + # variable and importing the Chocolatey profile module. + $env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.." + Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + refreshenv + + http --version + https --version + httpie --version + choco uninstall -y httpie + working-directory: ${{ env.package-dir }} + + - name: Publish on Chocolatey + shell: bash + env: + CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }} + run: | + choco apikey --key $CHOCO_API_KEY --source https://push.chocolatey.org/ + choco push httpie*.nupkg --source https://push.chocolatey.org/ + working-directory: ${{ env.package-dir }} diff --git a/.github/workflows/release-linux-standalone.yml b/.github/workflows/release-linux-standalone.yml new file mode 100644 index 0000000000..01821c9a91 --- /dev/null +++ b/.github/workflows/release-linux-standalone.yml @@ -0,0 +1,77 @@ +name: Release as Standalone Linux Package + +on: + workflow_dispatch: + inputs: + branch: + description: "The branch, tag or SHA to release from" + required: true + default: "master" + tag_name: + description: "Which release to upload the artifacts to (e.g., 3.0)" + required: true + + release: + types: [released, prereleased] + + +jobs: + binary-build-and-release: + name: Build and Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.branch }} + + - uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Build Artifacts + run: | + cd extras/packaging/linux + ./get_release_artifacts.sh + + - uses: actions/upload-artifact@v3 + with: + name: http + path: extras/packaging/linux/artifacts/dist/http + + - uses: actions/upload-artifact@v3 + with: + name: httpie.deb + path: extras/packaging/linux/artifacts/dist/*.deb + + - uses: actions/upload-artifact@v3 + with: + name: httpie.rpm + path: extras/packaging/linux/artifacts/dist/*.rpm + + - name: Determine the release upload upload_url + id: release_id + run: | + pip install httpie + export API_URL="api.github.com/repos/httpie/cli/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" + + - name: Publish Debian Package + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.release_id.outputs.UPLOAD_URL }} + asset_path: extras/packaging/linux/artifacts/dist/httpie_${{ github.event.inputs.tag_name }}_amd64.deb + asset_name: httpie-${{ github.event.inputs.tag_name }}.deb + asset_content_type: binary/octet-stream + + - name: Publish Single Executable + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.release_id.outputs.UPLOAD_URL }} + asset_path: extras/packaging/linux/artifacts/dist/http + asset_name: http + asset_content_type: binary/octet-stream diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml new file mode 100644 index 0000000000..28ad081712 --- /dev/null +++ b/.github/workflows/release-pypi.yml @@ -0,0 +1,30 @@ +name: Release on PyPI + +on: + workflow_dispatch: + inputs: + branch: + description: "The branch, tag or SHA to release from" + required: true + default: "master" + +jobs: + pypi-build-and-release: + name: Build and Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.branch }} + + - uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Build a binary wheel and a source tarball + run: make install && make build + + - name: Release on PyPI + uses: pypa/gh-action-pypi-publish@master + with: + password: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/release-snap.yml b/.github/workflows/release-snap.yml index f67c0e2577..ad25186e88 100644 --- a/.github/workflows/release-snap.yml +++ b/.github/workflows/release-snap.yml @@ -1,4 +1,4 @@ -name: Release snap +name: Release on Snap on: workflow_dispatch: @@ -7,22 +7,35 @@ on: description: "The branch, tag or SHA to release from" required: true default: "master" - level: - description: "Release level: stable, candidate, beta, edge" - required: true - default: "edge" jobs: - snap: + snap-build-and-release: + name: Build & Release the Snap Package runs-on: ubuntu-latest + + strategy: + # If any of the stages fail, then we'll stop the action + # to give release manager time to investigate the underlying + # issue. + fail-fast: true + matrix: + level: [edge, beta, candidate, stable] + + # Set the concurrency level for this version, so + # that we'll release one by one. + concurrency: ${{ github.event.inputs.branch }} + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: ${{ github.event.inputs.branch }} + - uses: snapcore/action-build@v1 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: ${{ github.event.inputs.level }} + release: ${{ matrix.level }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 12753b49f5..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Release on PyPI - -on: - # Add a "Trigger" button to manually start the workflow. - workflow_dispatch: - inputs: - branch: - description: "The branch, tag or SHA to release from" - required: true - default: "master" - # It could be fully automated by uncommenting following lines. - # Let's see later if we are confident enough to try it :) - # release: - # types: - # - published - -jobs: - new-release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: ${{ github.event.inputs.branch }} - - name: PyPI configuration - run: | - echo "[distutils]\nindex-servers=\n httpie\n\n[httpie]\nrepository = https://upload.pypi.org/legacy/\n" > $HOME/.pypirc - - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - run: make publish - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index a3aae58de5..7aa2e24555 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v4 + - uses: actions/stale@v8 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' diff --git a/.github/workflows/test-package-linux-snap.yml b/.github/workflows/test-package-linux-snap.yml index 12a2766a40..ac9640a06d 100644 --- a/.github/workflows/test-package-linux-snap.yml +++ b/.github/workflows/test-package-linux-snap.yml @@ -12,7 +12,7 @@ jobs: snap: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build uses: snapcore/action-build@v1 id: snapcraft diff --git a/.github/workflows/test-package-mac-brew.yml b/.github/workflows/test-package-mac-brew.yml index 6570a2afd9..babdaa5def 100644 --- a/.github/workflows/test-package-mac-brew.yml +++ b/.github/workflows/test-package-mac-brew.yml @@ -11,7 +11,7 @@ jobs: brew: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup brew run: | brew developer on diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e3cde99669..d98b63ae69 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,7 @@ name: Tests +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true on: push: @@ -21,13 +24,19 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.7, 3.8, 3.9, "3.10"] + os: [ubuntu-latest, macos-13, windows-latest] + python-version: + - '3.12' + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - '3.7' pyopenssl: [0, 1] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Windows setup diff --git a/.gitignore b/.gitignore index 4f4d94543e..aee3301cc3 100644 --- a/.gitignore +++ b/.gitignore @@ -43,8 +43,8 @@ MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest *.spec +*.manifest # Installer logs pip-log.txt @@ -151,3 +151,5 @@ dmypy.json # Windows Chocolatey *.nupkg + +artifacts/ diff --git a/.packit.yaml b/.packit.yaml index 8fc33379d6..015fdf8e57 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -3,16 +3,10 @@ specfile_path: httpie.spec actions: # get the current Fedora Rawhide specfile: - # post-upstream-clone: "wget https://src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -O httpie.spec" - post-upstream-clone: "cp docs/packaging/linux-fedora/httpie.spec.txt httpie.spec" + post-upstream-clone: "wget https://src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -O httpie.spec" + # Use this when the latest spec is not up-to-date. + # post-upstream-clone: "cp docs/packaging/linux-fedora/httpie.spec.txt httpie.spec" jobs: -- job: copr_build - trigger: pull_request - metadata: - targets: - - fedora-all - additional_repos: - - "https://kojipkgs.fedoraproject.org/repos/f$releasever-build/latest/$basearch/" - job: propose_downstream trigger: release metadata: diff --git a/AUTHORS.md b/AUTHORS.md index 72fc384df6..5351307d84 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -4,7 +4,7 @@ ## Patches, features, ideas -[Complete list of contributors on GitHub](https://github.com/httpie/httpie/graphs/contributors) +[Complete list of contributors on GitHub](https://github.com/httpie/cli/graphs/contributors) - [Cláudia T. Delgado](https://github.com/claudiatd) - [Hank Gay](https://github.com/gthank) diff --git a/CHANGELOG.md b/CHANGELOG.md index 045d406cfe..0497ac3508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,112 +3,156 @@ This document records all notable changes to [HTTPie](https://httpie.io). This project adheres to [Semantic Versioning](https://semver.org/). -## [3.0.2](https://github.com/httpie/httpie/compare/3.0.1...3.0.2) (2022-01-24) +## [3.2.4](https://github.com/httpie/cli/compare/3.2.3...3.2.4) (2024-11-01) + +- Fix default certs loading and unpin `requests`. ([#1596](https://github.com/httpie/cli/issues/1596)) + +## [3.2.3](https://github.com/httpie/cli/compare/3.2.2...3.2.3) (2024-07-10) + +- Fix SSL connections by pinning the `requests` version to `2.31.0`. (#1583, #1581) +- Make it possible to [unset](https://httpie.io/docs/cli/default-request-headers) the `User-Agent` and `Accept-Encoding` request headers. ([#1502](https://github.com/httpie/cli/issues/1502)) + +## [3.2.2](https://github.com/httpie/cli/compare/3.2.1...3.2.2) (2023-05-19) + +- Fixed compatibility with urllib3 2.0.0. ([#1499](https://github.com/httpie/cli/issues/1499)) + +## [3.2.1](https://github.com/httpie/cli/compare/3.1.0...3.2.1) (2022-05-06) + +- 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)) + +## [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) [What’s 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/httpie/pull/1280)) +- Fixed usage of `httpie` when there is a presence of a config with `default_options`. ([#1280](https://github.com/httpie/cli/pull/1280)) -## [3.0.1](https://github.com/httpie/httpie/compare/3.0.0...3.0.1) (2022-01-23) +## [3.0.1](https://github.com/httpie/cli/compare/3.0.0...3.0.1) (2022-01-23) [What’s 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/httpie/issues/1277)) +- Changed the value shown as time elapsed from time-to-read-headers to total exchange time. ([#1277](https://github.com/httpie/cli/issues/1277)) -## [3.0.0](https://github.com/httpie/httpie/compare/2.6.0...3.0.0) (2022-01-21) +## [3.0.0](https://github.com/httpie/cli/compare/2.6.0...3.0.0) (2022-01-21) [What’s 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/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/httpie/compare/2.5.0...2.6.0) (2021-10-14) +- 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)) + +## [2.6.0](https://github.com/httpie/cli/compare/2.5.0...2.6.0) (2021-10-14) [What’s 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/httpie/issues/1130)) -- Added charset auto-detection when `Content-Type` doesn’t 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)) +- 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` doesn’t 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)) -## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06) +## [2.5.0](https://github.com/httpie/cli/compare/2.4.0...2.5.0) (2021-09-06) [What’s 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/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)) + 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)) -## [2.4.0](https://github.com/httpie/httpie/compare/2.3.0...2.4.0) (2021-02-06) +## [2.4.0](https://github.com/httpie/cli/compare/2.3.0...2.4.0) (2021-02-06) -- Added support for `--session` cookie expiration based on `Set-Cookie: max-age=`. ([#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)). +- Added support for `--session` cookie expiration based on `Set-Cookie: max-age=`. ([#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)). -## [2.3.0](https://github.com/httpie/httpie/compare/2.2.0...2.3.0) (2020-10-25) +## [2.3.0](https://github.com/httpie/cli/compare/2.2.0...2.3.0) (2020-10-25) -- Added support for streamed uploads ([#201](https://github.com/httpie/httpie/issues/201)). -- Added support for multipart upload streaming ([#684](https://github.com/httpie/httpie/issues/684)). +- Added support for 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 body-from-file upload streaming (`http pie.dev/post @file`). -- Added `--chunked` to enable chunked transfer encoding ([#753](https://github.com/httpie/httpie/issues/753)). +- Added `--chunked` to enable chunked transfer encoding ([#753](https://github.com/httpie/cli/issues/753)). - Added `--multipart` to allow `multipart/form-data` encoding for non-file `--form` requests as well. -- Added support for preserving field order in multipart requests ([#903](https://github.com/httpie/httpie/issues/903)). +- Added support for preserving field order in multipart requests ([#903](https://github.com/httpie/cli/issues/903)). - Added `--boundary` to allow a custom boundary string for `multipart/form-data` requests. -- Added support for combining cookies specified on the CLI and in a session file ([#932](https://github.com/httpie/httpie/issues/932)). -- Added out of the box SOCKS support with no extra installation ([#904](https://github.com/httpie/httpie/issues/904)). +- Added 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 `--quiet, -q` flag to enforce silent behaviour. -- Fixed the handling of invalid `expires` dates in `Set-Cookie` headers ([#963](https://github.com/httpie/httpie/issues/963)). -- Removed Tox testing entirely ([#943](https://github.com/httpie/httpie/issues/943)). +- 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)). -## [2.2.0](https://github.com/httpie/httpie/compare/2.1.0...2.2.0) (2020-06-18) +## [2.2.0](https://github.com/httpie/cli/compare/2.1.0...2.2.0) (2020-06-18) -- Added support for custom content types for uploaded files ([#668](https://github.com/httpie/httpie/issues/668)). -- Added support for `$XDG_CONFIG_HOME` ([#920](https://github.com/httpie/httpie/issues/920)). -- Added support for `Set-Cookie`-triggered cookie expiration ([#853](https://github.com/httpie/httpie/issues/853)). -- Added `--format-options` to allow disabling sorting, etc. ([#128](https://github.com/httpie/httpie/issues/128)) -- Added `--sorted` and `--unsorted` shortcuts for (un)setting all sorting-related `--format-options`. ([#128](https://github.com/httpie/httpie/issues/128)) -- Added `--ciphers` to allow configuring OpenSSL ciphers ([#870](https://github.com/httpie/httpie/issues/870)). +- Added 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 `netrc` support for auth plugins. Enabled for `--auth-type=basic` - and `digest`, 3rd parties may opt in ([#718](https://github.com/httpie/httpie/issues/718), [#719](https://github.com/httpie/httpie/issues/719), [#852](https://github.com/httpie/httpie/issues/852), [#934](https://github.com/httpie/httpie/issues/934)). -- Fixed built-in plugins-related circular imports ([#925](https://github.com/httpie/httpie/issues/925)). + 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)). -## [2.1.0](https://github.com/httpie/httpie/compare/2.0.0...2.1.0) (2020-04-18) +## [2.1.0](https://github.com/httpie/cli/compare/2.0.0...2.1.0) (2020-04-18) - Added `--path-as-is` to bypass dot segment (`/../` or `/./`) - URL squashing ([#895](https://github.com/httpie/httpie/issues/895)). + URL squashing ([#895](https://github.com/httpie/cli/issues/895)). - Changed the default `Accept` header value for JSON requests from `application/json, */*` to `application/json, */*;q=0.5` - to clearly indicate preference ([#488](https://github.com/httpie/httpie/issues/488)). + to clearly indicate preference ([#488](https://github.com/httpie/cli/issues/488)). - Fixed `--form` file upload mixed with redirected `stdin` error handling - ([#840](https://github.com/httpie/httpie/issues/840)). + ([#840](https://github.com/httpie/cli/issues/840)). -## [2.0.0](https://github.com/httpie/httpie/compare/1.0.3...2.0.0) (2020-01-12) +## [2.0.0](https://github.com/httpie/cli/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 @@ -131,7 +175,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/httpie/compare/1.0.2...1.0.3) (2019-08-26) +## [1.0.3](https://github.com/httpie/cli/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 @@ -157,15 +201,15 @@ This project adheres to [Semantic Versioning](https://semver.org/). Reported by Raul Onitza and Giulio Comi. -## [1.0.2](https://github.com/httpie/httpie/compare/1.0.1...1.0.2) (2018-11-14) +## [1.0.2](https://github.com/httpie/cli/compare/1.0.1...1.0.2) (2018-11-14) - Fixed tests for installation with pyOpenSSL. -## [1.0.1](https://github.com/httpie/httpie/compare/1.0.0...1.0.1) (2018-11-14) +## [1.0.1](https://github.com/httpie/cli/compare/1.0.0...1.0.1) (2018-11-14) - Removed external URL calls from tests. -## [1.0.0](https://github.com/httpie/httpie/compare/0.9.9...1.0.0) (2018-11-02) +## [1.0.0](https://github.com/httpie/cli/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` @@ -176,11 +220,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/httpie/compare/0.9.8...0.9.9) (2016-12-08) +## [0.9.9](https://github.com/httpie/cli/compare/0.9.8...0.9.9) (2016-12-08) - Fixed README. -## [0.9.8](https://github.com/httpie/httpie/compare/0.9.6...0.9.8) (2016-12-08) +## [0.9.8](https://github.com/httpie/cli/compare/0.9.6...0.9.8) (2016-12-08) - Extended auth plugin API. - Added exit status code `7` for plugin errors. @@ -189,7 +233,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/httpie/compare/0.9.4...0.9.6) (2016-08-13) +## [0.9.6](https://github.com/httpie/cli/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 @@ -208,7 +252,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/httpie/compare/0.9.3...0.9.4) (2016-07-01) +## [0.9.4](https://github.com/httpie/cli/compare/0.9.3...0.9.4) (2016-07-01) - Added `Content-Type` of files uploaded in `multipart/form-data` requests - Added `--ssl=` to specify the desired SSL/TLS protocol version @@ -232,7 +276,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/httpie/compare/0.9.2...0.9.3) (2016-01-01) +## [0.9.3](https://github.com/httpie/cli/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) @@ -242,19 +286,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/httpie/compare/0.9.1...0.9.2) (2015-02-24) +## [0.9.2](https://github.com/httpie/cli/compare/0.9.1...0.9.2) (2015-02-24) - Fixed compatibility with Requests 2.5.1 - Changed the default JSON `Content-Type` to `application/json` as UTF-8 is the default JSON encoding -## [0.9.1](https://github.com/httpie/httpie/compare/0.9.0...0.9.1) (2015-02-07) +## [0.9.1](https://github.com/httpie/cli/compare/0.9.0...0.9.1) (2015-02-07) - Added support for Requests transport adapter plugins (see [httpie-unixsocket](https://github.com/httpie/httpie-unixsocket) and [httpie-http2](https://github.com/httpie/httpie-http2)) -## [0.9.0](https://github.com/httpie/httpie/compare/0.8.0...0.9.0) (2015-01-31) +## [0.9.0](https://github.com/httpie/cli/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 @@ -273,7 +317,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/httpie/compare/0.7.1...0.8.0) (2014-01-25) +## [0.8.0](https://github.com/httpie/cli/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 @@ -281,7 +325,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/httpie/compare/0.6.0...0.7.1) (2013-09-24) +## [0.7.1](https://github.com/httpie/cli/compare/0.6.0...0.7.1) (2013-09-24) - Added `--ignore-stdin` - Added support for auth plugins @@ -289,27 +333,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/httpie/compare/0.5.1...0.6.0) (2013-06-03) +## [0.6.0](https://github.com/httpie/cli/compare/0.5.1...0.6.0) (2013-06-03) - XML data is now formatted - `--session` and `--session-read-only` now also accept paths to session files (eg. `http --session=/tmp/session.json example.org`) -## [0.5.1](https://github.com/httpie/httpie/compare/0.5.0...0.5.1) (2013-05-13) +## [0.5.1](https://github.com/httpie/cli/compare/0.5.0...0.5.1) (2013-05-13) - `Content-*` and `If-*` request headers are not stored in sessions anymore as they are request-specific -## [0.5.0](https://github.com/httpie/httpie/compare/0.4.1...0.5.0) (2013-04-27) +## [0.5.0](https://github.com/httpie/cli/compare/0.4.1...0.5.0) (2013-04-27) - Added a download mode via `--download` - Fixes miscellaneous bugs -## [0.4.1](https://github.com/httpie/httpie/compare/0.4.0...0.4.1) (2013-02-26) +## [0.4.1](https://github.com/httpie/cli/compare/0.4.0...0.4.1) (2013-02-26) - Fixed `setup.py` -## [0.4.0](https://github.com/httpie/httpie/compare/0.3.0...0.4.0) (2013-02-22) +## [0.4.0](https://github.com/httpie/cli/compare/0.3.0...0.4.0) (2013-02-22) - Added Python 3.3 compatibility - Added Requests >= v1.0.4 compatibility @@ -318,7 +362,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/httpie/compare/0.2.7...0.3.0) (2012-09-21) +## [0.3.0](https://github.com/httpie/cli/compare/0.2.7...0.3.0) (2012-09-21) - Allow output redirection on Windows - Added configuration file @@ -333,7 +377,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/httpie/compare/0.2.5...0.2.7) (2012-08-07) +## [0.2.7](https://github.com/httpie/cli/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 @@ -350,7 +394,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/httpie/compare/0.2.5...0.2.6) (2012-07-26) +## [0.2.6](https://github.com/httpie/cli/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`) @@ -365,7 +409,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/httpie/compare/0.2.2...0.2.5) (2012-07-17) +## [0.2.5](https://github.com/httpie/cli/compare/0.2.2...0.2.5) (2012-07-17) - Unicode characters in prettified JSON now don't get escaped for improved readability @@ -376,20 +420,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/httpie/compare/0.2.1...0.2.2) (2012-06-24) +## [0.2.2](https://github.com/httpie/cli/compare/0.2.1...0.2.2) (2012-06-24) - The `METHOD` positional argument can now be omitted (defaults to `GET`, or to `POST` with data) - Fixed --verbose --form - Added support for Tox -## [0.2.1](https://github.com/httpie/httpie/compare/0.2.0...0.2.1) (2012-06-13) +## [0.2.1](https://github.com/httpie/cli/compare/0.2.0...0.2.1) (2012-06-13) - Added compatibility with `requests-0.12.1` - Dropped custom JSON and HTTP lexers in favor of the ones newly included in `pygments-1.5` -## [0.2.0](https://github.com/httpie/httpie/compare/0.1.6...0.2.0) (2012-04-25) +## [0.2.0](https://github.com/httpie/cli/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 @@ -401,18 +445,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/httpie/compare/0.1.5...0.1.6) (2012-03-04) +## [0.1.6](https://github.com/httpie/cli/compare/0.1.5...0.1.6) (2012-03-04) - Fixed `setup.py` -## [0.1.5](https://github.com/httpie/httpie/compare/0.1.4...0.1.5) (2012-03-04) +## [0.1.5](https://github.com/httpie/cli/compare/0.1.4...0.1.5) (2012-03-04) - Many improvements and bug fixes -## [0.1.4](https://github.com/httpie/httpie/compare/b966efa...0.1.4) (2012-02-28) +## [0.1.4](https://github.com/httpie/cli/compare/b966efa...0.1.4) (2012-02-28) - Many improvements and bug fixes -## [0.1.0](https://github.com/httpie/httpie/commit/b966efa) (2012-02-25) +## [0.1.0](https://github.com/httpie/cli/commit/b966efa) (2012-02-25) - Initial public release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 555aa913b9..1360184a8b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ $ http --debug ## 2. Contributing Code and Docs -Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/httpie/issues) +Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/cli/issues) to see whether it has previously been discussed. If your change alters HTTPie’s 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/httpie/blob/master/CHANGELOG.md) entry for your changes. +Consider also adding a [CHANGELOG](https://github.com/httpie/cli/blob/master/CHANGELOG.md) entry for your changes. ### Development Environment #### Getting the code -Go to and fork the project repository. +Go to and fork the project repository. ```bash # Clone your fork @@ -59,8 +59,10 @@ $ git checkout -b my_topical_branch #### Setup -The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started. Just run -the following command, which: +The [Makefile](https://github.com/httpie/cli/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: - Creates an isolated Python virtual environment inside `./venv` (via the standard library [venv](https://docs.python.org/3/library/venv.html) tool); @@ -70,7 +72,7 @@ the following command, which: - and runs tests (It is the same as running `make install test`). ```bash -$ make +$ make all ``` #### Python virtual environment @@ -110,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/httpie/actions) will automatically run HTTPie’s [test suite](https://github.com/httpie/httpie/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/cli/actions) will automatically run HTTPie’s [test suite](https://github.com/httpie/cli/tree/master/tests) against your code, so please make sure all checks pass. #### Running tests locally @@ -142,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/httpie/blob/master/Makefile) for additional development utilities. +See [Makefile](https://github.com/httpie/cli/blob/master/Makefile) for additional development utilities. #### Running benchmarks @@ -152,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/benchmarks/run.py +$ python extras/profiling/run.py ``` The benchmarks can also be run on the CI. Since it is a long process, it requires manual @@ -207,4 +209,4 @@ $ python -m pytest ______________________________________________________________________ -Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/httpie/blob/master/AUTHORS.md)! +Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/cli/blob/master/AUTHORS.md)! diff --git a/MANIFEST.in b/MANIFEST.in index e166aa09fb..a09a3037eb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,5 +4,5 @@ include CHANGELOG.md include AUTHORS.md include docs/README.md -# +# recursive-include tests/ * diff --git a/Makefile b/Makefile index 0e5c1a1217..a2a80a1778 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,26 @@ VENV_PYTHON=$(VENV_BIN)/python export PATH := $(VENV_BIN):$(PATH) + +default: list-tasks + + +############################################################################### +# Default task to get a list of tasks when `make' is run without args. +# +############################################################################### + +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 '^$@$$' + @echo + + +############################################################################### +# Installation +############################################################################### + all: uninstall-httpie install test @@ -30,10 +50,10 @@ install: venv install-reqs install-reqs: @echo $(H1)Updating package tools$(H1END) - $(VENV_PIP) install --upgrade pip wheel + $(VENV_PIP) install --upgrade pip wheel build @echo $(H1)Installing dev requirements$(H1END) - $(VENV_PIP) install --upgrade --editable '.[dev]' + $(VENV_PIP) install --upgrade '.[dev]' '.[test]' @echo $(H1)Installing HTTPie$(H1END) $(VENV_PIP) install --upgrade --editable . @@ -104,7 +124,8 @@ test-dist: test-sdist test-bdist-wheel test-sdist: clean venv @echo $(H1)Testing sdist build an installation$(H1END) - $(VENV_PYTHON) setup.py sdist + $(VENV_PIP) install build + $(VENV_PYTHON) -m build --sdist $(VENV_PIP) install --force-reinstall --upgrade dist/*.gz $(VENV_BIN)/http --version @echo @@ -112,8 +133,8 @@ test-sdist: clean venv test-bdist-wheel: clean venv @echo $(H1)Testing wheel build an installation$(H1END) - $(VENV_PIP) install wheel - $(VENV_PYTHON) setup.py bdist_wheel + $(VENV_PIP) install build + $(VENV_PYTHON) -m build --wheel $(VENV_PIP) install --force-reinstall --upgrade dist/*.whl $(VENV_BIN)/http --version @echo @@ -147,19 +168,17 @@ doc-check: mdl --git-recurse --style docs/markdownlint.rb . -doc-update-install: - @echo $(H1)Updating installation instructions in the docs$(H1END) - $(VENV_PYTHON) docs/installation/generate.py - - ############################################################################### # Publishing to PyPi ############################################################################### build: - rm -rf build/ - $(VENV_PYTHON) setup.py sdist bdist_wheel + rm -rf build/ dist/ + mv httpie/internal/__build_channel__.py httpie/internal/__build_channel__.py.original + echo 'BUILD_CHANNEL = "pip"' > httpie/internal/__build_channel__.py + $(VENV_PYTHON) -m build --sdist --wheel --outdir dist/ + mv httpie/internal/__build_channel__.py.original httpie/internal/__build_channel__.py publish: test-all publish-no-test @@ -203,7 +222,7 @@ brew-test: - brew uninstall httpie @echo $(H1)Building from source…$(H1END) - - brew install --build-from-source ./docs/packaging/brew/httpie.rb + - brew install --HEAD --build-from-source ./docs/packaging/brew/httpie.rb @echo $(H1)Verifying…$(H1END) http --version @@ -211,3 +230,17 @@ brew-test: @echo $(H1)Auditing…$(H1END) brew audit --strict httpie + +############################################################################### +# Generated content +############################################################################### + +content: man installation-docs + +man: install + @echo $(H1)Regenerate man pages$(H1END) + $(VENV_PYTHON) extras/scripts/generate_man_pages.py + +installation-docs: + @echo $(H1)Updating installation instructions in the docs$(H1END) + $(VENV_PYTHON) docs/installation/generate.py diff --git a/README.md b/README.md index 9b8d0b58eb..13a3503b41 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,31 @@ -
- - HTTPie - -
+

+ + HTTPie + +
+ HTTPie CLI: human-friendly HTTP client for the API era +

+ +
+ +[![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) + +
+ -# HTTPie: human-friendly CLI HTTP client for the API era +
+ +[![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) + +
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. @@ -12,14 +33,22 @@ 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. -[![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) +
+ +HTTPie in action + + +
+ + + + +## We lost 54k GitHub stars + +Please note we recently accidentally made this repo private for a moment, and GitHub deleted our community that took a decade to build. Read the full story here: https://httpie.io/blog/stardust + +![](docs/stardust.png) -HTTPie in action ## Getting started @@ -45,25 +74,25 @@ They use simple and natural syntax and provide formatted and colorized output. 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): +Build and print a request without sending it using [offline mode](https://httpie.io/docs/cli/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/httpie/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/cli/issues/83) with [authentication](https://httpie.io/docs#authentication): ```bash -$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:' +http -a USERNAME POST https://api.github.com/repos/httpie/cli/issues/83/comments body='HTTPie is awesome! :heart:' ``` [See more examples →](https://httpie.io/docs#examples) @@ -74,11 +103,11 @@ $ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/com - Join our [Discord server](https://httpie.io/discord) is to ask questions, discuss features, and for general API chat. - Tweet at [@httpie](https://twitter.com/httpie) on Twitter. - Use [StackOverflow](https://stackoverflow.com/questions/tagged/httpie) to ask questions and include a `httpie` tag. -- Create [GitHub Issues](https://github.com/httpie/httpie/issues) for bug reports and feature requests. +- Create [GitHub Issues](https://github.com/httpie/cli/issues) for bug reports and feature requests. - Subscribe to the [HTTPie newsletter](https://httpie.io) for occasional updates. ## Contributing -Have a look through existing [Issues](https://github.com/httpie/httpie/issues) and [Pull Requests](https://github.com/httpie/httpie/pulls) that you could help with. If you'd like to request a feature or report a bug, please [create a GitHub Issue](https://github.com/httpie/httpie/issues) using one of the templates provided. +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. -[See contribution guide →](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md) +[See contribution guide →](https://github.com/httpie/cli/blob/master/CONTRIBUTING.md) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..542bcd7854 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security policy + +## Reporting a vulnerability + +When you identify a vulnerability in HTTPie, please report it privately using one of the following channels: + +- Email to [`security@httpie.io`](mailto:security@httpie.io) +- Report on [huntr.dev](https://huntr.dev/) + +In addition to the description of the vulnerability, include the following information: + +- A short reproducer to verify it (it can be a small HTTP server, shell script, docker image, etc.) +- Your deemed severity level of the vulnerability (`LOW`/`MEDIUM`/`HIGH`/`CRITICAL`) +- [CWE](https://cwe.mitre.org/) ID, if available. diff --git a/docs/README.md b/docs/README.md index 66bb4d6a9d..51dff51aec 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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/httpie/blob/master/docs/README.md). +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). @@ -126,77 +126,94 @@ $ choco upgrade httpie ### Linux -#### Snapcraft (Linux) +#### Debian and Ubuntu -To install [Snapcraft](https://snapcraft.io/), see [its installation](https://snapcraft.io/docs/installing-snapd). +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 -$ snap install httpie +$ curl -SsL https://packages.httpie.io/deb/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/httpie.gpg +$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" | sudo tee /etc/apt/sources.list.d/httpie.list > /dev/null +$ sudo apt update +$ sudo apt install httpie ``` ```bash # Upgrade httpie -$ snap refresh httpie +$ sudo apt update && sudo apt upgrade httpie ``` -#### Linuxbrew +#### Fedora -To install [Linuxbrew](https://docs.brew.sh/Homebrew-on-Linux), see [its installation](https://docs.brew.sh/Homebrew-on-Linux#install). +```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 -$ brew update -$ brew install httpie +$ yum install epel-release +$ yum install httpie ``` ```bash # Upgrade httpie -$ brew update -$ brew upgrade httpie +$ yum upgrade httpie ``` -#### Debian and Ubuntu +#### Single binary executables -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. +Get the standalone HTTPie Linux executables when you don't want to go through the full installation process. ```bash # Install httpie -$ apt update -$ apt install httpie +$ https --download packages.httpie.io/binaries/linux/http-latest -o http +$ ln -ls ./http ./https +$ chmod +x ./http ./https ``` ```bash # Upgrade httpie -$ apt update -$ apt upgrade httpie +$ https --download packages.httpie.io/binaries/linux/http-latest -o http ``` -#### Fedora +#### Snapcraft (Linux) + +To install [Snapcraft](https://snapcraft.io/), see [its installation](https://snapcraft.io/docs/installing-snapd). ```bash # Install httpie -$ dnf install httpie +$ snap install httpie ``` ```bash # Upgrade httpie -$ dnf upgrade httpie +$ snap refresh httpie ``` -#### CentOS and RHEL +#### Linuxbrew -Also works for other RHEL-derived distributions like ClearOS, Oracle Linux, etc. +To install [Linuxbrew](https://docs.brew.sh/Homebrew-on-Linux), see [its installation](https://docs.brew.sh/Homebrew-on-Linux#install). ```bash # Install httpie -$ yum install epel-release -$ yum install httpie +$ brew update +$ brew install httpie ``` ```bash # Upgrade httpie -$ yum upgrade httpie +$ brew update +$ brew upgrade httpie ``` #### Arch Linux @@ -205,12 +222,12 @@ Also works for other Arch-derived distributions like ArcoLinux, EndeavourOS, Art ```bash # Install httpie -$ pacman -Sy httpie +$ pacman -Syu httpie ``` ```bash # Upgrade httpie -$ pacman -Syu httpie +$ pacman -Syu ``` ### FreeBSD @@ -233,36 +250,39 @@ $ pkg upgrade www/py-httpie ### Unstable 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. +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 install it on Linux, macOS, Windows, or FreeBSD with `pip`: +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`. ```bash -$ python -m pip install --upgrade https://github.com/httpie/httpie/archive/master.tar.gz +$ python -m pip install --upgrade https://github.com/httpie/cli/archive/master.tar.gz ``` -Or on macOS, and Linux, with Homebrew: +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: ```bash $ brew uninstall --force httpie $ brew install --HEAD httpie ``` -And even on macOS, and Linux, with Snapcraft: +You can install it using Snapcraft by running the following commands: ```bash $ snap remove httpie $ snap install httpie --edge ``` -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: +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`. ```bash $ http --version -# 3.0.0 +# 3.X.X.dev0 ``` +Note that on your machine, the version name will have the `.dev0` suffix. + ## Usage Hello World: @@ -277,7 +297,7 @@ Synopsis: $ http [flags] [METHOD] URL [ITEM [ITEM]] ``` -See also `http --help`. +See also `http --help` (and for systems where man pages are available, you can use `man http`). ### Examples @@ -305,10 +325,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/httpie/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/cli/issues/83) with [authentication](#authentication): ```bash -$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:' +$ http -a USERNAME POST https://api.github.com/repos/httpie/cli/issues/83/comments body='HTTPie is awesome! :heart:' ``` Upload a file using [redirected input](#redirected-input): @@ -448,7 +468,7 @@ $ http https://api.github.com/search/repositories q==httpie per_page==1 GET /search/repositories?q=httpie&per_page=1 HTTP/1.1 ``` -You can even retrieve the `value` from a file by using the `param==@file` syntax. This would also effectively strip the newlines from the end. See [#file-based-separators] for more examples. +You can even retrieve the `value` from a file by using the `param==@file` syntax. This would also effectively strip the newlines from the end. See [file based separators](#file-based-separators) for more examples. ```bash $ http pie.dev/get text==@files/text.txt @@ -457,7 +477,7 @@ $ http pie.dev/get text==@files/text.txt ### URL shortcuts for `localhost` Additionally, curl-like shorthand for localhost is supported. -This means that, for example, `:3000` would expand to `http://localhost:3000` +This means that, for example, `:3000` would expand to `http://localhost:3000`. If the port is omitted, then port 80 is assumed. ```bash @@ -510,7 +530,7 @@ $ http-unix %2Fvar%2Frun%2Fdocker.sock/info ### `--path-as-is` -The standard behavior of HTTP clients is to normalize the path portion of URLs by squashing dot segments as a typically filesystem would: +The standard behavior of HTTP clients is to normalize the path portion of URLs by squashing dot segments as a typical filesystem would: ```bash $ http -v example.org/./../../etc/password @@ -554,7 +574,7 @@ $ http PUT pie.dev/put \ | HTTP Headers `Name:Value` | Arbitrary HTTP header, e.g. `X-API-Token:123` | | URL parameters `name==value` | Appends the given name/value pair as a querystring parameter to the URL. The `==` separator is used. | | Data Fields `field=value` | Request data fields to be serialized as a JSON object (default), to be form-encoded (with `--form, -f`), or to be serialized as `multipart/form-data` (with `--multipart`) | -| Raw JSON fields `field:=json` | Useful when sending JSON and one or more fields need to be a `Boolean`, `Number`, nested `Object`, or an `Array`, e.g., `meals:='["ham","spam"]'` or `pies:=[1,2,3]` (note the quotes) | +| Raw JSON fields `field:=json` | Useful when sending JSON and one or more fields need to be a `Boolean`, `Number`, nested `Object`, or an `Array`, e.g., `meals:='["ham","spam"]'` or `pies:='[1,2,3]'` (note the quotes) | | File upload fields `field@/dir/file`, `field@file;type=mime` | Only available with `--form`, `-f` and `--multipart`. For example `screenshot@~/Pictures/img.png`, or `'cv@cv.txt;type=text/markdown'`. With `--form`, the presence of a file field results in a `--multipart` request | Note that the structured data fields aren’t the only way to specify request data: @@ -563,7 +583,7 @@ Note that the structured data fields aren’t the only way to specify request da ### File based separators Using file contents as values for specific fields is a very common use case, which can be achieved through adding the `@` suffix to -the operators above. For example instead of using a static string as the value for some header, you can use `:@` operator +the operators above. For example, instead of using a static string as the value for some header, you can use `:@` operator to pass the desired value from a file. ```bash @@ -729,7 +749,7 @@ $ http --offline --print=B pie.dev/post \ In the example above, the `search[type]` is an instruction for creating an object called `search`, and setting the `type` field of it to the given value (`"id"`). -Also note that, just as the regular syntax, you can use the `:=` operator to directly pass raw JSON values (e.g, numbers in the case above). +Also note that, just as the regular syntax, you can use the `:=` operator to directly pass raw JSON values (e.g., numbers in the case above). ```json { @@ -854,6 +874,49 @@ $ http PUT pie.dev/put \ #### Advanced usage +##### Top level arrays + +If you want to send an array instead of a regular object, you can simply +do that by omitting the starting key: + +```bash +$ http --offline --print=B pie.dev/post \ + []:=1 \ + []:=2 \ + []:=3 +``` + +```json +[ + 1, + 2, + 3 +] +``` + +You can also apply the nesting to the items by referencing their index: + +```bash +http --offline --print=B pie.dev/post \ + [0][type]=platform [0][name]=terminal \ + [1][type]=platform [1][name]=desktop +``` + +```json +[ + { + "type": "platform", + "name": "terminal" + }, + { + "type": "platform", + "name": "desktop" + } +] +``` + +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=''`](#raw-request-body). + ##### Escaping behavior Nested JSON syntax uses the same [escaping rules](#escaping-rules) as @@ -981,7 +1044,7 @@ $ http POST pie.dev/post < files/data.json ## Forms Submitting forms is very similar to sending [JSON](#json) requests. -Often the only difference is in adding the `--form, -f` option, which ensures that data fields are serialized as, and `Content-Type` is set to `application/x-www-form-urlencoded; charset=utf-8`. +Often the only difference is in adding the `--form, -f` option, which ensures that data fields are serialized as key-value tuples separated by '&', with a '=' between the key and the value. In addition `Content-Type` is set to `application/x-www-form-urlencoded; charset=utf-8`. It is possible to make form data the implicit content type instead of JSON via the [config](#config) file. ### Regular forms @@ -1113,11 +1176,11 @@ User-Agent: HTTPie/ Host: ``` -Any of these can be overwritten and some of them unset (see below). +All of these can be overwritten or 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] 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](#file-based-separators) for more examples. ```bash $ http pie.dev/headers X-Data:@files/text.txt @@ -1172,7 +1235,7 @@ by individual commands when sending a request instead of being joined together. ### Limiting response headers -The `--max-headers=n` options allows you to control the number of headers HTTPie reads before giving up (the default `0`, i.e., there’s no limit). +The `--max-headers=n` option allows you to control the number of headers HTTPie reads before giving up (the default `0`, i.e., there’s no limit). ```bash $ http --max-headers=100 pie.dev/get @@ -1336,7 +1399,7 @@ Here are a few picks: - [httpie-jwt-auth](https://github.com/teracyhq/httpie-jwt-auth): JWTAuth (JSON Web Tokens) - [httpie-negotiate](https://github.com/ndzou/httpie-negotiate): SPNEGO (GSS Negotiate) - [httpie-ntlm](https://github.com/httpie/httpie-ntlm): NTLM (NT LAN Manager) -- [httpie-oauth](https://github.com/httpie/httpie-oauth): OAuth +- [httpie-oauth1](https://github.com/qcif/httpie-oauth1): OAuth 1.0a - [requests-hawk](https://github.com/mozilla-services/requests-hawk): Hawk See [plugin manager](#plugin-manager) for more details. @@ -1395,7 +1458,8 @@ $ 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://python-requests.org/) 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://requests.readthedocs.io/en/latest/) 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`: @@ -1448,6 +1512,21 @@ path of the key file with `--cert-key`: $ http --cert=client.crt --cert-key=client.key https://example.org ``` +If the given private key requires a passphrase, HTTPie will automatically detect it +and ask it through a prompt: + +```bash +$ http --cert=client.pem --cert-key=client.key https://example.org +http: passphrase for client.key: **** +``` + +If you don't want to see a prompt, you can supply the passphrase with the `--cert-key-pass` +argument: + +```bash +$ http --cert=client.pem --cert-key=client.key --cert-key-pass=my_password https://example.org +``` + ### SSL version Use the `--ssl=` option to specify the desired protocol version to use. @@ -1597,6 +1676,10 @@ If you’d like to silence warnings as well, use `-q` or `--quiet` twice: $ http -qq --check-status pie.dev/post enjoy='the silence without warnings' ``` +### Update warnings + +When there is a new release available for your platform (for example; if you installed HTTPie through `pip`, it will check the latest version on `PyPI`), HTTPie will regularly warn you about the new update (once a week). If you want to disable this behavior, you can set `disable_update_warnings` to `true` in your [config](#config) file. + ### Viewing intermediary requests/responses To see all the HTTP communication, i.e. the final request/response as well as any possible intermediary requests/responses, use the `--all` option. @@ -1609,14 +1692,6 @@ $ http --all --follow pie.dev/redirect/3 The intermediary requests/responses are by default formatted according to `--print, -p` (and its shortcuts described above). -If you’d like to change that, use the `--history-print, -P` option. -It takes the same arguments as `--print, -p` but applies to the intermediary requests only. - -```bash -# Print the intermediary requests/responses differently than the final one: -$ http -A digest -a foo:bar --all -p Hh -P H pie.dev/digest-auth/auth/foo/bar -``` - ### Conditional body download As an optimization, the response body is downloaded from the server only if it’s part of the output. @@ -1679,7 +1754,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/httpie | http POST pie.dev/post +$ http GET https://api.github.com/repos/httpie/cli | http POST pie.dev/post ``` You can use `cat` to enter multiline data on the terminal: @@ -1927,7 +2002,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/httpie/archive/master.tar.gz +$ http --download https://github.com/httpie/cli/archive/master.tar.gz ``` ```http @@ -1956,7 +2031,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/httpie/archive/master.tar.gz | tar zxf - +$ http -d https://github.com/httpie/cli/archive/master.tar.gz | tar zxf - ``` ### Resuming downloads @@ -2101,38 +2176,88 @@ $ http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:orig- $ http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:new-value ``` -### Cookie Storage Behavior +### Host-based cookie policy + +Cookies persisted in sessions files have a `domain` field. This _binds_ them to a specified hostname. For example: + +```json +{ + "cookies": [ + { + "domain": "pie.dev", + "name": "pie", + "value": "apple" + }, + { + "domain": "httpbin.org", + "name": "bin", + "value": "http" + } + ] +} +``` + +Using this session file, we include `Cookie: pie=apple` only in requests against `pie.dev` and subdomains (e.g., `foo.pie.dev` or `foo.bar.pie.dev`): + +```bash +$ http --session=./session.json pie.dev/cookies +``` + +```json +{ + "cookies": { + "pie": "apple" + } +} +``` + +To make a cookie domain _unbound_ (i.e., to make it available to all hosts, including throughout a cross-domain redirect chain), you can set the `domain` field to `null` in the session file: + +```json +{ + "cookies": [ + { + "domain": null, + "name": "unbound-cookie", + "value": "send-me-to-any-host" + } + ] +} +``` + +```bash +$ http --session=./session.json pie.dev/cookies +``` + +```json +{ + "cookies": { + "unbound-cookie": "send-me-to-any-host" + } +} +``` + -**TL;DR:** Cookie storage priority: Server response > Command line request > Session file +### Cookie storage behavior -To set a cookie within a Session there are three options: +There are three possible sources of persisted cookies within a session. They have the following storage priority: 1—response; 2—command line; 3—session file. -1. Get a `Set-Cookie` header in a response from a server +1. Receive a response with a `Set-Cookie` header: - ```bash - $ http --session=./session.json pie.dev/cookie/set?foo=bar - ``` + ```bash + $ http --session=./session.json pie.dev/cookie/set?foo=bar + ``` -2. Set the cookie name and value through the command line as seen in [cookies](#cookies) +2. Send a cookie specified on the command line as seen in [cookies](#cookies): - ```bash - $ http --session=./session.json pie.dev/headers Cookie:foo=bar - ``` + ```bash + $ http --session=./session.json pie.dev/headers Cookie:foo=bar + ``` -3. Manually set cookie parameters in the JSON file of the session +3. Manually set cookie parameters in the session file: - ```json - { - "__meta__": { - "about": "HTTPie session file", - "help": "https://httpie.org/doc#sessions", - "httpie": "2.2.0-dev" - }, - "auth": { - "password": null, - "type": null, - "username": null - }, + ```json + { "cookies": { "foo": { "expires": null, @@ -2141,16 +2266,55 @@ To set a cookie within a Session there are three options: "value": "bar" } } - } - ``` + } + ``` + +In summary: + +- Cookies set via the CLI overwrite cookies of the same name inside session files. +- Server-sent `Set-Cookie` header cookies overwrite any pre-existing ones with the same name. + +Cookie expiration handling: + +- When the server expires an existing cookie, HTTPie removes it from the session file. +- When a cookie in a session file expires, HTTPie removes it before sending a new request. + +### Upgrading sessions + +HTTPie may introduce changes in the session file format. When HTTPie detects an obsolete format, it shows a warning. You can upgrade your session files using the following commands: + +Upgrade all existing [named sessions](#named-sessions) inside the `sessions` subfolder of your [config directory](https://httpie.io/docs/cli/config-file-directory): + +```bash +$ httpie cli sessions upgrade-all +Upgraded 'api_auth' @ 'pie.dev' to v3.1.0 +Upgraded 'login_cookies' @ 'httpie.io' to v3.1.0 +``` + +Upgrading individual sessions requires you to specify the session's hostname. That allows HTTPie to find the correct file in the case of name sessions. Additionally, it allows it to correctly bind cookies when upgrading with [`--bind-cookies`](#session-upgrade-options). + +Upgrade a single [named session](#named-sessions): + +```bash +$ httpie cli sessions upgrade pie.dev api_auth +Upgraded 'api_auth' @ 'pie.dev' to v3.1.0 +``` + +Upgrade a single [anonymous session](#anonymous-sessions) using a file path: + +```bash +$ httpie cli sessions upgrade pie.dev ./session.json +Upgraded 'session.json' @ 'pie.dev' to v3.1.0 +``` + +#### Session upgrade options -Cookies will be set in the session file with the priority specified above. -For example, a cookie set through the command line will overwrite a cookie of the same name stored in the session file. -If the server returns a `Set-Cookie` header with a cookie of the same name, the returned cookie will overwrite the preexisting cookie. +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 session’s host ([context](https://github.com/httpie/cli/security/advisories/GHSA-9w4w-cpc8-h2fq)). | -Expired cookies are never stored. -If a cookie in a session file expires, it will be removed before sending a new request. -If the server expires an existing cookie, it will also be removed from the session file. ## Config @@ -2163,7 +2327,7 @@ To see the exact location for your installation, run `http --debug` and look for The default location of the configuration file on most platforms is `$XDG_CONFIG_HOME/httpie/config.json` (defaulting to `~/.config/httpie/config.json`). -For backwards compatibility, if the directory `~/.httpie` exists, the configuration file there will be used instead. +For backward compatibility, if the directory `~/.httpie` exists, the configuration file there will be used instead. On Windows, the config file is located at `%APPDATA%\httpie\config.json`. @@ -2202,7 +2366,7 @@ However, it is not recommended modifying the default behavior in a way that woul #### `plugins_dir` The directory where the plugins will be installed. HTTPie needs to have read/write access on that directory, since -`httpie plugins install` will download new plugins to there. See [plugin manager](#plugin-manager) for more information. +`httpie cli plugins install` will download new plugins to there. See [plugin manager](#plugin-manager) for more information. ### Un-setting previously specified options @@ -2236,16 +2400,13 @@ 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 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 there’s neither data nor `EOF`, it will get stuck. So unless you’re piping some data to HTTPie, the `--ignore-stdin` flag should be used in scripts. +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. -Also, it might be good to set a connection `--timeout` limit to prevent your program from hanging if the server never responds. +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. ## Plugin manager -HTTPie offers extensibility through a [plugin API](https://github.com/httpie/httpie/blob/master/httpie/plugins/base.py), +HTTPie offers extensibility through a [plugin API](https://github.com/httpie/cli/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)), @@ -2259,7 +2420,36 @@ For managing these plugins; starting with 3.0, we are offering a new plugin mana This command is currently in beta. -### `httpie plugins` +### `httpie cli` + +#### `httpie cli check-updates` + +You can check whether a new update is available for your system by running `httpie cli check-updates`: + +```bash-termible +$ httpie cli check-updates +``` + +#### `httpie cli export-args` + +`httpie cli export-args` command can expose the parser specification of `http`/`https` commands +(like an API definition) to outside tools so that they can use this to build better interactions +over them (e.g., offer auto-complete). + +Available formats to export in include: + +| Format | Description | +|--------|---------------------------------------------------------------------------------------------------------------------------------------------------| +| `json` | Export the parser spec in JSON. The schema includes a top-level `version` parameter which should be interpreted in [semver](https://semver.org/). | + +You can use any of these formats with `--format` parameter, but the default one is `json`. + +```bash +$ httpie cli export-args | jq '"Program: " + .spec.name + ", Version: " + .version' +"Program: http, Version: 0.0.1a0" +``` + +#### `httpie cli plugins` `plugins` interface is a very simple plugin manager for installing, listing and uninstalling HTTPie plugins. @@ -2270,13 +2460,13 @@ plugin installations on every installation method. By default, the plugins (and their missing dependencies) will be stored under the configuration directory, but this can be modified through `plugins_dir` variable on the config. -#### `httpie plugins install` +##### `httpie cli plugins install` -For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie plugins install` +For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie cli plugins install` can be used. ```bash -$ httpie plugins install httpie-plugin +$ httpie cli plugins install httpie-plugin Installing httpie-plugin... Successfully installed httpie-plugin-1.0.2 ``` @@ -2284,12 +2474,12 @@ Successfully installed httpie-plugin-1.0.2 > Tip: Generally HTTPie plugins start with `httpie-` prefix. Try searching for it on [PyPI](https://pypi.org/search/?q=httpie-) > to find out all plugins from the community. -#### `httpie plugins list` +##### `httpie cli plugins list` List all installed plugins. ```bash -$ httpie plugins list +$ httpie cli plugins list httpie_plugin (1.0.2) httpie_plugin (httpie.plugins.auth.v1) httpie_plugin_2 (1.0.6) @@ -2299,21 +2489,21 @@ httpie_converter (1.0.0) httpie_konsole_konverter (httpie.plugins.converter.v1) ``` -#### `httpie plugins upgrade` +##### `httpie cli plugins upgrade` For upgrading already installed plugins, use `httpie plugins upgrade`. ```bash -$ httpie plugins upgrade httpie-plugin +$ httpie cli plugins upgrade httpie-plugin ``` -#### `httpie plugins uninstall` +##### `httpie cli plugins uninstall` Uninstall plugins from the isolated plugins directory. If the plugin is not installed -through `httpie plugins install`, it won’t uninstall it. +through `httpie cli plugins install`, it won’t uninstall it. ```bash -$ httpie plugins uninstall httpie-plugin +$ httpie cli plugins uninstall httpie-plugin ``` ## Meta @@ -2356,7 +2546,7 @@ All changes are recorded in the [change log](#change-log). HTTPie has the following community channels: -- [GitHub Issues](https://github.com/httpie/httpie/issues) for bug reports and feature requests +- [GitHub Issues](https://github.com/httpie/cli/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) @@ -2366,7 +2556,7 @@ HTTPie has the following community channels: Under the hood, HTTPie uses these two amazing libraries: -- [Requests](https://python-requests.org) — Python HTTP library for humans +- [Requests](https://requests.readthedocs.io/en/latest/) — Python HTTP library for humans - [Pygments](https://pygments.org/) — Python syntax highlighter #### HTTPie friends @@ -2378,7 +2568,7 @@ HTTPie plays exceptionally well with the following tools: Helpers to convert from other client tools: -- [CurliPie](https://curlipie.now.sh/) help convert cURL command line to HTTPie command line +- [CurliPie](https://curlipie.open-api.vn) — library to convert cURL commands to HTTPie #### Alternatives @@ -2387,20 +2577,25 @@ Helpers to convert from other client tools: ### Contributing -See [CONTRIBUTING](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md). +See [CONTRIBUTING](https://github.com/httpie/cli/blob/master/CONTRIBUTING.md). + +### Security policy + +See [github.com/httpie/cli/security/policy](https://github.com/httpie/cli/security/policy). ### Change log -See [CHANGELOG](https://github.com/httpie/httpie/blob/master/CHANGELOG.md). +See [CHANGELOG](https://github.com/httpie/cli/blob/master/CHANGELOG.md). ### Artwork -- [README Animation](https://github.com/httpie/httpie/blob/master/docs/httpie-animation.gif) by [Allen Smith](https://github.com/loranallensmith). +- [README Animation](https://github.com/httpie/cli/blob/master/docs/httpie-animation.gif) by [Allen Smith](https://github.com/loranallensmith). ### Licence -BSD-3-Clause: [LICENSE](https://github.com/httpie/httpie/blob/master/LICENSE). +BSD-3-Clause: [LICENSE](https://github.com/httpie/cli/blob/master/LICENSE). ### Authors -[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. +[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. + diff --git a/docs/contributors/README.md b/docs/contributors/README.md index 20b3c278fb..9a739cd543 100644 --- a/docs/contributors/README.md +++ b/docs/contributors/README.md @@ -1,3 +1,3 @@ -Here we maintain a database of contributors, from which we generate credits on release blog posts and social medias. +Here we maintain a database of contributors, from which we generate credits on release blog posts and social media. For the HTTPie blog see: . diff --git a/docs/contributors/fetch.py b/docs/contributors/fetch.py index 7924f46443..ba94c28183 100644 --- a/docs/contributors/fetch.py +++ b/docs/contributors/fetch.py @@ -252,6 +252,7 @@ def fetch_missing_users_details(people: People) -> None: def save_awesome_people(people: People) -> None: with DB_FILE.open(mode='w', encoding='utf-8') as fh: json.dump(people, fh, indent=4, sort_keys=True) + fh.write("\n") def debug(*args: Any) -> None: diff --git a/docs/contributors/generate.py b/docs/contributors/generate.py index d3d6fdd95c..27470d5672 100644 --- a/docs/contributors/generate.py +++ b/docs/contributors/generate.py @@ -8,19 +8,27 @@ from fetch import HERE, load_awesome_people TPL_FILE = HERE / 'snippet.jinja2' + HTTPIE_TEAM = { 'claudiatd', 'jakubroztocil', 'jkbr', + 'isidentical' +} + +BOT_ACCOUNTS = { + 'dependabot-sr' } +IGNORE_ACCOUNTS = HTTPIE_TEAM | BOT_ACCOUNTS + def generate_snippets(release: str) -> str: people = load_awesome_people() contributors = { name: details for name, details in people.items() - if details['github'] not in HTTPIE_TEAM + if details['github'] not in IGNORE_ACCOUNTS and (release in details['committed'] or release in details['reported']) } diff --git a/docs/contributors/people.json b/docs/contributors/people.json index 041e67f2f7..70514fcc2d 100644 --- a/docs/contributors/people.json +++ b/docs/contributors/people.json @@ -53,11 +53,13 @@ }, "Batuhan Taskaya": { "committed": [ - "3.0.0" + "3.0.0", + "3.2.0" ], "github": "isidentical", "reported": [ - "3.0.0" + "3.0.0", + "3.2.0" ], "twitter": "isidentical" }, @@ -118,6 +120,14 @@ "reported": [], "twitter": "elena_lape" }, + "Ethan Mills": { + "committed": [ + "3.2.0" + ], + "github": "ethanmills", + "reported": [], + "twitter": null + }, "Fabio Peruzzo": { "committed": [], "github": "peruzzof", @@ -189,7 +199,8 @@ "committed": [ "2.5.0", "2.6.0", - "3.0.0" + "3.0.0", + "3.2.0" ], "github": "jakubroztocil", "reported": [ @@ -213,7 +224,8 @@ ], "github": "blyxxyz", "reported": [ - "3.0.0" + "3.0.0", + "3.2.0" ], "twitter": null }, @@ -309,7 +321,8 @@ "committed": [], "github": "ducaale", "reported": [ - "2.5.0" + "2.5.0", + "3.2.0" ], "twitter": null }, @@ -321,6 +334,22 @@ ], "twitter": "sevenc_nanashi" }, + "Nicklas Ansman Giertz": { + "committed": [], + "github": "ansman", + "reported": [ + "3.2.0" + ], + "twitter": null + }, + "Oliver Fish": { + "committed": [], + "github": "Oliver-Fish", + "reported": [ + "3.2.0" + ], + "twitter": null + }, "Omer Akram": { "committed": [ "2.6.0", @@ -357,6 +386,14 @@ ], "twitter": null }, + "Roberto L\u00f3pez L\u00f3pez": { + "committed": [], + "github": "robertolopezlopez", + "reported": [ + "3.2.0" + ], + "twitter": null + }, "Russell Shurts": { "committed": [], "github": "rshurts", @@ -487,6 +524,14 @@ ], "twitter": null }, + "dependabot[bot]": { + "committed": [ + "3.2.0" + ], + "github": "dependabot-sr", + "reported": [], + "twitter": null + }, "dkreeft": { "committed": [ "2.6.0", @@ -553,6 +598,14 @@ ], "twitter": null }, + "luzpaz": { + "committed": [ + "3.2.0" + ], + "github": "luzpaz", + "reported": [], + "twitter": null + }, "nixbytes": { "committed": [ "2.5.0" @@ -593,6 +646,14 @@ ], "twitter": null }, + "zhaohanqing95": { + "committed": [], + "github": "zhaohanqing95", + "reported": [ + "3.2.0" + ], + "twitter": null + }, "zoulja": { "committed": [], "github": "zoulja", @@ -627,4 +688,4 @@ ], "twitter": null } -} \ No newline at end of file +} diff --git a/docs/contributors/snippet.jinja2 b/docs/contributors/snippet.jinja2 index 4fa21b12ef..56e7d33fc1 100644 --- a/docs/contributors/snippet.jinja2 +++ b/docs/contributors/snippet.jinja2 @@ -2,9 +2,10 @@ ## Community contributions -We’d like to thank these amazing people for their contributions to this release: {% for name, details in contributors.items() -%} - [{{ name }}](https://github.com/{{ details.github }}){{ '' if loop.last else ', ' }} -{%- endfor %}. +We’d like to thank these amazing people for their contributions to this release: +{% for name, details in contributors.items() -%} +- [{{ name }}](https://github.com/{{ details.github }}){{ '' if loop.last else '\n' }} +{%- endfor %} diff --git a/docs/installation/generate.py b/docs/installation/generate.py index a67389ddd5..0597a3a429 100644 --- a/docs/installation/generate.py +++ b/docs/installation/generate.py @@ -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 alpha-numeric for generated links to work' + assert platform.isalnum(), f'{platform=} must be alphanumeric for generated links to work' platform_tools = [tools[tool_id] for tool_id in tools_ids] structure.append((platform, platform_tools)) return structure diff --git a/docs/installation/methods.yml b/docs/installation/methods.yml index 1583b2364a..290b0e2436 100644 --- a/docs/installation/methods.yml +++ b/docs/installation/methods.yml @@ -17,11 +17,12 @@ docs-structure: Windows: - chocolatey Linux: - - snap-linux - - brew-linux - apt - dnf - yum + - single-binary + - snap-linux + - brew-linux - pacman FreeBSD: - pkg @@ -36,11 +37,13 @@ tools: package: https://packages.debian.org/sid/web/httpie commands: install: - - apt update - - apt install httpie + - 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 + - echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" | sudo tee /etc/apt/sources.list.d/httpie.list > /dev/null + - sudo apt update + - sudo apt install httpie upgrade: - - apt update - - apt upgrade httpie + - sudo apt update && sudo apt upgrade httpie brew-mac: title: Homebrew @@ -106,9 +109,9 @@ tools: package: https://archlinux.org/packages/community/any/httpie/ commands: install: - - pacman -Sy httpie - upgrade: - pacman -Syu httpie + upgrade: + - pacman -Syu pkg: title: FreshPorts @@ -179,3 +182,16 @@ tools: - yum install httpie upgrade: - yum upgrade httpie + + single-binary: + title: Single binary executables + name: Single binary executables + note: Get the standalone HTTPie Linux executables when you don't want to go through the full installation process. + links: + commands: + install: + - https --download packages.httpie.io/binaries/linux/http-latest -o http + - ln -ls ./http ./https + - chmod +x ./http ./https + upgrade: + - https --download packages.httpie.io/binaries/linux/http-latest -o http diff --git a/docs/markdownlint.rb b/docs/markdownlint.rb index 0bf3f87b2b..cf2878c7b0 100644 --- a/docs/markdownlint.rb +++ b/docs/markdownlint.rb @@ -11,6 +11,9 @@ # Because we use HTML to hide them on the website. exclude_rule 'MD002' +# MD007 Allow unordered list indentation +exclude_rule 'MD007' + # MD013 Line length exclude_rule 'MD013' diff --git a/docs/packaging/README.md b/docs/packaging/README.md index c8d18b2832..e455742cc5 100644 --- a/docs/packaging/README.md +++ b/docs/packaging/README.md @@ -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/httpie/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/cli/issues/). - If you are looking for technical information about the HTTPie packaging, then you are at the good place. ## About @@ -12,18 +12,20 @@ You are looking at the HTTPie packaging documentation, where you will find valua The overall release process starts simple: -1. Do the [PyPI](https://pypi.org/project/httpie/) publication. -2. Then, handle company-related tasks. -3. Finally, follow OS-specific steps, described in documents below, to send patches downstream. +1. Bump the version identifiers in the following places: + - `httpie/__init__.py` + - `docs/packaging/windows-chocolatey/httpie.nuspec` + - `CHANGELOG.md` +2. Commit your changes and make a PR against the `master`. +3. Merge the PR, and tag the last commit with your version identifier. +4. Make a GitHub release (by copying the text in `CHANGELOG.md`) +5. Push that release to PyPI (dispatch the `Release PyPI` GitHub action). +6. Once PyPI is ready, push the release to the Snap, Homebrew and Chocolatey with their respective actions. +7. Go to the [`httpie/debian.httpie.io`](https://github.com/httpie/debian.httpie.io) repo and trigger the package index workflow. -## First, PyPI +## Company-specific tasks -Let's do the release on [PyPi](https://pypi.org/project/httpie/). -That is done quite easily by manually triggering the [release workflow](https://github.com/httpie/httpie/actions/workflows/release.yml). - -## Then, company-specific tasks - -- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/httpie/blob/master/docs/config.json). +- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/cli/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)). @@ -36,11 +38,10 @@ A more complete state of deployment can be found on [repology](https://repology. | -------------------------------------------: | -------------- | | [Arch Linux, and derived](linux-arch/) | trusted person | | [CentOS, RHEL, and derived](linux-centos/) | trusted person | -| [Debian, Ubuntu, and derived](linux-debian/) | trusted person | | [Fedora](linux-fedora/) | trusted person | -| :construction: [Homebrew, Linuxbrew](brew/) | **HTTPie** | -| :construction: [MacPorts](mac-ports/) | **HTTPie** | +| [Debian, Ubuntu, and derived](linux-debian/) | **HTTPie** | +| [Homebrew, Linuxbrew](brew/) | **HTTPie** | | [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/httpie/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/cli/issues/). diff --git a/docs/packaging/brew/README.md b/docs/packaging/brew/README.md index 2acb3299fb..a06324ecd3 100644 --- a/docs/packaging/brew/README.md +++ b/docs/packaging/brew/README.md @@ -13,21 +13,19 @@ We will discuss setting up the environment, installing development tools, instal ## Overall process -:construction: Work in progress. +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 +from the release manager. -First, update the current Formula: +If it is needed to be done manually, the following command can be used: -```bash -make brew-deps -# Copy-paste content into downstream/mac/brew/httpie.rb -git add downstream/mac/brew/httpie.rb -git commit -s -m 'Update brew formula to XXX' +```console +$ brew bump-formula-pr httpie --version={TARGET_VERSION} ``` -That [GitHub workflow](https://github.com/httpie/httpie/actions/workflows/test-package-mac-brew.yml) will test the formula when `downstream/mac/brew/httpie.rb` is changed in a pull request. - -Then, open a pull request with those changes to the [downstream file](https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpie.rb). +which will bump the formula, and create a PR against the package index. ## Hacking -:construction: Work in progress. +Make your changes, test the formula through the [`Test Brew Package`](https://github.com/httpie/cli/actions/workflows/test-package-mac-brew.yml) action +and then finally submit your patch to [`homebrew-core`](https://github.com/Homebrew/homebrew-core`) + diff --git a/docs/packaging/brew/brew-deps.py b/docs/packaging/brew/brew-deps.py deleted file mode 100755 index 3e45683942..0000000000 --- a/docs/packaging/brew/brew-deps.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -""" -Generate Ruby code with URLs and file hashes for packages from PyPi -(i.e., httpie itself as well as its dependencies) to be included -in the Homebrew formula after a new release of HTTPie has been published -on PyPi. - - - -""" -import hashlib -import requests - - -VERSIONS = { - # By default, we use the latest packages. But sometimes Requests has a maximum supported versions. - # Take a look here before making a release: - 'idna': '3.2', -} - - -# Note: Keep that list sorted. -PACKAGES = [ - 'certifi', - 'charset-normalizer', - 'defusedxml', - 'httpie', - 'idna', - 'Pygments', - 'PySocks', - 'requests', - 'requests-toolbelt', - 'urllib3', - 'multidict', -] - - -def get_package_meta(package_name): - api_url = f'https://pypi.org/pypi/{package_name}/json' - resp = requests.get(api_url).json() - hasher = hashlib.sha256() - version = VERSIONS.get(package_name) - if package_name not in VERSIONS: - # Latest version - release_bundle = resp['urls'] - else: - release_bundle = resp['releases'][version] - - for release in release_bundle: - download_url = release['url'] - if download_url.endswith('.tar.gz'): - hasher.update(requests.get(download_url).content) - return { - 'name': package_name, - 'url': download_url, - 'sha256': hasher.hexdigest(), - } - else: - raise RuntimeError(f'{package_name}: download not found: {resp}') - - -def main(): - package_meta_map = { - package_name: get_package_meta(package_name) - for package_name in PACKAGES - } - httpie_meta = package_meta_map.pop('httpie') - print() - print(' url "{url}"'.format(url=httpie_meta['url'])) - print(' sha256 "{sha256}"'.format(sha256=httpie_meta['sha256'])) - print() - for dep_meta in package_meta_map.values(): - print(' resource "{name}" do'.format(name=dep_meta['name'])) - print(' url "{url}"'.format(url=dep_meta['url'])) - print(' sha256 "{sha256}"'.format(sha256=dep_meta['sha256'])) - print(' end') - print('') - - -if __name__ == '__main__': - main() diff --git a/docs/packaging/brew/httpie.rb b/docs/packaging/brew/httpie.rb index ed09cb5309..e249a5aa10 100644 --- a/docs/packaging/brew/httpie.rb +++ b/docs/packaging/brew/httpie.rb @@ -3,18 +3,18 @@ class Httpie < Formula desc "User-friendly cURL replacement (command-line HTTP client)" homepage "https://httpie.io/" - url "https://files.pythonhosted.org/packages/7b/f9/13070f19226b7db3641fb787df36bb715063abe1b8ca03fbaeca0f465d27/httpie-3.0.1.tar.gz" - sha256 "0e9bc93ebdcdd2d32ec24b8fa46cf7e4fde9eec7a6bd0c5d0ef224f25d7466b2" + 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/httpie.git", branch: "master" + head "https://github.com/httpie/cli.git", branch: "master" bottle do - sha256 cellar: :any_skip_relocation, arm64_monterey: "9d285fcfb55ce8ed787d1b01966d51e6e07f7e77c44a204695a2d6eee9c8698d" - sha256 cellar: :any_skip_relocation, arm64_big_sur: "743a282b475e87a4eaf11e545f761aef1b8e4bfe49eaee47251d7629a35a8ced" - sha256 cellar: :any_skip_relocation, monterey: "5d63ea4f47b2028b2ba68abe12a4176934193e058edd869270221b41cc946c76" - sha256 cellar: :any_skip_relocation, big_sur: "5a53221a680a35d1aa00cbadde279dbe4f562d22ed207c15bd4221cb8c3180f1" - sha256 cellar: :any_skip_relocation, catalina: "5feadb6d76f55d6f9681682e221008c282dccf0e46ae22a959b4bad2efde204a" - sha256 cellar: :any_skip_relocation, x86_64_linux: "d530ddbec49588b0d481f156d35f7e5bb7d3b6427d203f04750e55cd3eecc303" + sha256 cellar: :any_skip_relocation, arm64_monterey: "9bb6e8c1ef5ba8b019ddedd7e908dd2174da695351aa9a238dfb28b0f57ef005" + sha256 cellar: :any_skip_relocation, arm64_big_sur: "47ffccd3241155d863e1b4f6259d538a34d42a0cdeed8152bda257ee607b51be" + sha256 cellar: :any_skip_relocation, monterey: "dc4a04cb05a9cd1bfa6a632a0e4a21975905954af54ece41f9050c52474267be" + sha256 cellar: :any_skip_relocation, big_sur: "ae469e37864e967e0fd99fba15a78e719dcb351b462f98f3843c78ed1473df6d" + sha256 cellar: :any_skip_relocation, catalina: "291a3eaecb2a2cc845c1652686a9a14b21053d7e3a7d0115245b2150ca2e199e" + sha256 cellar: :any_skip_relocation, x86_64_linux: "710836e27c44c8e3ad181d668f4a9f78c4cb4c355d7b148a397599a7cd42713d" end depends_on "python@3.10" @@ -25,8 +25,8 @@ class Httpie < Formula end resource "charset-normalizer" do - url "https://files.pythonhosted.org/packages/48/44/76b179e0d1afe6e6a91fd5661c284f60238987f3b42b676d141d01cd5b97/charset-normalizer-2.0.10.tar.gz" - sha256 "876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd" + url "https://files.pythonhosted.org/packages/56/31/7bcaf657fafb3c6db8c787a865434290b726653c912085fbd371e9b92e1c/charset-normalizer-2.0.12.tar.gz" + sha256 "2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597" end resource "defusedxml" do @@ -40,8 +40,8 @@ class Httpie < Formula end resource "multidict" do - url "https://files.pythonhosted.org/packages/8e/7c/e12a69795b7b7d5071614af2c691c97fbf16a2a513c66ec52dd7d0a115bb/multidict-5.2.0.tar.gz" - sha256 "0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce" + url "https://files.pythonhosted.org/packages/fa/a7/71c253cdb8a1528802bac7503bf82fe674367e4055b09c28846fdfa4ab90/multidict-6.0.2.tar.gz" + sha256 "5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013" end resource "Pygments" do diff --git a/docs/packaging/brew/update.sh b/docs/packaging/brew/update.sh new file mode 100755 index 0000000000..7c26ae0ba4 --- /dev/null +++ b/docs/packaging/brew/update.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -xe + +rm -f httpie.rb +http --download https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Formula/httpie.rb diff --git a/docs/packaging/linux-arch/PKGBUILD b/docs/packaging/linux-arch/PKGBUILD index d483fd67b2..5ecec154e8 100644 --- a/docs/packaging/linux-arch/PKGBUILD +++ b/docs/packaging/linux-arch/PKGBUILD @@ -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/httpie" +url="https://github.com/httpie/cli" 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/httpie/archive/$pkgver.tar.gz") +source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/cli/archive/$pkgver.tar.gz") sha256sums=('3bcd9a8cb2b11299da12d3af36c095c6d4b665e41c395898a07f1ae4d99fc14a') build() { diff --git a/docs/packaging/linux-debian/README.md b/docs/packaging/linux-debian/README.md index f43ff3c40e..4ec0c0e24e 100644 --- a/docs/packaging/linux-debian/README.md +++ b/docs/packaging/linux-debian/README.md @@ -11,19 +11,16 @@ Welcome to the documentation about **packaging HTTPie for Debian GNU/Linux**. This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Debian GNU/Linux. They apply to Ubuntu as well, and any Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc. We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream. -The current maintainer is Bartosz Fenski. +We create the standalone binaries (see this [for more details](../../../extras/packaging/linux/)) and package them with +[FPM](https://github.com/jordansissel/fpm)'s `dir` mode. The core `http`/`https` commands don't have any dependencies, but the `httpie` +command (due to the underlying `httpie cli plugins` interface) explicitly depends to the system Python (through `python3`/`python3-pip`). ## Overall process -Open a new bug on the Debian Bug Tracking System by sending an email: +The [`Release as Standalone Linux Binary`](https://github.com/httpie/cli/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. -- To: `Debian Bug Tracking System ` -- Subject: `httpie: Version XXX available` -- Message template (examples [1](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993937), and [2](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996479)): - - ```email - Package: httpie - Severity: normal - - - ``` +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 +and trigger the [`Update Index`](https://github.com/httpie/debian.httpie.io/actions/workflows/update-index.yml) action. It will automatically +scrape all new debian packages from the release assets, properly update the indexes and create a new PR ([an example](https://github.com/httpie/debian.httpie.io/pull/1)) +which then will become active when merged. diff --git a/docs/packaging/linux-fedora/README.md b/docs/packaging/linux-fedora/README.md index b21e003d25..e8bcf99039 100644 --- a/docs/packaging/linux-fedora/README.md +++ b/docs/packaging/linux-fedora/README.md @@ -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/httpie/blob/master/.packit.yaml) local file. +We added the [.packit.yaml](https://github.com/httpie/cli/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. diff --git a/docs/packaging/linux-fedora/httpie.spec.txt b/docs/packaging/linux-fedora/httpie.spec.txt index b0ab5b7b3a..3414b188c1 100644 --- a/docs/packaging/linux-fedora/httpie.spec.txt +++ b/docs/packaging/linux-fedora/httpie.spec.txt @@ -1,11 +1,11 @@ Name: httpie -Version: 2.6.0 +Version: 3.1.0 Release: 1%{?dist} Summary: A Curl-like tool for humans License: BSD URL: https://httpie.org/ -Source0: https://github.com/httpie/httpie/archive/%{version}/%{name}-%{version}.tar.gz +Source0: https://github.com/httpie/cli/archive/%{version}/%{name}-%{version}.tar.gz BuildArch: noarch @@ -78,6 +78,25 @@ help2man %{buildroot}%{_bindir}/httpie > %{buildroot}%{_mandir}/man1/httpie.1 %changelog +* Tue Mar 08 2022 Miro Hrončok - 3.1.0-1 +- Update to 3.1.0 +- Fixes: rhbz#2061597 + +* Mon Jan 24 2022 Miro Hrončok - 3.0.2-1 +- Update to 3.0.2 +- Fixes: rhbz#2044572 + +* Mon Jan 24 2022 Miro Hrončok - 3.0.1-1 +- Update to 3.0.1 +- Fixes: rhbz#2044058 + +* Fri Jan 21 2022 Miro Hrončok - 3.0.0-1 +- Update to 3.0.0 +- Fixes: rhbz#2043680 + +* Thu Jan 20 2022 Fedora Release Engineering - 2.6.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Fri Oct 15 2021 Miro Hrončok - 2.6.0-1 - Update to 2.6.0 - Fixes: rhbz#2014022 diff --git a/docs/packaging/linux-fedora/update.sh b/docs/packaging/linux-fedora/update.sh new file mode 100755 index 0000000000..773bef336c --- /dev/null +++ b/docs/packaging/linux-fedora/update.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -xe + +rm -f httpie.spec.txt +https --download src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -o httpie.spec.txt diff --git a/docs/packaging/mac-ports/README.md b/docs/packaging/mac-ports/README.md index 2d8170afa4..792638789f 100644 --- a/docs/packaging/mac-ports/README.md +++ b/docs/packaging/mac-ports/README.md @@ -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/httpie/tarball/2.5.0 + $ wget https://api.github.com/repos/httpie/cli/tarball/2.5.0 # Size $ stat --printf="%s\n" 2.5.0 diff --git a/docs/packaging/snapcraft/README.md b/docs/packaging/snapcraft/README.md index b22a00ef80..e7c37c4782 100644 --- a/docs/packaging/snapcraft/README.md +++ b/docs/packaging/snapcraft/README.md @@ -13,7 +13,16 @@ We will discuss setting up the environment, installing development tools, instal ## Overall process -Trigger a new [build](https://snapcraft.io/httpie/builds), then [promote it](https://snapcraft.io/httpie/releases). If more management is needed: [revisions supervision](https://dashboard.snapcraft.io/snaps/httpie/revisions/). +Trigger the [`Release on Snap`](https://github.com/httpie/cli/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 +- Beta +- Candidate +- Stable + +If a push to any of them fail, all the release tasks for the following channels will be cancelled so that the +release manager can look into the underlying cause. ## Hacking @@ -28,7 +37,7 @@ From inside the container: ```bash # Clone -git clone --depth=1 https://github.com/httpie/httpie.git +git clone --depth=1 https://github.com/httpie/cli.git cd httpie # Build diff --git a/docs/packaging/windows-chocolatey/README.md b/docs/packaging/windows-chocolatey/README.md index 588fd7e7d7..33c5d35f11 100644 --- a/docs/packaging/windows-chocolatey/README.md +++ b/docs/packaging/windows-chocolatey/README.md @@ -13,18 +13,23 @@ We will discuss setting up the environment, installing development tools, instal ## Overall process -After having successfully [built and tested](#hacking) the package, push it: +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 +to push it to the `Chocolatey` store or use the CLI: ```bash # Replace 2.5.0 with the correct version choco push httpie.2.5.0.nupkg -s https://push.chocolatey.org/ --api-key=API_KEY ``` +Be aware that it might take multiple days until the release is approved, sine it goes through multiple +sets of reviews (some of them are done manually). + ## Hacking ```bash # Clone -git clone --depth=1 https://github.com/httpie/httpie.git +git clone --depth=1 https://github.com/httpie/cli.git cd httpie/docs/packaging/windows-chocolatey # Build diff --git a/docs/packaging/windows-chocolatey/httpie.nuspec b/docs/packaging/windows-chocolatey/httpie.nuspec index ce69afa5a7..1d8c69790a 100644 --- a/docs/packaging/windows-chocolatey/httpie.nuspec +++ b/docs/packaging/windows-chocolatey/httpie.nuspec @@ -2,7 +2,7 @@ httpie - 2.6.0 + 3.2.2 Modern, user-friendly command-line HTTP client for the API era HTTPie *aitch-tee-tee-pie* is a user-friendly command-line HTTP client for the API era. @@ -29,17 +29,17 @@ Main features: HTTPie HTTPie jakubroztocil - 2012-2021 Jakub Roztocil - https://raw.githubusercontent.com/httpie/httpie/master/LICENSE + 2012-2022 Jakub Roztocil + https://raw.githubusercontent.com/httpie/cli/master/LICENSE https://pie-assets.s3.eu-central-1.amazonaws.com/LogoIcons/GB.png false - See the [changelog](https://github.com/httpie/httpie/blob/2.6.0/CHANGELOG.md). + See the [changelog](https://github.com/httpie/cli/releases/tag/3.2.2). httpie http https rest api client curl python ssl cli foss oss url https://httpie.io - https://github.com/httpie/httpie/tree/master/docs/packaging/windows-chocolatey - https://github.com/httpie/httpie + https://github.com/httpie/cli/tree/master/docs/packaging/windows-chocolatey + https://github.com/httpie/cli https://httpie.io/docs - https://github.com/httpie/httpie/issues + https://github.com/httpie/cli/issues diff --git a/docs/stardust.png b/docs/stardust.png new file mode 100644 index 0000000000..f95821a425 Binary files /dev/null and b/docs/stardust.png differ diff --git a/extras/httpie-completion.fish b/extras/httpie-completion.fish index 5bb32c7605..c0cfc20ad9 100644 --- a/extras/httpie-completion.fish +++ b/extras/httpie-completion.fish @@ -1,52 +1,24 @@ function __fish_httpie_styles - echo " -abap -algol -algol_nu -arduino -auto -autumn -borland -bw -colorful -default -emacs -friendly -fruity -gruvbox-dark -gruvbox-light -igor -inkpot -lovelace -manni -material -monokai -murphy -native -paraiso-dark -paraiso-light -pastie -perldoc -rainbow_dash -rrt -sas -solarized -solarized-dark -solarized-light -stata -stata-dark -stata-light -tango -trac -vim -vs -xcode -zenburn" + printf '%s\n' abap algol algol_nu arduino auto autumn borland bw colorful default emacs friendly fruity gruvbox-dark gruvbox-light igor inkpot lovelace manni material monokai murphy native paraiso-dark paraiso-light pastie perldoc pie pie-dark pie-light rainbow_dash rrt sas solarized solarized-dark solarized-light stata stata-dark stata-light tango trac vim vs xcode zenburn +end + +function __fish_httpie_mime_types + test -r /usr/share/mime/types && cat /usr/share/mime/types +end + +function __fish_httpie_print_args + set -l arg (commandline -t) + string match -qe H "$arg" || echo -e $arg"H\trequest headers" + string match -qe B "$arg" || echo -e $arg"B\trequest body" + string match -qe h "$arg" || echo -e $arg"h\tresponse headers" + string match -qe b "$arg" || echo -e $arg"b\tresponse body" + string match -qe m "$arg" || echo -e $arg"m\tresponse metadata" end function __fish_httpie_auth_types echo -e "basic\tBasic HTTP auth" echo -e "digest\tDigest HTTP auth" + echo -e "bearer\tBearer HTTP Auth" end function __fish_http_verify_options @@ -54,6 +26,7 @@ function __fish_http_verify_options echo -e "no\tDisable cert verification" end + # Predefined Content Types complete -c http -s j -l json -d 'Data items are serialized as a JSON object' @@ -70,26 +43,28 @@ complete -c http -s x -l compress -d 'Content compressed with Deflate algorithm' # Output Processing -complete -c http -l pretty -xa "all colors format none" -d 'Controls output processing' -complete -c http -s s -l style -xa "(__fish_httpie_styles)" -d 'Output coloring style' -complete -c http -l unsorted -d 'Disables all sorting while formatting output' -complete -c http -l sorted -d 'Re-enables all sorting options while formatting output' -complete -c http -l format-options -x -d 'Controls output formatting' +complete -c http -l pretty -xa "all colors format none" -d 'Controls output processing' +complete -c http -s s -l style -xa "(__fish_httpie_styles)" -d 'Output coloring style' +complete -c http -l unsorted -d 'Disables all sorting while formatting output' +complete -c http -l sorted -d 'Re-enables all sorting options while formatting output' +complete -c http -l response-charset -x -d 'Override the response encoding' +complete -c http -l response-mime -xa "(__fish_httpie_mime_types)" -d 'Override the response mime type for coloring and formatting' +complete -c http -l format-options -x -d 'Controls output formatting' # Output Options -complete -c http -s p -l print -x -d 'String specifying what the output should contain' -complete -c http -s h -l headers -d 'Print only the response headers' -complete -c http -s b -l body -d 'Print only the response body' -complete -c http -s v -l verbose -d 'Print the whole request as well as the response' -complete -c http -l all -d 'Show any intermediary requests/responses' -complete -c http -s P -l history-print -x -d 'The same as --print but applies only to intermediary requests/responses' -complete -c http -s S -l stream -d 'Always stream the response body by line' -complete -c http -s o -l output -F -d 'Save output to FILE' -complete -c http -s d -l download -d 'Download a file' -complete -c http -s c -l continue -d 'Resume an interrupted download' -complete -c http -s q -l quiet -d 'Do not print to stdout or stderr' +complete -c http -s p -l print -xa "(__fish_httpie_print_args)" -d 'String specifying what the output should contain' +complete -c http -s h -l headers -d 'Print only the response headers' +complete -c http -s m -l meta -d 'Print only the response metadata' +complete -c http -s b -l body -d 'Print only the response body' +complete -c http -s v -l verbose -d 'Print the whole request as well as the response' +complete -c http -l all -d 'Show any intermediary requests/responses' +complete -c http -s S -l stream -d 'Always stream the response body by line' +complete -c http -s o -l output -F -d 'Save output to FILE' +complete -c http -s d -l download -d 'Download a file' +complete -c http -s c -l continue -d 'Resume an interrupted download' +complete -c http -s q -l quiet -d 'Do not print to stdout or stderr' # Sessions @@ -115,23 +90,30 @@ complete -c http -l max-headers -x -d 'Maximum number of response headers complete -c http -l timeout -x -d 'Connection timeout in seconds' complete -c http -l check-status -d 'Error with non-200 HTTP status code' complete -c http -l path-as-is -d 'Bypass dot segment URL squashing' -complete -c http -l chunked -d '' +complete -c http -l chunked -d 'Enable streaming via chunked transfer encoding' # SSL -complete -c http -l verify -xa "(__fish_http_verify_options)" -d 'Enable/disable cert verification' -complete -c http -l ssl -x -d 'Desired protocol version to use' -complete -c http -l ciphers -x -d 'String in the OpenSSL cipher list format' -complete -c http -l cert -F -d 'Client side SSL certificate' -complete -c http -l cert-key -F -d 'Private key to use with SSL' +complete -c http -l verify -xa "(__fish_http_verify_options)" -d 'Enable/disable cert verification' +complete -c http -l ssl -x -d 'Desired protocol version to use' +complete -c http -l ciphers -x -d 'String in the OpenSSL cipher list format' +complete -c http -l cert -F -d 'Client side SSL certificate' +complete -c http -l cert-key -F -d 'Private key to use with SSL' +complete -c http -l cert-key-pass -x -d 'Passphrase for the given private key' # Troubleshooting complete -c http -s I -l ignore-stdin -d 'Do not attempt to read stdin' complete -c http -l help -d 'Show help' +complete -c http -l manual -d 'Show the full manual' complete -c http -l version -d 'Show version' complete -c http -l traceback -d 'Prints exception traceback should one occur' complete -c http -l default-scheme -x -d 'The default scheme to use' complete -c http -l debug -d 'Show debugging output' + + +# Alias for https to http + +complete -c https -w http diff --git a/extras/man/http.1 b/extras/man/http.1 new file mode 100644 index 0000000000..889e82b31d --- /dev/null +++ b/extras/man/http.1 @@ -0,0 +1,600 @@ +.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py. +.TH http 1 "2024-11-01" "HTTPie 3.2.4" "HTTPie Manual" +.SH NAME +http +.SH SYNOPSIS +http [METHOD] URL [REQUEST_ITEM ...] + +.SH DESCRIPTION +HTTPie: modern, user-friendly command-line HTTP client for the API era. +.SH Positional arguments + +These arguments come after any flags and in the order they are listed here. +Only URL is required. + +.IP "\fB\,METHOD\/\fR" + + +The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...). + +This argument can be omitted in which case HTTPie will use POST if there +is some data to be sent, otherwise GET: + + $ http example.org # => GET + $ http example.org hello=world # => POST + + + +.IP "\fB\,URL\/\fR" + + +The request URL. Scheme defaults to \[aq]http://\[aq] if the URL +does not include one. (You can override this with: \fB\,--default-scheme\/\fR=http/https) + +You can also use a shorthand for localhost + + $ http :3000 # => http://localhost:3000 + $ http :/foo # => http://localhost/foo + + + +.IP "\fB\,REQUEST_ITEM\/\fR" + + +Optional key-value pairs to be included in the request. The separator used +determines the type: + +\[aq]:\[aq] HTTP headers: + + Referer:https://httpie.io Cookie:foo=bar User-Agent:bacon/1.0 + +\[aq]==\[aq] URL parameters to be appended to the request URI: + + search==httpie + +\[aq]=\[aq] Data fields to be serialized into a JSON object (with \fB\,--json\/\fR, \fB\,-j\/\fR) + or form data (with \fB\,--form\/\fR, \fB\,-f\/\fR): + + name=HTTPie language=Python description=\[aq]CLI HTTP client\[aq] + +\[aq]:=\[aq] Non-string JSON data fields (only with \fB\,--json\/\fR, \fB\,-j\/\fR): + + awesome:=true amount:=42 colors:=\[aq][\[dq]red\[dq], \[dq]green\[dq], \[dq]blue\[dq]]\[aq] + +\[aq]@\[aq] Form file fields (only with \fB\,--form\/\fR or \fB\,--multipart\/\fR): + + cv@\(ti/Documents/CV.pdf + cv@\[aq]\(ti/Documents/CV.pdf;type=application/pdf\[aq] + +\[aq]=@\[aq] A data field like \[aq]=\[aq], but takes a file path and embeds its content: + + essay=@Documents/essay.txt + +\[aq]:=@\[aq] A raw JSON field like \[aq]:=\[aq], but takes a file path and embeds its content: + + package:=@./package.json + +You can use a backslash to escape a colliding separator in the field name: + + field-name-with\e:colon=value + + + +.PP +.SH Predefined content types +.IP "\fB\,--json\/\fR, \fB\,-j\/\fR" + + +(default) Data items from the command line are serialized as a JSON object. +The Content-Type and Accept headers are set to application/json +(if not specified). + + + +.IP "\fB\,--form\/\fR, \fB\,-f\/\fR" + + +Data items from the command line are serialized as form fields. + +The Content-Type is set to application/x-www-form-urlencoded (if not +specified). The presence of any file fields results in a +multipart/form-data request. + + + +.IP "\fB\,--multipart\/\fR" + + +Similar to \fB\,--form\/\fR, but always sends a multipart/form-data request (i.e., even without files). + + +.IP "\fB\,--boundary\/\fR" + + +Specify a custom boundary string for multipart/form-data requests. Only has effect only together with \fB\,--form\/\fR. + + +.IP "\fB\,--raw\/\fR" + + +This option allows you to pass raw request data without extra processing +(as opposed to the structured request items syntax): + + $ http \fB\,--raw\/\fR=\[aq]data\[aq] pie.dev/post + +You can achieve the same by piping the data via stdin: + + $ echo data | http pie.dev/post + +Or have HTTPie load the raw data from a file: + + $ http pie.dev/post @data.txt + + + + +.PP +.SH Content processing options +.IP "\fB\,--compress\/\fR, \fB\,-x\/\fR" + + +Content compressed (encoded) with Deflate algorithm. +The Content-Encoding header is set to deflate. + +Compression is skipped if it appears that compression ratio is +negative. Compression can be forced by repeating the argument. + + + +.PP +.SH Output processing +.IP "\fB\,--pretty\/\fR" + + +Controls output processing. The value can be \[dq]none\[dq] to not prettify +the output (default for redirected output), \[dq]all\[dq] to apply both colors +and formatting (default for terminal output), \[dq]colors\[dq], or \[dq]format\[dq]. + + + +.IP "\fB\,--style\/\fR, \fB\,-s\/\fR \fI\,STYLE\/\fR" + + +Output coloring style (default is \[dq]auto\[dq]). It can be one of: + + auto, pie, pie-dark, pie-light, solarized + + +For finding out all available styles in your system, try: + +$ http \fB\,--style\/\fR + +The \[dq]auto\[dq] style follows your terminal\[aq]s ANSI color styles. +For non-auto styles to work properly, please make sure that the +$TERM environment variable is set to \[dq]xterm-256color\[dq] or similar +(e.g., via `export TERM=xterm-256color\[aq] in your \(ti/.bashrc). + +.IP "\fB\,--unsorted\/\fR" + + +Disables all sorting while formatting output. It is a shortcut for: + + \fB\,--format-options\/\fR=headers.sort:false,json.sort_keys:false + + + +.IP "\fB\,--sorted\/\fR" + + +Re-enables all sorting options while formatting output. It is a shortcut for: + + \fB\,--format-options\/\fR=headers.sort:true,json.sort_keys:true + + + +.IP "\fB\,--response-charset\/\fR \fI\,ENCODING\/\fR" + + +Override the response encoding for terminal display purposes, e.g.: + + \fB\,--response-charset\/\fR=utf8 + \fB\,--response-charset\/\fR=big5 + + + +.IP "\fB\,--response-mime\/\fR \fI\,MIME_TYPE\/\fR" + + +Override the response mime type for coloring and formatting for the terminal, e.g.: + + \fB\,--response-mime\/\fR=application/json + \fB\,--response-mime\/\fR=text/xml + + + +.IP "\fB\,--format-options\/\fR" + + +Controls output formatting. Only relevant when formatting is enabled +through (explicit or implied) \fB\,--pretty\/\fR=all or \fB\,--pretty\/\fR=format. +The following are the default options: + + headers.sort:true + json.format:true + json.indent:4 + json.sort_keys:true + xml.format:true + xml.indent:2 + +You may use this option multiple times, as well as specify multiple +comma-separated options at the same time. For example, this modifies the +settings to disable the sorting of JSON keys, and sets the indent size to 2: + + \fB\,--format-options\/\fR json.sort_keys:false,json.indent:2 + +This is something you will typically put into your config file. + + + +.PP +.SH Output options +.IP "\fB\,--print\/\fR, \fB\,-p\/\fR \fI\,WHAT\/\fR" + + +String specifying what the output should contain: + + \[aq]H\[aq] request headers + \[aq]B\[aq] request body + \[aq]h\[aq] response headers + \[aq]b\[aq] response body + \[aq]m\[aq] response metadata + +The default behaviour is \[aq]hb\[aq] (i.e., the response +headers and body is printed), if standard output is not redirected. +If the output is piped to another program or to a file, then only the +response body is printed by default. + + + +.IP "\fB\,--headers\/\fR, \fB\,-h\/\fR" + + +Print only the response headers. Shortcut for \fB\,--print\/\fR=h. + + + +.IP "\fB\,--meta\/\fR, \fB\,-m\/\fR" + + +Print only the response metadata. Shortcut for \fB\,--print\/\fR=m. + + + +.IP "\fB\,--body\/\fR, \fB\,-b\/\fR" + + +Print only the response body. Shortcut for \fB\,--print\/\fR=b. + + + +.IP "\fB\,--verbose\/\fR, \fB\,-v\/\fR" + + +Verbose output. For the level one (with single `\fB\,-v\/\fR`/`\fB\,--verbose\/\fR`), print +the whole request as well as the response. Also print any intermediary +requests/responses (such as redirects). For the second level and higher, +print these as well as the response metadata. + +Level one is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbh +Level two is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbhm + + +.IP "\fB\,--all\/\fR" + + +By default, only the final request/response is shown. Use this flag to show +any intermediary requests/responses as well. Intermediary requests include +followed redirects (with \fB\,--follow\/\fR), the first unauthorized request when +Digest auth is used (\fB\,--auth\/\fR=digest), etc. + + + +.IP "\fB\,--stream\/\fR, \fB\,-S\/\fR" + + +Always stream the response body by line, i.e., behave like `tail \fB\,-f\/\fR\[aq]. + +Without \fB\,--stream\/\fR and with \fB\,--pretty\/\fR (either set or implied), +HTTPie fetches the whole response before it outputs the processed data. + +Set this option when you want to continuously display a prettified +long-lived response, such as one from the Twitter streaming API. + +It is useful also without \fB\,--pretty\/\fR: It ensures that the output is flushed +more often and in smaller chunks. + + + +.IP "\fB\,--output\/\fR, \fB\,-o\/\fR \fI\,FILE\/\fR" + + +Save output to FILE instead of stdout. If \fB\,--download\/\fR is also set, then only +the response body is saved to FILE. Other parts of the HTTP exchange are +printed to stderr. + + + +.IP "\fB\,--download\/\fR, \fB\,-d\/\fR" + + +Do not print the response body to stdout. Rather, download it and store it +in a file. The filename is guessed unless specified with \fB\,--output\/\fR +[filename]. This action is similar to the default behaviour of wget. + + + +.IP "\fB\,--continue\/\fR, \fB\,-c\/\fR" + + +Resume an interrupted download. Note that the \fB\,--output\/\fR option needs to be +specified as well. + + + +.IP "\fB\,--quiet\/\fR, \fB\,-q\/\fR" + + +Do not print to stdout or stderr, except for errors and warnings when provided once. +Provide twice to suppress warnings as well. +stdout is still redirected if \fB\,--output\/\fR is specified. +Flag doesn\[aq]t affect behaviour of download beyond not printing to terminal. + + + +.PP +.SH Sessions +.IP "\fB\,--session\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR" + + +Create, or reuse and update a session. Within a session, custom headers, +auth credential, as well as any cookies sent by the server persist between +requests. + +Session files are stored in: + + [HTTPIE_CONFIG_DIR]//.json. + +See the following page to find out your default HTTPIE_CONFIG_DIR: + + https://httpie.io/docs/cli/config-file-directory + + +.IP "\fB\,--session-read-only\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR" + + +Create or read a session without updating it form the request/response +exchange. + + + +.PP +.SH Authentication +.IP "\fB\,--auth\/\fR, \fB\,-a\/\fR \fI\,USER[:PASS] | TOKEN\/\fR" + + +For username/password based authentication mechanisms (e.g +basic auth or digest auth) if only the username is provided +(\fB\,-a\/\fR username), HTTPie will prompt for the password. + + + +.IP "\fB\,--auth-type\/\fR, \fB\,-A\/\fR" + + +The authentication mechanism to be used. Defaults to \[dq]basic\[dq]. + +\[dq]basic\[dq]: Basic HTTP auth + +\[dq]digest\[dq]: Digest HTTP auth + +\[dq]bearer\[dq]: Bearer HTTP Auth + +To see all available auth types on your system, including ones installed via plugins, run: + +$ http \fB\,--auth-type\/\fR + +.IP "\fB\,--ignore-netrc\/\fR" + + +Ignore credentials from .netrc. + + +.PP +.SH Network +.IP "\fB\,--offline\/\fR" + + +Build the request and print it but don\(gat actually send it. + + +.IP "\fB\,--proxy\/\fR \fI\,PROTOCOL:PROXY_URL\/\fR" + + +String mapping protocol to the URL of the proxy +(e.g. http:http://foo.bar:3128). You can specify multiple proxies with +different protocols. The environment variables $ALL_PROXY, $HTTP_PROXY, +and $HTTPS_proxy are supported as well. + + + +.IP "\fB\,--follow\/\fR, \fB\,-F\/\fR" + + +Follow 30x Location redirects. + + +.IP "\fB\,--max-redirects\/\fR" + + +By default, requests have a limit of 30 redirects (works with \fB\,--follow\/\fR). + + + +.IP "\fB\,--max-headers\/\fR" + + +The maximum number of response headers to be read before giving up (default 0, i.e., no limit). + + +.IP "\fB\,--timeout\/\fR \fI\,SECONDS\/\fR" + + +The connection timeout of the request in seconds. +The default value is 0, i.e., there is no timeout limit. +This is not a time limit on the entire response download; +rather, an error is reported if the server has not issued a response for +timeout seconds (more precisely, if no bytes have been received on +the underlying socket for timeout seconds). + + + +.IP "\fB\,--check-status\/\fR" + + +By default, HTTPie exits with 0 when no network or other fatal errors +occur. This flag instructs HTTPie to also check the HTTP status code and +exit with an error if the status indicates one. + +When the server replies with a 4xx (Client Error) or 5xx (Server Error) +status code, HTTPie exits with 4 or 5 respectively. If the response is a +3xx (Redirect) and \fB\,--follow\/\fR hasn\[aq]t been set, then the exit status is 3. +Also an error message is written to stderr if stdout is redirected. + + + +.IP "\fB\,--path-as-is\/\fR" + + +Bypass dot segment (/../ or /./) URL squashing. + + +.IP "\fB\,--chunked\/\fR" + + +Enable streaming via chunked transfer encoding. The Transfer-Encoding header is set to chunked. + + +.PP +.SH SSL +.IP "\fB\,--verify\/\fR" + + +Set to \[dq]no\[dq] (or \[dq]false\[dq]) to skip checking the host\[aq]s SSL certificate. +Defaults to \[dq]yes\[dq] (\[dq]true\[dq]). You can also pass the path to a CA_BUNDLE file +for private certs. (Or you can set the REQUESTS_CA_BUNDLE environment +variable instead.) + + +.IP "\fB\,--ssl\/\fR" + + +The desired protocol version to use. This will default to +SSL v2.3 which will negotiate the highest protocol that both +the server and your installation of OpenSSL support. Available protocols +may vary depending on OpenSSL installation (only the supported ones +are shown here). + + + +.IP "\fB\,--ciphers\/\fR" + + + +A string in the OpenSSL cipher list format. + + +See `http \fB\,--help\/\fR` for the default ciphers list on you system. + + + + + +.IP "\fB\,--cert\/\fR" + + +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 +specify \fB\,--cert-key\/\fR separately. + + + +.IP "\fB\,--cert-key\/\fR" + + +The private key to use with SSL. Only needed if \fB\,--cert\/\fR is given and the +certificate file does not contain the private key. + + + +.IP "\fB\,--cert-key-pass\/\fR" + + +The passphrase to be used to with the given private key. Only needed if \fB\,--cert-key\/\fR +is given and the key file requires a passphrase. +If not provided, you\(gall be prompted interactively. + + +.PP +.SH Troubleshooting +.IP "\fB\,--ignore-stdin\/\fR, \fB\,-I\/\fR" + + +Do not attempt to read stdin + + +.IP "\fB\,--help\/\fR" + + +Show this help message and exit. + + +.IP "\fB\,--manual\/\fR" + + +Show the full manual. + + +.IP "\fB\,--version\/\fR" + + +Show version and exit. + + +.IP "\fB\,--traceback\/\fR" + + +Prints the exception traceback should one occur. + + +.IP "\fB\,--default-scheme\/\fR" + + +The default scheme to use if not specified in the URL. + + +.IP "\fB\,--debug\/\fR" + + +Prints the exception traceback should one occur, as well as other +information useful for debugging HTTPie itself and for reporting bugs. + + + +.PP +.SH SEE ALSO + +For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts OPTION +to its default value. + +Suggestions and bug reports are greatly appreciated: +https://github.com/httpie/cli/issues \ No newline at end of file diff --git a/extras/man/httpie.1 b/extras/man/httpie.1 new file mode 100644 index 0000000000..b44172967b --- /dev/null +++ b/extras/man/httpie.1 @@ -0,0 +1,100 @@ +.\" This file is auto-generated from the parser declaration in httpie/manager/cli.py by extras/scripts/generate_man_pages.py. +.TH httpie 1 "2024-11-01" "HTTPie 3.2.4" "HTTPie Manual" +.SH NAME +httpie +.SH SYNOPSIS +httpie +.SH DESCRIPTION + +Managing interface for the HTTPie itself. + +Be aware that you might be looking for http/https commands for sending +HTTP requests. This command is only available for managing the HTTTPie +plugins and the configuration around it. + + +If you are looking for the man pages of http/https commands, try one of the following: + $ man http + $ man https + + +.SH httpie cli export-args +Export available options for the CLI +.IP "\fB\,-f\/\fR, \fB\,--format\/\fR" + +Format to export in. + +.PP +.SH httpie cli check-updates +Check for updates +.PP +.SH httpie cli sessions upgrade +Upgrade the given HTTPie session with the latest layout. A list of changes between different session versions can be found in the official documentation. +.IP "\fB\,HOSTNAME\/\fR" + +The host this session belongs. + +.IP "\fB\,SESSION_NAME_OR_PATH\/\fR" + +The name or the path for the session that will be upgraded. + +.IP "\fB\,--bind-cookies\/\fR" + +Bind domainless cookies to the host that session belongs. + +.PP +.SH httpie cli sessions upgrade-all +Upgrade all named sessions with the latest layout. A list of changes between different session versions can be found in the official documentation. +.IP "\fB\,--bind-cookies\/\fR" + +Bind domainless cookies to the host that session belongs. + +.PP +.SH httpie cli plugins install +Install the given targets from PyPI or from a local paths. +.IP "\fB\,TARGET\/\fR" + +targets to install + +.PP +.SH httpie cli plugins upgrade +Upgrade the given plugins +.IP "\fB\,TARGET\/\fR" + +targets to upgrade + +.PP +.SH httpie cli plugins uninstall +Uninstall the given HTTPie plugins. +.IP "\fB\,TARGET\/\fR" + +targets to install + +.PP +.SH httpie cli plugins list +List all installed HTTPie plugins. +.PP +.SH httpie plugins install +Install the given targets from PyPI or from a local paths. +.IP "\fB\,TARGET\/\fR" + +targets to install + +.PP +.SH httpie plugins upgrade +Upgrade the given plugins +.IP "\fB\,TARGET\/\fR" + +targets to upgrade + +.PP +.SH httpie plugins uninstall +Uninstall the given HTTPie plugins. +.IP "\fB\,TARGET\/\fR" + +targets to install + +.PP +.SH httpie plugins list +List all installed HTTPie plugins. +.PP \ No newline at end of file diff --git a/extras/man/https.1 b/extras/man/https.1 new file mode 100644 index 0000000000..14434b9a71 --- /dev/null +++ b/extras/man/https.1 @@ -0,0 +1,600 @@ +.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py. +.TH https 1 "2024-11-01" "HTTPie 3.2.4" "HTTPie Manual" +.SH NAME +https +.SH SYNOPSIS +https [METHOD] URL [REQUEST_ITEM ...] + +.SH DESCRIPTION +HTTPie: modern, user-friendly command-line HTTP client for the API era. +.SH Positional arguments + +These arguments come after any flags and in the order they are listed here. +Only URL is required. + +.IP "\fB\,METHOD\/\fR" + + +The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...). + +This argument can be omitted in which case HTTPie will use POST if there +is some data to be sent, otherwise GET: + + $ http example.org # => GET + $ http example.org hello=world # => POST + + + +.IP "\fB\,URL\/\fR" + + +The request URL. Scheme defaults to \[aq]http://\[aq] if the URL +does not include one. (You can override this with: \fB\,--default-scheme\/\fR=http/https) + +You can also use a shorthand for localhost + + $ http :3000 # => http://localhost:3000 + $ http :/foo # => http://localhost/foo + + + +.IP "\fB\,REQUEST_ITEM\/\fR" + + +Optional key-value pairs to be included in the request. The separator used +determines the type: + +\[aq]:\[aq] HTTP headers: + + Referer:https://httpie.io Cookie:foo=bar User-Agent:bacon/1.0 + +\[aq]==\[aq] URL parameters to be appended to the request URI: + + search==httpie + +\[aq]=\[aq] Data fields to be serialized into a JSON object (with \fB\,--json\/\fR, \fB\,-j\/\fR) + or form data (with \fB\,--form\/\fR, \fB\,-f\/\fR): + + name=HTTPie language=Python description=\[aq]CLI HTTP client\[aq] + +\[aq]:=\[aq] Non-string JSON data fields (only with \fB\,--json\/\fR, \fB\,-j\/\fR): + + awesome:=true amount:=42 colors:=\[aq][\[dq]red\[dq], \[dq]green\[dq], \[dq]blue\[dq]]\[aq] + +\[aq]@\[aq] Form file fields (only with \fB\,--form\/\fR or \fB\,--multipart\/\fR): + + cv@\(ti/Documents/CV.pdf + cv@\[aq]\(ti/Documents/CV.pdf;type=application/pdf\[aq] + +\[aq]=@\[aq] A data field like \[aq]=\[aq], but takes a file path and embeds its content: + + essay=@Documents/essay.txt + +\[aq]:=@\[aq] A raw JSON field like \[aq]:=\[aq], but takes a file path and embeds its content: + + package:=@./package.json + +You can use a backslash to escape a colliding separator in the field name: + + field-name-with\e:colon=value + + + +.PP +.SH Predefined content types +.IP "\fB\,--json\/\fR, \fB\,-j\/\fR" + + +(default) Data items from the command line are serialized as a JSON object. +The Content-Type and Accept headers are set to application/json +(if not specified). + + + +.IP "\fB\,--form\/\fR, \fB\,-f\/\fR" + + +Data items from the command line are serialized as form fields. + +The Content-Type is set to application/x-www-form-urlencoded (if not +specified). The presence of any file fields results in a +multipart/form-data request. + + + +.IP "\fB\,--multipart\/\fR" + + +Similar to \fB\,--form\/\fR, but always sends a multipart/form-data request (i.e., even without files). + + +.IP "\fB\,--boundary\/\fR" + + +Specify a custom boundary string for multipart/form-data requests. Only has effect only together with \fB\,--form\/\fR. + + +.IP "\fB\,--raw\/\fR" + + +This option allows you to pass raw request data without extra processing +(as opposed to the structured request items syntax): + + $ http \fB\,--raw\/\fR=\[aq]data\[aq] pie.dev/post + +You can achieve the same by piping the data via stdin: + + $ echo data | http pie.dev/post + +Or have HTTPie load the raw data from a file: + + $ http pie.dev/post @data.txt + + + + +.PP +.SH Content processing options +.IP "\fB\,--compress\/\fR, \fB\,-x\/\fR" + + +Content compressed (encoded) with Deflate algorithm. +The Content-Encoding header is set to deflate. + +Compression is skipped if it appears that compression ratio is +negative. Compression can be forced by repeating the argument. + + + +.PP +.SH Output processing +.IP "\fB\,--pretty\/\fR" + + +Controls output processing. The value can be \[dq]none\[dq] to not prettify +the output (default for redirected output), \[dq]all\[dq] to apply both colors +and formatting (default for terminal output), \[dq]colors\[dq], or \[dq]format\[dq]. + + + +.IP "\fB\,--style\/\fR, \fB\,-s\/\fR \fI\,STYLE\/\fR" + + +Output coloring style (default is \[dq]auto\[dq]). It can be one of: + + auto, pie, pie-dark, pie-light, solarized + + +For finding out all available styles in your system, try: + +$ http \fB\,--style\/\fR + +The \[dq]auto\[dq] style follows your terminal\[aq]s ANSI color styles. +For non-auto styles to work properly, please make sure that the +$TERM environment variable is set to \[dq]xterm-256color\[dq] or similar +(e.g., via `export TERM=xterm-256color\[aq] in your \(ti/.bashrc). + +.IP "\fB\,--unsorted\/\fR" + + +Disables all sorting while formatting output. It is a shortcut for: + + \fB\,--format-options\/\fR=headers.sort:false,json.sort_keys:false + + + +.IP "\fB\,--sorted\/\fR" + + +Re-enables all sorting options while formatting output. It is a shortcut for: + + \fB\,--format-options\/\fR=headers.sort:true,json.sort_keys:true + + + +.IP "\fB\,--response-charset\/\fR \fI\,ENCODING\/\fR" + + +Override the response encoding for terminal display purposes, e.g.: + + \fB\,--response-charset\/\fR=utf8 + \fB\,--response-charset\/\fR=big5 + + + +.IP "\fB\,--response-mime\/\fR \fI\,MIME_TYPE\/\fR" + + +Override the response mime type for coloring and formatting for the terminal, e.g.: + + \fB\,--response-mime\/\fR=application/json + \fB\,--response-mime\/\fR=text/xml + + + +.IP "\fB\,--format-options\/\fR" + + +Controls output formatting. Only relevant when formatting is enabled +through (explicit or implied) \fB\,--pretty\/\fR=all or \fB\,--pretty\/\fR=format. +The following are the default options: + + headers.sort:true + json.format:true + json.indent:4 + json.sort_keys:true + xml.format:true + xml.indent:2 + +You may use this option multiple times, as well as specify multiple +comma-separated options at the same time. For example, this modifies the +settings to disable the sorting of JSON keys, and sets the indent size to 2: + + \fB\,--format-options\/\fR json.sort_keys:false,json.indent:2 + +This is something you will typically put into your config file. + + + +.PP +.SH Output options +.IP "\fB\,--print\/\fR, \fB\,-p\/\fR \fI\,WHAT\/\fR" + + +String specifying what the output should contain: + + \[aq]H\[aq] request headers + \[aq]B\[aq] request body + \[aq]h\[aq] response headers + \[aq]b\[aq] response body + \[aq]m\[aq] response metadata + +The default behaviour is \[aq]hb\[aq] (i.e., the response +headers and body is printed), if standard output is not redirected. +If the output is piped to another program or to a file, then only the +response body is printed by default. + + + +.IP "\fB\,--headers\/\fR, \fB\,-h\/\fR" + + +Print only the response headers. Shortcut for \fB\,--print\/\fR=h. + + + +.IP "\fB\,--meta\/\fR, \fB\,-m\/\fR" + + +Print only the response metadata. Shortcut for \fB\,--print\/\fR=m. + + + +.IP "\fB\,--body\/\fR, \fB\,-b\/\fR" + + +Print only the response body. Shortcut for \fB\,--print\/\fR=b. + + + +.IP "\fB\,--verbose\/\fR, \fB\,-v\/\fR" + + +Verbose output. For the level one (with single `\fB\,-v\/\fR`/`\fB\,--verbose\/\fR`), print +the whole request as well as the response. Also print any intermediary +requests/responses (such as redirects). For the second level and higher, +print these as well as the response metadata. + +Level one is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbh +Level two is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbhm + + +.IP "\fB\,--all\/\fR" + + +By default, only the final request/response is shown. Use this flag to show +any intermediary requests/responses as well. Intermediary requests include +followed redirects (with \fB\,--follow\/\fR), the first unauthorized request when +Digest auth is used (\fB\,--auth\/\fR=digest), etc. + + + +.IP "\fB\,--stream\/\fR, \fB\,-S\/\fR" + + +Always stream the response body by line, i.e., behave like `tail \fB\,-f\/\fR\[aq]. + +Without \fB\,--stream\/\fR and with \fB\,--pretty\/\fR (either set or implied), +HTTPie fetches the whole response before it outputs the processed data. + +Set this option when you want to continuously display a prettified +long-lived response, such as one from the Twitter streaming API. + +It is useful also without \fB\,--pretty\/\fR: It ensures that the output is flushed +more often and in smaller chunks. + + + +.IP "\fB\,--output\/\fR, \fB\,-o\/\fR \fI\,FILE\/\fR" + + +Save output to FILE instead of stdout. If \fB\,--download\/\fR is also set, then only +the response body is saved to FILE. Other parts of the HTTP exchange are +printed to stderr. + + + +.IP "\fB\,--download\/\fR, \fB\,-d\/\fR" + + +Do not print the response body to stdout. Rather, download it and store it +in a file. The filename is guessed unless specified with \fB\,--output\/\fR +[filename]. This action is similar to the default behaviour of wget. + + + +.IP "\fB\,--continue\/\fR, \fB\,-c\/\fR" + + +Resume an interrupted download. Note that the \fB\,--output\/\fR option needs to be +specified as well. + + + +.IP "\fB\,--quiet\/\fR, \fB\,-q\/\fR" + + +Do not print to stdout or stderr, except for errors and warnings when provided once. +Provide twice to suppress warnings as well. +stdout is still redirected if \fB\,--output\/\fR is specified. +Flag doesn\[aq]t affect behaviour of download beyond not printing to terminal. + + + +.PP +.SH Sessions +.IP "\fB\,--session\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR" + + +Create, or reuse and update a session. Within a session, custom headers, +auth credential, as well as any cookies sent by the server persist between +requests. + +Session files are stored in: + + [HTTPIE_CONFIG_DIR]//.json. + +See the following page to find out your default HTTPIE_CONFIG_DIR: + + https://httpie.io/docs/cli/config-file-directory + + +.IP "\fB\,--session-read-only\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR" + + +Create or read a session without updating it form the request/response +exchange. + + + +.PP +.SH Authentication +.IP "\fB\,--auth\/\fR, \fB\,-a\/\fR \fI\,USER[:PASS] | TOKEN\/\fR" + + +For username/password based authentication mechanisms (e.g +basic auth or digest auth) if only the username is provided +(\fB\,-a\/\fR username), HTTPie will prompt for the password. + + + +.IP "\fB\,--auth-type\/\fR, \fB\,-A\/\fR" + + +The authentication mechanism to be used. Defaults to \[dq]basic\[dq]. + +\[dq]basic\[dq]: Basic HTTP auth + +\[dq]digest\[dq]: Digest HTTP auth + +\[dq]bearer\[dq]: Bearer HTTP Auth + +To see all available auth types on your system, including ones installed via plugins, run: + +$ http \fB\,--auth-type\/\fR + +.IP "\fB\,--ignore-netrc\/\fR" + + +Ignore credentials from .netrc. + + +.PP +.SH Network +.IP "\fB\,--offline\/\fR" + + +Build the request and print it but don\(gat actually send it. + + +.IP "\fB\,--proxy\/\fR \fI\,PROTOCOL:PROXY_URL\/\fR" + + +String mapping protocol to the URL of the proxy +(e.g. http:http://foo.bar:3128). You can specify multiple proxies with +different protocols. The environment variables $ALL_PROXY, $HTTP_PROXY, +and $HTTPS_proxy are supported as well. + + + +.IP "\fB\,--follow\/\fR, \fB\,-F\/\fR" + + +Follow 30x Location redirects. + + +.IP "\fB\,--max-redirects\/\fR" + + +By default, requests have a limit of 30 redirects (works with \fB\,--follow\/\fR). + + + +.IP "\fB\,--max-headers\/\fR" + + +The maximum number of response headers to be read before giving up (default 0, i.e., no limit). + + +.IP "\fB\,--timeout\/\fR \fI\,SECONDS\/\fR" + + +The connection timeout of the request in seconds. +The default value is 0, i.e., there is no timeout limit. +This is not a time limit on the entire response download; +rather, an error is reported if the server has not issued a response for +timeout seconds (more precisely, if no bytes have been received on +the underlying socket for timeout seconds). + + + +.IP "\fB\,--check-status\/\fR" + + +By default, HTTPie exits with 0 when no network or other fatal errors +occur. This flag instructs HTTPie to also check the HTTP status code and +exit with an error if the status indicates one. + +When the server replies with a 4xx (Client Error) or 5xx (Server Error) +status code, HTTPie exits with 4 or 5 respectively. If the response is a +3xx (Redirect) and \fB\,--follow\/\fR hasn\[aq]t been set, then the exit status is 3. +Also an error message is written to stderr if stdout is redirected. + + + +.IP "\fB\,--path-as-is\/\fR" + + +Bypass dot segment (/../ or /./) URL squashing. + + +.IP "\fB\,--chunked\/\fR" + + +Enable streaming via chunked transfer encoding. The Transfer-Encoding header is set to chunked. + + +.PP +.SH SSL +.IP "\fB\,--verify\/\fR" + + +Set to \[dq]no\[dq] (or \[dq]false\[dq]) to skip checking the host\[aq]s SSL certificate. +Defaults to \[dq]yes\[dq] (\[dq]true\[dq]). You can also pass the path to a CA_BUNDLE file +for private certs. (Or you can set the REQUESTS_CA_BUNDLE environment +variable instead.) + + +.IP "\fB\,--ssl\/\fR" + + +The desired protocol version to use. This will default to +SSL v2.3 which will negotiate the highest protocol that both +the server and your installation of OpenSSL support. Available protocols +may vary depending on OpenSSL installation (only the supported ones +are shown here). + + + +.IP "\fB\,--ciphers\/\fR" + + + +A string in the OpenSSL cipher list format. + + +See `http \fB\,--help\/\fR` for the default ciphers list on you system. + + + + + +.IP "\fB\,--cert\/\fR" + + +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 +specify \fB\,--cert-key\/\fR separately. + + + +.IP "\fB\,--cert-key\/\fR" + + +The private key to use with SSL. Only needed if \fB\,--cert\/\fR is given and the +certificate file does not contain the private key. + + + +.IP "\fB\,--cert-key-pass\/\fR" + + +The passphrase to be used to with the given private key. Only needed if \fB\,--cert-key\/\fR +is given and the key file requires a passphrase. +If not provided, you\(gall be prompted interactively. + + +.PP +.SH Troubleshooting +.IP "\fB\,--ignore-stdin\/\fR, \fB\,-I\/\fR" + + +Do not attempt to read stdin + + +.IP "\fB\,--help\/\fR" + + +Show this help message and exit. + + +.IP "\fB\,--manual\/\fR" + + +Show the full manual. + + +.IP "\fB\,--version\/\fR" + + +Show version and exit. + + +.IP "\fB\,--traceback\/\fR" + + +Prints the exception traceback should one occur. + + +.IP "\fB\,--default-scheme\/\fR" + + +The default scheme to use if not specified in the URL. + + +.IP "\fB\,--debug\/\fR" + + +Prints the exception traceback should one occur, as well as other +information useful for debugging HTTPie itself and for reporting bugs. + + + +.PP +.SH SEE ALSO + +For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts OPTION +to its default value. + +Suggestions and bug reports are greatly appreciated: +https://github.com/httpie/cli/issues \ No newline at end of file diff --git a/extras/packaging/linux/Dockerfile b/extras/packaging/linux/Dockerfile new file mode 100644 index 0000000000..ea441fd613 --- /dev/null +++ b/extras/packaging/linux/Dockerfile @@ -0,0 +1,33 @@ +# Use the oldest (but still supported) Ubuntu as the base for PyInstaller +# packages. This will prevent stuff like glibc from conflicting. +FROM ubuntu:18.04 + +RUN apt-get update +RUN apt-get install -y software-properties-common binutils +RUN apt-get install -y ruby-dev +RUN gem install fpm + +# Use deadsnakes for the latest Pythons (e.g 3.9) +RUN add-apt-repository ppa:deadsnakes/ppa +RUN apt-get update && apt-get install -y python3.9 python3.9-dev python3.9-venv + +# Install rpm as well, since we are going to build fedora dists too +RUN apt-get install -y rpm + +ADD . /app +WORKDIR /app/extras/packaging/linux + +ENV VIRTUAL_ENV=/opt/venv +RUN python3.9 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +# Ensure that pip is renewed, otherwise we would be using distro-provided pip +# which strips vendored packages and doesn't work with PyInstaller. +RUN python -m pip install /app +RUN python -m pip install pyinstaller wheel +RUN python -m pip install --force-reinstall --upgrade pip + +RUN echo 'BUILD_CHANNEL="pypi"' > /app/httpie/internal/__build_channel__.py +RUN python build.py + +ENTRYPOINT ["mv", "/app/extras/packaging/linux/dist/", "/artifacts"] diff --git a/extras/packaging/linux/README.md b/extras/packaging/linux/README.md new file mode 100644 index 0000000000..ab18bfd02f --- /dev/null +++ b/extras/packaging/linux/README.md @@ -0,0 +1,52 @@ +# Standalone Linux Packages + +![packaging.png](https://user-images.githubusercontent.com/47358913/159950478-2d090d1b-69b9-4914-a1b4-d3e3d8e25fe0.png) + +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) +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 +contains 2 major methods: + +- `build_binaries`, for the self-contained executables +- `build_packages`, for the OS-specific packages (which wrap the binaries) + +### `build_binaries` + +We use [PyInstaller](https://pyinstaller.readthedocs.io/en/stable/) for the binaries. Normally pyinstaller offers two different modes: + +- Single directory (harder to distribute, low redundancy. Library files are shared across different executables) +- Single binary (easier to distribute, higher redundancy. Same libraries are statically linked to different executables, so higher total size) + +Since our binary size (in total 20 MiBs) is not that big, we have decided to choose the single binary mode for the sake of easier distribution. + +We also disable `UPX`, which is a runtime decompression method since it adds some startup cost. + +### `build_packages` + +We build our OS-specific packages with [FPM](https://github.com/jordansissel/fpm) which offers a really nice abstraction. We use the `dir` mode, +and package `http`, `https` and `httpie` commands. More can be added to the `files` option. + +Since the `httpie` depends on having a pip executable, we explicitly depend on the system Python even though the core does not use it. + +### Docker Image + +This directory also contains a [docker image](https://github.com/httpie/cli/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. + +It also contains the Python version we package our HTTPie with, so it is the place if you need to change it. + +### `./get_release_artifacts.sh` + +If you make a change in the `build.py`, run the following script to test it out. It will return multiple files under `artifacts/dist` which +then you can test out and ensure their quality (it is also the script that we use in our automation). diff --git a/extras/packaging/linux/build.py b/extras/packaging/linux/build.py new file mode 100644 index 0000000000..9f02136923 --- /dev/null +++ b/extras/packaging/linux/build.py @@ -0,0 +1,109 @@ +import stat +import subprocess +from pathlib import Path +from typing import Iterator, Tuple + +BUILD_DIR = Path(__file__).parent +HTTPIE_DIR = BUILD_DIR.parent.parent.parent + +EXTRAS_DIR = HTTPIE_DIR / 'extras' +MAN_PAGES_DIR = EXTRAS_DIR / 'man' + +SCRIPT_DIR = BUILD_DIR / Path('scripts') +HOOKS_DIR = SCRIPT_DIR / 'hooks' + +DIST_DIR = BUILD_DIR / 'dist' + +TARGET_SCRIPTS = { + SCRIPT_DIR / 'http_cli.py': [], + SCRIPT_DIR / 'httpie_cli.py': ['--hidden-import=pip'], +} + + +def build_binaries() -> Iterator[Tuple[str, Path]]: + for target_script, extra_args in TARGET_SCRIPTS.items(): + subprocess.check_call( + [ + 'pyinstaller', + '--onefile', + '--noupx', + '-p', + HTTPIE_DIR, + '--additional-hooks-dir', + HOOKS_DIR, + *extra_args, + target_script, + ] + ) + + for executable_path in DIST_DIR.iterdir(): + if executable_path.suffix: + continue + stat_r = executable_path.stat() + executable_path.chmod(stat_r.st_mode | stat.S_IEXEC) + yield executable_path.stem, executable_path + + +def build_packages(http_binary: Path, httpie_binary: Path) -> None: + import httpie + + # Mapping of src_file -> dst_file + files = [ + (http_binary, '/usr/bin/http'), + (http_binary, '/usr/bin/https'), + (httpie_binary, '/usr/bin/httpie'), + ] + files.extend( + (man_page, f'/usr/share/man/man1/{man_page.name}') + for man_page in MAN_PAGES_DIR.glob('*.1') + ) + + # A list of additional dependencies + deps = [ + 'python3 >= 3.7', + 'python3-pip' + ] + + processed_deps = [ + f'--depends={dep}' + for dep in deps + ] + processed_files = [ + '='.join([str(src.resolve()), dst]) for src, dst in files + ] + for target in ['deb', 'rpm']: + subprocess.check_call( + [ + 'fpm', + '--force', + '-s', + 'dir', + '-t', + target, + '--name', + 'httpie', + '--version', + httpie.__version__, + '--description', + httpie.__doc__.strip(), + '--license', + httpie.__licence__, + *processed_deps, + *processed_files, + ], + cwd=DIST_DIR, + ) + + +def main(): + binaries = dict(build_binaries()) + build_packages(binaries['http_cli'], binaries['httpie_cli']) + + # Rename http_cli/httpie_cli to http/httpie + binaries['http_cli'].rename(DIST_DIR / 'http') + binaries['httpie_cli'].rename(DIST_DIR / 'httpie') + + + +if __name__ == '__main__': + main() diff --git a/extras/packaging/linux/get_release_artifacts.sh b/extras/packaging/linux/get_release_artifacts.sh new file mode 100755 index 0000000000..b56e8b83d8 --- /dev/null +++ b/extras/packaging/linux/get_release_artifacts.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -xe + +REPO_ROOT=../../../ +ARTIFACTS_DIR=$(pwd)/artifacts + +# Reset the ARTIFACTS_DIR. +rm -rf $ARTIFACTS_DIR +mkdir -p $ARTIFACTS_DIR + +# Operate on the repository root to have the proper +# docker context. +pushd $REPO_ROOT + +# Build the PyInstaller image +docker build -t pyinstaller-httpie -f extras/packaging/linux/Dockerfile . + +# Copy the artifacts to the designated directory. +docker run --rm -i -v $ARTIFACTS_DIR:/artifacts pyinstaller-httpie:latest + +popd diff --git a/extras/packaging/linux/scripts/hooks/hook-pip.py b/extras/packaging/linux/scripts/hooks/hook-pip.py new file mode 100644 index 0000000000..1dac8fb17f --- /dev/null +++ b/extras/packaging/linux/scripts/hooks/hook-pip.py @@ -0,0 +1,14 @@ +from pathlib import Path +from PyInstaller.utils.hooks import collect_all + +def hook(hook_api): + for pkg in [ + 'pip', + 'setuptools', + 'distutils', + 'pkg_resources' + ]: + datas, binaries, hiddenimports = collect_all(pkg) + hook_api.add_datas(datas) + hook_api.add_binaries(binaries) + hook_api.add_imports(*hiddenimports) diff --git a/extras/packaging/linux/scripts/http_cli.py b/extras/packaging/linux/scripts/http_cli.py new file mode 100644 index 0000000000..12ac773fef --- /dev/null +++ b/extras/packaging/linux/scripts/http_cli.py @@ -0,0 +1,5 @@ +from httpie.__main__ import main + +if __name__ == '__main__': + import sys + sys.exit(main()) diff --git a/extras/packaging/linux/scripts/httpie_cli.py b/extras/packaging/linux/scripts/httpie_cli.py new file mode 100644 index 0000000000..1e979c9521 --- /dev/null +++ b/extras/packaging/linux/scripts/httpie_cli.py @@ -0,0 +1,5 @@ +from httpie.manager.__main__ import main + +if __name__ == '__main__': + import sys + sys.exit(main()) diff --git a/extras/profiling/README.md b/extras/profiling/README.md index c2487de4a6..aff4c68614 100644 --- a/extras/profiling/README.md +++ b/extras/profiling/README.md @@ -1,7 +1,7 @@ # HTTPie Benchmarking Infrastructure This directory includes the benchmarks we use for testing HTTPie's speed and the -infrastructure to automate this testing accross versions. +infrastructure to automate this testing across versions. ## Usage @@ -10,7 +10,7 @@ Ensure the following requirements are satisfied: - Python 3.7+ - `pyperf` -Then, run the `extras/benchmarks/run.py`: +Then, run the `extras/profiling/run.py`: ```console $ python extras/profiling/run.py @@ -28,12 +28,12 @@ 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/httpie` +`--fresh` option. This way, the benchmark runner will clone the `httpie/cli` repo from `GitHub` and use it as the baseline. You can customize these branches by passing `--local-repo`/`--target-branch`, and customize the repos by passing `--local-repo`/`--target-repo` (can either take a URL or a path). -If you want to run a third enviroment with additional dependencies (such as +If you want to run a third environment with additional dependencies (such as `pyOpenSSL`), you can pass `--complex`. diff --git a/extras/profiling/benchmarks.py b/extras/profiling/benchmarks.py index 5d47a3a125..9d409debbe 100644 --- a/extras/profiling/benchmarks.py +++ b/extras/profiling/benchmarks.py @@ -9,11 +9,11 @@ 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 acurrate results. +please run `pyperf system tune` to get even more accurate results. Examples: - # Run everything as usual, the default is that we do 3 warmup runs + # Run everything as usual, the default is that we do 3 warm-up runs # and 5 actual runs. $ python extras/profiling/benchmarks.py @@ -21,7 +21,7 @@ $ python extras/profiling/benchmarks.py --fast # For verify everything works as expected, pass --debug-single-value. - # It will only run everything once, so the resuls are not realiable. But + # It will only run everything once, so the resuls are not reliable. But # very useful when iterating on a benchmark $ python extras/profiling/benchmarks.py --debug-single-value @@ -188,7 +188,7 @@ def run(self, context: Context) -> pyperf.Benchmark: 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 warmup (e.g especially for download benchmark, this + # benchmarks 3 times to warm up (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'] diff --git a/extras/profiling/run.py b/extras/profiling/run.py index 8691367316..040e4389e7 100644 --- a/extras/profiling/run.py +++ b/extras/profiling/run.py @@ -19,19 +19,19 @@ Examples: # Run everything as usual, and compare last commit with master - $ python extras/benchmarks/run.py + $ python extras/profiling/run.py # Include complex environments - $ python extras/benchmarks/run.py --complex + $ python extras/profiling/run.py --complex # Compare against a fresh copy - $ python extras/benchmarks/run.py --fresh + $ python extras/profiling/run.py --fresh # Compare against a custom branch of a custom repo - $ python extras/benchmarks/run.py --target-repo my_repo --target-branch my_branch + $ python extras/profiling/run.py --target-repo my_repo --target-branch my_branch # Debug changes made on this script (only run benchmarks once) - $ python extras/benchmarks/run.py --debug + $ python extras/profiling/run.py --debug """ import dataclasses @@ -50,7 +50,7 @@ BENCHMARK_SCRIPT = Path(__file__).parent / 'benchmarks.py' CURRENT_REPO = Path(__file__).parent.parent.parent -GITHUB_URL = 'https://github.com/httpie/httpie.git' +GITHUB_URL = 'https://github.com/httpie/cli.git' TARGET_BRANCH = 'master' # Additional dependencies for --complex diff --git a/extras/scripts/generate_man_pages.py b/extras/scripts/generate_man_pages.py new file mode 100644 index 0000000000..87939bd5b3 --- /dev/null +++ b/extras/scripts/generate_man_pages.py @@ -0,0 +1,188 @@ +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.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 + + +assert IS_MAN_PAGE, 'CLI definition does not understand we’re building man pages' + +# Escape certain characters, so they are rendered properly on all terminals. +# +ESCAPE_MAP = { + '"': '\[dq]', + "'": '\[aq]', + '~': '\(ti', + '’': "\(ga", + '\\': '\e', +} +ESCAPE_MAP = {ord(key): value for key, value in ESCAPE_MAP.items()} + +EXTRAS_DIR = Path(__file__).parent.parent +MAN_PAGE_PATH = EXTRAS_DIR / 'man' +PROJECT_ROOT = EXTRAS_DIR.parent + +OPTION_HIGHLIGHT_RE = re.compile( + OptionsHighlighter.highlights[0] +) + + +class ManPageBuilder: + def __init__(self): + self.source = [] + + def title_line( + self, + full_name: str, + program_name: str, + program_version: str, + last_edit_date: str, + ) -> None: + self.source.append( + f'.TH {program_name} 1 "{last_edit_date}" ' + f'"{full_name} {program_version}" "{full_name} Manual"' + ) + + def set_name(self, program_name: str) -> None: + with self.section('NAME'): + self.write(program_name) + + def write(self, text: str, *, bold: bool = False) -> None: + if bold: + text = '.B ' + text + self.source.append(text) + + def separate(self) -> None: + self.source.append('.PP') + + def format_desc(self, desc: str) -> str: + description = _escape_and_dedent(desc) + description = OPTION_HIGHLIGHT_RE.sub( + # Boldify the option part, but don't remove the prefix (start of the match). + lambda match: match[1] + self.boldify(match['option']), + description + ) + return description + + def add_comment(self, comment: str) -> None: + self.source.append(f'.\\" {comment}') + + def add_options(self, options: Iterable[str], *, metavar: Optional[str] = None) -> None: + text = ", ".join(map(self.boldify, options)) + if metavar: + text += f' {self.underline(metavar)}' + self.write(f'.IP "{text}"') + + def build(self) -> str: + return '\n'.join(self.source) + + @contextmanager + def section(self, section_name: str) -> Iterator[None]: + self.write(f'.SH {section_name}') + self.in_section = True + yield + self.in_section = False + + def underline(self, text: str) -> str: + return r'\fI\,{}\/\fR'.format(text) + + def boldify(self, text: str) -> str: + return r'\fB\,{}\/\fR'.format(text) + + +def _escape_and_dedent(text: str) -> str: + lines = [] + for should_act, line in enumerate(text.splitlines()): + # Only dedent after the first line. + if should_act: + if line.startswith(' '): + line = line[4:] + + lines.append(line) + return '\n'.join(lines).translate(ESCAPE_MAP) + + +def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool = False) -> str: + builder = ManPageBuilder() + builder.add_comment( + f"This file is auto-generated from the parser declaration " + + (f"in {Path(spec.source_file).relative_to(PROJECT_ROOT)} " if spec.source_file else "") + + f"by {Path(__file__).relative_to(PROJECT_ROOT)}." + ) + + builder.title_line( + full_name='HTTPie', + program_name=program_name, + program_version=httpie.__version__, + last_edit_date=httpie.__date__, + ) + builder.set_name(program_name) + + 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, + # so for the synopsis we'll only reference the `httpie` name. + if is_top_level_cmd: + synopsis = program_name + else: + synopsis = render_as_string(to_usage(spec, program_name=program_name)) + builder.write(synopsis) + + with builder.section('DESCRIPTION'): + builder.write(spec.description) + if spec.man_page_hint: + builder.write(spec.man_page_hint) + + for index, group in enumerate(spec.groups, 1): + with builder.section(group.name): + if group.description: + builder.write(group.description) + + for argument in group.arguments: + if argument.is_hidden: + continue + + raw_arg = argument.serialize(isolation_mode=True) + + metavar = raw_arg.get('metavar') + 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 + builder.add_options(raw_arg['options'], metavar=metavar) + + desc = builder.format_desc(raw_arg.get('description', '')) + builder.write('\n' + desc + '\n') + + builder.separate() + + if spec.epilog: + with builder.section('SEE ALSO'): + builder.write(builder.format_desc(spec.epilog)) + + return builder.build() + + +def main() -> None: + for program_name, spec, config in [ + ('http', core_options, {}), + ('https', core_options, {}), + ('httpie', manager_options, {'is_top_level_cmd': True}), + ]: + with open((MAN_PAGE_PATH / program_name).with_suffix('.1'), 'w') as stream: + stream.write(to_man_page(program_name, spec, **config)) + + +if __name__ == '__main__': + main() diff --git a/httpie/__init__.py b/httpie/__init__.py index 7d48b3499c..a4dded9ced 100644 --- a/httpie/__init__.py +++ b/httpie/__init__.py @@ -3,6 +3,7 @@ """ -__version__ = '3.0.2' +__version__ = '3.2.4' +__date__ = '2024-11-01' __author__ = 'Jakub Roztocil' __licence__ = 'BSD' diff --git a/httpie/cli/argparser.py b/httpie/cli/argparser.py index 64481096c7..9bf09b3b73 100644 --- a/httpie/cli/argparser.py +++ b/httpie/cli/argparser.py @@ -10,7 +10,8 @@ from requests.utils import get_netrc_auth from .argtypes import ( - AuthCredentials, KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS, + AuthCredentials, SSLCredentials, KeyValueArgType, + PARSED_DEFAULT_FORMAT_OPTIONS, parse_auth, parse_format_options, ) @@ -47,12 +48,39 @@ def _split_lines(self, text, width): text = dedent(text).strip() + '\n\n' return text.splitlines() + def add_usage(self, usage, actions, groups, prefix=None): + # Only display the positional arguments + displayed_actions = [ + action + for action in actions + if not action.option_strings + ] + + _, exception, _ = sys.exc_info() + if ( + isinstance(exception, argparse.ArgumentError) + and len(exception.args) >= 1 + and isinstance(exception.args[0], argparse.Action) + ): + # add_usage path is also taken when you pass an invalid option, + # e.g --style=invalid. If something like that happens, we want + # to include to action that caused to the invalid usage into + # the list of actions we are displaying. + displayed_actions.insert(0, exception.args[0]) + + super().add_usage( + usage, + displayed_actions, + groups, + prefix="usage:\n " + ) + # TODO: refactor and design type-annotated data structures # for raw args + parsed args and keep things immutable. class BaseHTTPieArgumentParser(argparse.ArgumentParser): - def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs): - super().__init__(*args, formatter_class=formatter_class, **kwargs) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) self.env = None self.args = None self.has_stdin_data = False @@ -115,9 +143,9 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser): """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs): kwargs.setdefault('add_help', False) - super().__init__(*args, **kwargs) + super().__init__(*args, formatter_class=formatter_class, **kwargs) # noinspection PyMethodOverriding def parse_args( @@ -127,6 +155,7 @@ def parse_args( namespace=None ) -> argparse.Namespace: self.env = env + self.env.args = namespace = namespace or argparse.Namespace() self.args, no_options = super().parse_known_args(args, namespace) if self.args.debug: self.args.traceback = True @@ -148,6 +177,7 @@ def parse_args( self._parse_items() self._process_url() self._process_auth() + self._process_ssl_cert() if self.args.raw is not None: self._body_from_input(self.args.raw) @@ -230,9 +260,24 @@ def _setup_standard_streams(self): self.env.stdout_isatty = False if self.args.quiet: + self.env.quiet = self.args.quiet self.env.stderr = self.env.devnull if not (self.args.output_file_specified and not self.args.download): self.env.stdout = self.env.devnull + self.env.apply_warnings_filter() + + def _process_ssl_cert(self): + from httpie.ssl_ import _is_key_file_encrypted + + if self.args.cert_key_pass is None: + self.args.cert_key_pass = SSLCredentials(None) + + if ( + self.args.cert_key is not None + and self.args.cert_key_pass.value is None + and _is_key_file_encrypted(self.args.cert_key) + ): + self.args.cert_key_pass.prompt_password(self.args.cert_key) def _process_auth(self): # TODO: refactor & simplify this method. @@ -512,3 +557,57 @@ def _process_format_options(self): for options_group in format_options: parsed_options = parse_format_options(options_group, defaults=parsed_options) self.args.format_options = parsed_options + + def print_manual(self): + from httpie.output.ui import man_pages + + if man_pages.is_available(self.env.program_name): + man_pages.display_for(self.env, self.env.program_name) + return None + + text = self.format_help() + with self.env.rich_console.pager(): + self.env.rich_console.print( + text, + highlight=False + ) + + def print_usage(self, file): + from rich.text import Text + from httpie.output.ui import rich_help + + whitelist = set() + _, exception, _ = sys.exc_info() + if ( + isinstance(exception, argparse.ArgumentError) + and len(exception.args) >= 1 + and isinstance(exception.args[0], argparse.Action) + and exception.args[0].option_strings + ): + # add_usage path is also taken when you pass an invalid option, + # e.g --style=invalid. If something like that happens, we want + # to include to action that caused to the invalid usage into + # the list of actions we are displaying. + whitelist.add(exception.args[0].option_strings[0]) + + usage_text = Text('usage', style='bold') + usage_text.append(':\n ') + usage_text.append(rich_help.to_usage(self.spec, whitelist=whitelist)) + self.env.rich_error_console.print(usage_text) + + def error(self, message): + """Prints a usage message incorporating the message to stderr and + exits.""" + self.print_usage(sys.stderr) + self.env.rich_error_console.print( + dedent( + f''' + [bold]error[/bold]: + {message} + + [bold]for more information[/bold]: + run '{self.prog} --help' or visit https://httpie.io/docs/cli + '''.rstrip() + ) + ) + self.exit(2) diff --git a/httpie/cli/argtypes.py b/httpie/cli/argtypes.py index 7bc487ea81..8f19c3c51e 100644 --- a/httpie/cli/argtypes.py +++ b/httpie/cli/argtypes.py @@ -130,16 +130,11 @@ def tokenize(self, s: str) -> List[Union[str, Escaped]]: return tokens -class AuthCredentials(KeyValueArg): - """Represents parsed credentials.""" - - def has_password(self) -> bool: - return self.value is not None - - def prompt_password(self, host: str): - prompt_text = f'http: password for {self.key}@{host}: ' +class PromptMixin: + def _prompt_password(self, prompt: str) -> str: + prompt_text = f'http: {prompt}: ' try: - self.value = self._getpass(prompt_text) + return self._getpass(prompt_text) except (EOFError, KeyboardInterrupt): sys.stderr.write('\n') sys.exit(0) @@ -150,6 +145,26 @@ def _getpass(prompt): return getpass.getpass(str(prompt)) +class SSLCredentials(PromptMixin): + """Represents the passphrase for the certificate's key.""" + + def __init__(self, value: Optional[str]) -> None: + self.value = value + + def prompt_password(self, key_file: str) -> None: + self.value = self._prompt_password(f'passphrase for {key_file}') + + +class AuthCredentials(KeyValueArg, PromptMixin): + """Represents parsed credentials.""" + + def has_password(self) -> bool: + return self.value is not None + + def prompt_password(self, host: str) -> None: + self.value = self._prompt_password(f'password for {self.key}@{host}:') + + class AuthCredentialsArgType(KeyValueArgType): """A key-value arg type that parses credentials.""" diff --git a/httpie/cli/constants.py b/httpie/cli/constants.py index 897e806b4d..09ca19e4af 100644 --- a/httpie/cli/constants.py +++ b/httpie/cli/constants.py @@ -9,6 +9,7 @@ HTTP_POST = 'POST' HTTP_GET = 'GET' +HTTP_OPTIONS = 'OPTIONS' # Various separators used in args SEPARATOR_HEADER = ':' @@ -90,13 +91,19 @@ }) # Pretty + + +class PrettyOptions(enum.Enum): + STDOUT_TTY_ONLY = enum.auto() + + PRETTY_MAP = { 'all': ['format', 'colors'], 'colors': ['colors'], 'format': ['format'], 'none': [] } -PRETTY_STDOUT_TTY_ONLY = object() +PRETTY_STDOUT_TTY_ONLY = PrettyOptions.STDOUT_TTY_ONLY DEFAULT_FORMAT_OPTIONS = [ @@ -125,9 +132,3 @@ class RequestType(enum.Enum): FORM = enum.auto() MULTIPART = enum.auto() JSON = enum.auto() - - -OPEN_BRACKET = '[' -CLOSE_BRACKET = ']' -BACKSLASH = '\\' -HIGHLIGHTER = '^' diff --git a/httpie/cli/definition.py b/httpie/cli/definition.py index 5ccc3a16f9..843b29c9cf 100644 --- a/httpie/cli/definition.py +++ b/httpie/cli/definition.py @@ -1,67 +1,66 @@ -""" -CLI arguments definition. - -""" -from argparse import (FileType, OPTIONAL, SUPPRESS, ZERO_OR_MORE) -from textwrap import dedent, wrap - -from .. import __doc__, __version__ -from .argparser import HTTPieArgumentParser -from .argtypes import ( - KeyValueArgType, SessionNameValidator, - readable_file_arg, response_charset_type, response_mime_type, -) -from .constants import ( - DEFAULT_FORMAT_OPTIONS, BASE_OUTPUT_OPTIONS, OUTPUT_OPTIONS, - OUTPUT_OPTIONS_DEFAULT, OUT_REQ_BODY, OUT_REQ_HEAD, - OUT_RESP_BODY, OUT_RESP_HEAD, OUT_RESP_META, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY, - RequestType, SEPARATOR_GROUP_ALL_ITEMS, SEPARATOR_PROXY, - SORTED_FORMAT_OPTIONS_STRING, - UNSORTED_FORMAT_OPTIONS_STRING, -) -from .utils import LazyChoices -from ..output.formatters.colors import ( - AUTO_STYLE, DEFAULT_STYLE, get_available_styles -) -from ..plugins.builtin import BuiltinAuthPlugin -from ..plugins.registry import plugin_manager -from ..sessions import DEFAULT_SESSIONS_DIR -from ..ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS - - -parser = HTTPieArgumentParser( - prog='http', +from __future__ import annotations + +import os +import textwrap +from argparse import FileType + +from httpie import __doc__, __version__ +from httpie.cli.argtypes import (KeyValueArgType, SessionNameValidator, + SSLCredentials, readable_file_arg, + response_charset_type, response_mime_type) +from httpie.cli.constants import (BASE_OUTPUT_OPTIONS, DEFAULT_FORMAT_OPTIONS, + OUT_REQ_BODY, OUT_REQ_HEAD, OUT_RESP_BODY, + OUT_RESP_HEAD, OUT_RESP_META, OUTPUT_OPTIONS, + OUTPUT_OPTIONS_DEFAULT, PRETTY_MAP, + PRETTY_STDOUT_TTY_ONLY, + SEPARATOR_GROUP_ALL_ITEMS, SEPARATOR_PROXY, + SORTED_FORMAT_OPTIONS_STRING, + UNSORTED_FORMAT_OPTIONS_STRING, RequestType) +from httpie.cli.options import ParserSpec, Qualifiers, to_argparse +from httpie.output.formatters.colors import (AUTO_STYLE, DEFAULT_STYLE, BUNDLED_STYLES, + 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')) + + +options = ParserSpec( + 'http', description=f'{__doc__.strip()} ', - epilog=dedent(''' + epilog=""" For every --OPTION there is also a --no-OPTION that reverts OPTION to its default value. Suggestions and bug reports are greatly appreciated: - - https://github.com/httpie/httpie/issues - - '''), + https://github.com/httpie/cli/issues + """, + source_file=__file__ ) -parser.register('action', 'lazy_choices', LazyChoices) ####################################################################### # Positional arguments. ####################################################################### -positional = parser.add_argument_group( - title='Positional Arguments', - description=dedent(''' +positional_arguments = options.add_group( + 'Positional arguments', + description=""" These arguments come after any flags and in the order they are listed here. Only URL is required. - - ''') + """, ) -positional.add_argument( + +positional_arguments.add_argument( dest='method', metavar='METHOD', - nargs=OPTIONAL, + nargs=Qualifiers.OPTIONAL, default=None, - help=''' + short_help='The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...).', + help=""" The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...). This argument can be omitted in which case HTTPie will use POST if there @@ -70,29 +69,41 @@ $ http example.org # => GET $ http example.org hello=world # => POST - ''' + """, ) -positional.add_argument( +positional_arguments.add_argument( dest='url', metavar='URL', - help=''' - The scheme defaults to 'http://' if the URL does not include one. - (You can override this with: --default-scheme=https) + short_help='The request URL.', + help=""" + The request URL. Scheme defaults to 'http://' if the URL + does not include one. (You can override this with: --default-scheme=http/https) You can also use a shorthand for localhost $ http :3000 # => http://localhost:3000 $ http :/foo # => http://localhost/foo - ''' + """, ) -positional.add_argument( +positional_arguments.add_argument( dest='request_items', metavar='REQUEST_ITEM', - nargs=ZERO_OR_MORE, + nargs=Qualifiers.ZERO_OR_MORE, default=None, type=KeyValueArgType(*SEPARATOR_GROUP_ALL_ITEMS), - help=r''' + short_help=( + 'HTTPie’s request items syntax for specifying HTTP headers, JSON/Form' + 'data, files, and URL parameters.' + ), + nested_options=[ + ('HTTP Headers', 'Name:Value', 'Arbitrary HTTP header, e.g X-API-Token:123'), + ('URL Parameters', 'name==value', 'Querystring parameter to the URL, e.g limit==50'), + ('Data Fields', 'field=value', 'Data fields to be serialized as JSON (default) or Form Data (with --form)'), + ('Raw JSON Fields', 'field:=json', 'Data field for real JSON types.'), + ('File upload Fields', 'field@/dir/file', 'Path field for uploading a file.'), + ], + help=r""" Optional key-value pairs to be included in the request. The separator used determines the type: @@ -130,66 +141,66 @@ field-name-with\:colon=value - ''' + """, ) ####################################################################### # Content type. ####################################################################### -content_type = parser.add_argument_group( - title='Predefined Content Types', - description=None -) +content_types = options.add_group('Predefined content types') -content_type.add_argument( - '--json', '-j', +content_types.add_argument( + '--json', + '-j', action='store_const', const=RequestType.JSON, dest='request_type', - help=''' + short_help='(default) Serialize data items from the command line as a JSON object.', + help=""" (default) Data items from the command line are serialized as a JSON object. The Content-Type and Accept headers are set to application/json (if not specified). - ''' + """, ) -content_type.add_argument( - '--form', '-f', +content_types.add_argument( + '--form', + '-f', action='store_const', const=RequestType.FORM, dest='request_type', - help=''' + short_help='Serialize data items from the command line as form field data.', + help=""" Data items from the command line are serialized as form fields. The Content-Type is set to application/x-www-form-urlencoded (if not specified). The presence of any file fields results in a multipart/form-data request. - ''' + """, ) -content_type.add_argument( +content_types.add_argument( '--multipart', action='store_const', const=RequestType.MULTIPART, dest='request_type', - help=''' - Similar to --form, but always sends a multipart/form-data - request (i.e., even without files). - - ''' + short_help=( + 'Similar to --form, but always sends a multipart/form-data ' + 'request (i.e., even without files).' + ) ) -content_type.add_argument( +content_types.add_argument( '--boundary', - help=''' - Specify a custom boundary string for multipart/form-data requests. - Only has effect only together with --form. - - ''' + short_help=( + 'Specify a custom boundary string for multipart/form-data requests. ' + 'Only has effect only together with --form.' + ) ) -content_type.add_argument( +content_types.add_argument( '--raw', - help=''' + short_help='Pass raw request data without extra processing.', + help=""" This option allows you to pass raw request data without extra processing (as opposed to the structured request items syntax): @@ -204,149 +215,168 @@ $ http pie.dev/post @data.txt - ''' + """, ) - ####################################################################### # Content processing. ####################################################################### -content_processing = parser.add_argument_group( - title='Content Processing Options', - description=None -) +processing_options = options.add_group('Content processing options') -content_processing.add_argument( - '--compress', '-x', +processing_options.add_argument( + '--compress', + '-x', action='count', default=0, - help=''' + short_help='Compress the content with Deflate algorithm.', + help=""" Content compressed (encoded) with Deflate algorithm. The Content-Encoding header is set to deflate. Compression is skipped if it appears that compression ratio is negative. Compression can be forced by repeating the argument. - ''' + """, ) + ####################################################################### # Output processing ####################################################################### -output_processing = parser.add_argument_group(title='Output Processing') + +def format_style_help(available_styles, *, isolation_mode: bool = False): + text = """ + Output coloring style (default is "{default}"). It can be one of: + + {available_styles} + """ + if isolation_mode: + text += '\n\n' + text += 'For finding out all available styles in your system, try:\n\n' + text += ' $ http --style\n' + text += textwrap.dedent(""" + The "{auto_style}" style follows your terminal's ANSI color styles. + For non-{auto_style} styles to work properly, please make sure that the + $TERM environment variable is set to "xterm-256color" or similar + (e.g., via `export TERM=xterm-256color' in your ~/.bashrc). + """) + + if isolation_mode: + available_styles = sorted(BUNDLED_STYLES) + + available_styles_text = '\n'.join( + f' {line.strip()}' + for line in textwrap.wrap(', '.join(available_styles), 60) + ).strip() + return text.format( + default=DEFAULT_STYLE, + available_styles=available_styles_text, + auto_style=AUTO_STYLE, + ) + + +_sorted_kwargs = { + 'action': 'append_const', + 'const': SORTED_FORMAT_OPTIONS_STRING, + 'dest': 'format_options', +} +_unsorted_kwargs = { + 'action': 'append_const', + 'const': UNSORTED_FORMAT_OPTIONS_STRING, + 'dest': 'format_options', +} + +output_processing = options.add_group('Output processing') output_processing.add_argument( '--pretty', dest='prettify', default=PRETTY_STDOUT_TTY_ONLY, choices=sorted(PRETTY_MAP.keys()), - help=''' + short_help='Control the processing of console outputs.', + help=""" Controls output processing. The value can be "none" to not prettify the output (default for redirected output), "all" to apply both colors and formatting (default for terminal output), "colors", or "format". - ''' + """, ) - - -def format_style_help(available_styles): - return ''' - Output coloring style (default is "{default}"). It can be one of: - - {available_styles} - - The "{auto_style}" style follows your terminal's ANSI color styles. - For non-{auto_style} styles to work properly, please make sure that the - $TERM environment variable is set to "xterm-256color" or similar - (e.g., via `export TERM=xterm-256color' in your ~/.bashrc). - '''.format( - default=DEFAULT_STYLE, - available_styles='\n'.join( - f' {line.strip()}' - for line in wrap(', '.join(available_styles), 60) - ).strip(), - auto_style=AUTO_STYLE, - ) - - output_processing.add_argument( - '--style', '-s', + '--style', + '-s', dest='style', metavar='STYLE', default=DEFAULT_STYLE, action='lazy_choices', getter=get_available_styles, - help_formatter=format_style_help + short_help=f'Output coloring style (default is "{DEFAULT_STYLE}").', + help_formatter=format_style_help, ) -_sorted_kwargs = { - 'action': 'append_const', - 'const': SORTED_FORMAT_OPTIONS_STRING, - 'dest': 'format_options' -} -_unsorted_kwargs = { - 'action': 'append_const', - 'const': UNSORTED_FORMAT_OPTIONS_STRING, - 'dest': 'format_options' -} # The closest approx. of the documented resetting to default via --no-