Skip to content

Commit 65e4422

Browse files
committed
Move IP version options validation to the CLI layer
1 parent 191824c commit 65e4422

File tree

5 files changed

+37
-18
lines changed

5 files changed

+37
-18
lines changed

httpie/cli/argparser.py

+11
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
)
2626
from .exceptions import ParseError
2727
from .requestitems import RequestItems
28+
from ..compat import has_ipv6_support
2829
from ..context import Environment
2930
from ..plugins.registry import plugin_manager
3031
from ..utils import ExplicitNullAuth, get_content_type
@@ -174,6 +175,7 @@ def parse_args(
174175
self._process_output_options()
175176
self._process_pretty_options()
176177
self._process_format_options()
178+
self._process_ip_version_options()
177179

178180
# bellow is a fix for detecting "false-or empty" stdin.
179181
# see https://github.com/httpie/cli/issues/1551 for more information.
@@ -576,6 +578,15 @@ def _process_format_options(self):
576578
parsed_options = parse_format_options(options_group, defaults=parsed_options)
577579
self.args.format_options = parsed_options
578580

581+
def _process_ip_version_options(self):
582+
if not has_ipv6_support() and self.args.force_ipv6:
583+
self.error('Unable to force IPv6 because your system lack IPv6 support.')
584+
if self.args.force_ipv4 and self.args.force_ipv6:
585+
self.error(
586+
'Unable to force both IPv4 and IPv6, omit the flags to allow both. '
587+
'The flags "-6" and "-4" are meant to force one of them.'
588+
)
589+
579590
def print_manual(self):
580591
from httpie.output.ui import man_pages
581592

httpie/cli/definition.py

+2
Original file line numberDiff line numberDiff line change
@@ -749,13 +749,15 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
749749
network.add_argument(
750750
'--ipv6',
751751
'-6',
752+
dest='force_ipv6',
752753
default=False,
753754
action='store_true',
754755
short_help='Force using a IPv6 address to reach the remote peer.'
755756
)
756757
network.add_argument(
757758
'--ipv4',
758759
'-4',
760+
dest='force_ipv4',
759761
default=False,
760762
action='store_true',
761763
short_help='Force using a IPv4 address to reach the remote peer.'

httpie/client.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ def collect_messages(
116116
disable_http2=args.disable_http2,
117117
disable_http3=args.disable_http3,
118118
resolver=resolver,
119-
disable_ipv6=args.ipv4,
120-
disable_ipv4=args.ipv6,
119+
disable_ipv6=args.force_ipv4,
120+
disable_ipv4=args.force_ipv6,
121121
source_address=(args.interface, args.local_port),
122122
quic_cache=env.config.quic_file,
123123
happy_eyeballs=args.happy_eyeballs,
@@ -156,12 +156,15 @@ def collect_messages(
156156

157157
hooks = None
158158

159-
# The hook set up bellow is crucial for HTTPie.
160-
# It will help us yield the request before it is
161-
# actually sent. This will permit us to know about
162-
# the connection information for example.
163159
if request_or_response_callback:
164-
hooks = {"pre_send": [request_or_response_callback], "early_response": [request_or_response_callback]}
160+
# The hook set up bellow is crucial for HTTPie.
161+
# It will help us yield the request before it is
162+
# actually sent. This will permit us to know about
163+
# the connection information for example.
164+
hooks = {
165+
'pre_send': [request_or_response_callback],
166+
'early_response': [request_or_response_callback],
167+
}
165168

166169
request = niquests.Request(**request_kwargs, hooks=hooks)
167170
prepared_request = requests_session.prepare_request(request)
@@ -247,11 +250,6 @@ def build_requests_session(
247250
if quic_cache is not None:
248251
requests_session.quic_cache_layer = QuicCapabilityCache(quic_cache)
249252

250-
if urllib3.util.connection.HAS_IPV6 is False and disable_ipv4 is True:
251-
raise ValueError('Unable to force IPv6 because your system lack IPv6 support.')
252-
if disable_ipv4 and disable_ipv6:
253-
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.')
254-
255253
if resolver:
256254
resolver_rebuilt = []
257255
for r in resolver:

httpie/compat.py

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131
resolve_ssl_version,
3232
)
3333

34+
35+
def has_ipv6_support(new_value: Optional[bool] = None) -> bool:
36+
if new_value is not None:
37+
# Allow overriding the default value for testing purposes.
38+
urllib3.util.connection.HAS_IPV6 = new_value
39+
return urllib3.util.connection.HAS_IPV6
40+
41+
3442
def enforce_niquests():
3543
"""
3644
Force imported 3rd-party plugins to use `niquests` instead of `requests` if they haven’t migrated yet.

tests/test_network.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
local_port_arg_type,
1010
parse_local_port_arg,
1111
)
12+
from httpie.compat import has_ipv6_support
1213
from .utils import HTTP_OK, http
1314

1415

@@ -98,17 +99,16 @@ def test_invalid_interface_arg(httpbin, interface_arg):
9899

99100

100101
def test_force_ipv6_on_unsupported_system(remote_httpbin):
101-
from httpie.compat import urllib3
102-
orig_has_ipv6 = urllib3.util.connection.HAS_IPV6
103-
urllib3.util.connection.HAS_IPV6 = False
102+
orig = has_ipv6_support()
103+
has_ipv6_support(False)
104104
try:
105105
r = http(
106-
"-6", # invalid port
107-
remote_httpbin + "/get",
106+
'-6',
107+
remote_httpbin + '/get',
108108
tolerate_error_exit_status=True,
109109
)
110110
finally:
111-
urllib3.util.connection.HAS_IPV6 = orig_has_ipv6
111+
has_ipv6_support(orig)
112112
assert 'Unable to force IPv6 because your system lack IPv6 support.' in r.stderr
113113

114114

0 commit comments

Comments
 (0)