add support for early responses 1xx (informational)

This commit is contained in:
Ahmed TAHRI 2024-10-13 20:09:35 +02:00
parent 2e3617ecdb
commit 1379a2e281
5 changed files with 34 additions and 14 deletions

View File

@ -3,10 +3,11 @@
This document records all notable changes to [HTTPie](https://httpie.io). This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/). This project adheres to [Semantic Versioning](https://semver.org/).
## [4.0.0.b1](https://github.com/httpie/cli/compare/3.2.2...master) (unreleased) ## [4.0.0](https://github.com/httpie/cli/compare/3.2.3...master) (unreleased)
- Switched from the [`requests`](https://github.com/psf/requests) library to the compatible [`niquests`](https://github.com/jawah/niquests). ([#1531](https://github.com/httpie/cli/pull/1531)) - Switched from the [`requests`](https://github.com/psf/requests) library to the compatible [`niquests`](https://github.com/jawah/niquests). ([#1531](https://github.com/httpie/cli/pull/1531))
- Added support for HTTP/2, and HTTP/3 protocols. ([#523](https://github.com/httpie/cli/issues/523), [#692](https://github.com/httpie/cli/issues/692), [#1531](https://github.com/httpie/cli/pull/1531)) - Added support for HTTP/2, and HTTP/3 protocols. ([#523](https://github.com/httpie/cli/issues/523), [#692](https://github.com/httpie/cli/issues/692), [#1531](https://github.com/httpie/cli/pull/1531))
- Added support for early (informational) responses. ([#752](https://github.com/httpie/cli/issues/752)) ([#1531](https://github.com/httpie/cli/pull/1531))
- Added support for IPv4/IPv6 enforcement with `-6` and `-4`. ([#94](https://github.com/httpie/cli/issues/94), [#1531](https://github.com/httpie/cli/pull/1531)) - Added support for IPv4/IPv6 enforcement with `-6` and `-4`. ([#94](https://github.com/httpie/cli/issues/94), [#1531](https://github.com/httpie/cli/pull/1531))
- Added support for alternative DNS resolvers via `--resolver`. DNS over HTTPS, DNS over TLS, DNS over QUIC, and DNS over UDP are accepted. ([#99](https://github.com/httpie/cli/issues/99), [#1531](https://github.com/httpie/cli/pull/1531)) - Added support for alternative DNS resolvers via `--resolver`. DNS over HTTPS, DNS over TLS, DNS over QUIC, and DNS over UDP are accepted. ([#99](https://github.com/httpie/cli/issues/99), [#1531](https://github.com/httpie/cli/pull/1531))
- Added support for binding to a specific network adapter with `--interface`. ([#1422](https://github.com/httpie/cli/issues/1422), [#1531](https://github.com/httpie/cli/pull/1531)) - Added support for binding to a specific network adapter with `--interface`. ([#1422](https://github.com/httpie/cli/issues/1422), [#1531](https://github.com/httpie/cli/pull/1531))

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import argparse import argparse
import json import json
import sys import sys
@ -43,7 +45,7 @@ def collect_messages(
env: Environment, env: Environment,
args: argparse.Namespace, args: argparse.Namespace,
request_body_read_callback: Callable[[bytes], None] = None, request_body_read_callback: Callable[[bytes], None] = None,
prepared_request_readiness: Callable[[niquests.PreparedRequest], None] = None, request_or_response_callback: Callable[[niquests.PreparedRequest | niquests.Response], None] = None,
) -> Iterable[RequestsMessage]: ) -> Iterable[RequestsMessage]:
httpie_session = None httpie_session = None
httpie_session_headers = None httpie_session_headers = None
@ -155,8 +157,8 @@ def collect_messages(
# It will help us yield the request before it is # It will help us yield the request before it is
# actually sent. This will permit us to know about # actually sent. This will permit us to know about
# the connection information for example. # the connection information for example.
if prepared_request_readiness: if request_or_response_callback:
hooks = {"pre_send": [prepared_request_readiness]} hooks = {"pre_send": [request_or_response_callback], "early_response": [request_or_response_callback]}
request = niquests.Request(**request_kwargs, hooks=hooks) request = niquests.Request(**request_kwargs, hooks=hooks)
prepared_request = requests_session.prepare_request(request) prepared_request = requests_session.prepare_request(request)

View File

@ -3,6 +3,7 @@ import os
import platform import platform
import sys import sys
import socket import socket
from time import monotonic
from typing import List, Optional, Union, Callable from typing import List, Optional, Union, Callable
import niquests import niquests
@ -211,21 +212,26 @@ def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
downloader = Downloader(env, output_file=args.output_file, resume=args.download_resume) downloader = Downloader(env, output_file=args.output_file, resume=args.download_resume)
downloader.pre_request(args.headers) downloader.pre_request(args.headers)
def prepared_request_readiness(pr): def request_or_response_callback(delayed_message):
"""This callback is meant to output the request part. It is triggered by """This callback is called in two scenario:
the underlying Niquests library just after establishing the connection."""
(i) just after initializing a connection to remote host
(ii) an early response has been received (1xx responses)"""
oo = OutputOptions.from_message( oo = OutputOptions.from_message(
pr, delayed_message,
args.output_options args.output_options
) )
oo = oo._replace( if hasattr(delayed_message, "body"):
body=isinstance(pr.body, (str, bytes)) and (args.verbose or oo.body) oo = oo._replace(
) body=isinstance(delayed_message.body, (str, bytes)) and (args.verbose or oo.body)
)
else:
delayed_message._httpie_headers_parsed_at = monotonic()
write_message( write_message(
requests_message=pr, requests_message=delayed_message,
env=env, env=env,
output_options=oo, output_options=oo,
processing_options=processing_options processing_options=processing_options
@ -238,7 +244,7 @@ def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
env, env,
args=args, args=args,
request_body_read_callback=request_body_read_callback, request_body_read_callback=request_body_read_callback,
prepared_request_readiness=prepared_request_readiness request_or_response_callback=request_or_response_callback
) )
force_separator = False force_separator = False

View File

@ -71,7 +71,7 @@ install_requires =
pip pip
charset_normalizer>=2.0.0 charset_normalizer>=2.0.0
defusedxml>=0.6.0 defusedxml>=0.6.0
niquests[socks]>=3.7 niquests[socks]>=3.9
Pygments>=2.5.2 Pygments>=2.5.2
setuptools setuptools
importlib-metadata>=1.4.0; python_version<"3.8" importlib-metadata>=1.4.0; python_version<"3.8"

View File

@ -0,0 +1,11 @@
from .utils import http
def test_early_response_show(remote_httpbin_secure):
r = http(
"--verify=no",
'https://early-hints.fastlylabs.com/'
)
assert "103 Early Hints" in r
assert "200 OK" in r