Move IP version options validation to the CLI layer

This commit is contained in:
Jakub Roztocil 2024-10-26 19:22:52 +02:00
parent 191824ce30
commit 65e44228be
5 changed files with 37 additions and 18 deletions

View File

@ -25,6 +25,7 @@ from .constants import (
)
from .exceptions import ParseError
from .requestitems import RequestItems
from ..compat import has_ipv6_support
from ..context import Environment
from ..plugins.registry import plugin_manager
from ..utils import ExplicitNullAuth, get_content_type
@ -174,6 +175,7 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
self._process_output_options()
self._process_pretty_options()
self._process_format_options()
self._process_ip_version_options()
# bellow is a fix for detecting "false-or empty" stdin.
# see https://github.com/httpie/cli/issues/1551 for more information.
@ -576,6 +578,15 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
parsed_options = parse_format_options(options_group, defaults=parsed_options)
self.args.format_options = parsed_options
def _process_ip_version_options(self):
if not has_ipv6_support() and self.args.force_ipv6:
self.error('Unable to force IPv6 because your system lack IPv6 support.')
if self.args.force_ipv4 and self.args.force_ipv6:
self.error(
'Unable to force both IPv4 and IPv6, omit the flags to allow both. '
'The flags "-6" and "-4" are meant to force one of them.'
)
def print_manual(self):
from httpie.output.ui import man_pages

View File

@ -749,6 +749,7 @@ network.add_argument(
network.add_argument(
'--ipv6',
'-6',
dest='force_ipv6',
default=False,
action='store_true',
short_help='Force using a IPv6 address to reach the remote peer.'
@ -756,6 +757,7 @@ network.add_argument(
network.add_argument(
'--ipv4',
'-4',
dest='force_ipv4',
default=False,
action='store_true',
short_help='Force using a IPv4 address to reach the remote peer.'

View File

@ -116,8 +116,8 @@ def collect_messages(
disable_http2=args.disable_http2,
disable_http3=args.disable_http3,
resolver=resolver,
disable_ipv6=args.ipv4,
disable_ipv4=args.ipv6,
disable_ipv6=args.force_ipv4,
disable_ipv4=args.force_ipv6,
source_address=(args.interface, args.local_port),
quic_cache=env.config.quic_file,
happy_eyeballs=args.happy_eyeballs,
@ -156,12 +156,15 @@ def collect_messages(
hooks = None
if request_or_response_callback:
# The hook set up bellow is crucial for HTTPie.
# It will help us yield the request before it is
# actually sent. This will permit us to know about
# the connection information for example.
if request_or_response_callback:
hooks = {"pre_send": [request_or_response_callback], "early_response": [request_or_response_callback]}
hooks = {
'pre_send': [request_or_response_callback],
'early_response': [request_or_response_callback],
}
request = niquests.Request(**request_kwargs, hooks=hooks)
prepared_request = requests_session.prepare_request(request)
@ -247,11 +250,6 @@ def build_requests_session(
if quic_cache is not None:
requests_session.quic_cache_layer = QuicCapabilityCache(quic_cache)
if urllib3.util.connection.HAS_IPV6 is False and disable_ipv4 is True:
raise ValueError('Unable to force IPv6 because your system lack IPv6 support.')
if disable_ipv4 and disable_ipv6:
raise ValueError('Unable to force both IPv4 and IPv6, omit the flags to allow both. The flags "-6" and "-4" are meant to force one of them.')
if resolver:
resolver_rebuilt = []
for r in resolver:

View File

@ -31,6 +31,14 @@ else:
resolve_ssl_version,
)
def has_ipv6_support(new_value: Optional[bool] = None) -> bool:
if new_value is not None:
# Allow overriding the default value for testing purposes.
urllib3.util.connection.HAS_IPV6 = new_value
return urllib3.util.connection.HAS_IPV6
def enforce_niquests():
"""
Force imported 3rd-party plugins to use `niquests` instead of `requests` if they havent migrated yet.

View File

@ -9,6 +9,7 @@ from httpie.cli.ports import (
local_port_arg_type,
parse_local_port_arg,
)
from httpie.compat import has_ipv6_support
from .utils import HTTP_OK, http
@ -98,17 +99,16 @@ def test_invalid_interface_arg(httpbin, interface_arg):
def test_force_ipv6_on_unsupported_system(remote_httpbin):
from httpie.compat import urllib3
orig_has_ipv6 = urllib3.util.connection.HAS_IPV6
urllib3.util.connection.HAS_IPV6 = False
orig = has_ipv6_support()
has_ipv6_support(False)
try:
r = http(
"-6", # invalid port
remote_httpbin + "/get",
'-6',
remote_httpbin + '/get',
tolerate_error_exit_status=True,
)
finally:
urllib3.util.connection.HAS_IPV6 = orig_has_ipv6
has_ipv6_support(orig)
assert 'Unable to force IPv6 because your system lack IPv6 support.' in r.stderr