Skip to content

Commit

Permalink
Move IP version options validation to the CLI layer
Browse files Browse the repository at this point in the history
  • Loading branch information
jkbrzt committed Oct 26, 2024
1 parent 191824c commit 65e4422
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 18 deletions.
11 changes: 11 additions & 0 deletions httpie/cli/argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
)
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
Expand Down Expand Up @@ -174,6 +175,7 @@ def parse_args(
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.
Expand Down Expand Up @@ -576,6 +578,15 @@ def _process_format_options(self):
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

Expand Down
2 changes: 2 additions & 0 deletions httpie/cli/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,13 +749,15 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
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.'
)
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.'
Expand Down
22 changes: 10 additions & 12 deletions httpie/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -156,12 +156,15 @@ def collect_messages(

hooks = None

# 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]}
# 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.
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)
Expand Down Expand Up @@ -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:
Expand Down
8 changes: 8 additions & 0 deletions httpie/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
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 haven’t migrated yet.
Expand Down
12 changes: 6 additions & 6 deletions tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
local_port_arg_type,
parse_local_port_arg,
)
from httpie.compat import has_ipv6_support
from .utils import HTTP_OK, http


Expand Down Expand Up @@ -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


Expand Down

0 comments on commit 65e4422

Please sign in to comment.