9
9
from time import monotonic
10
10
from typing import Any , Dict , Callable , Iterable
11
11
from urllib .parse import urlparse , urlunparse
12
+ import ipaddress
12
13
13
14
import niquests
14
15
@@ -71,12 +72,38 @@ def collect_messages(
71
72
source_address = None
72
73
73
74
if args .interface :
75
+ # automatically raises ValueError upon invalid IP
76
+ ipaddress .ip_address (args .interface )
77
+
74
78
source_address = (args .interface , 0 )
75
79
if args .local_port :
80
+
76
81
if '-' not in args .local_port :
77
- source_address = (args .interface or "0.0.0.0" , int (args .local_port ))
82
+ try :
83
+ parsed_port = int (args .local_port )
84
+ except ValueError :
85
+ raise ValueError (f'"{ args .local_port } " is not a valid port number.' )
86
+
87
+ source_address = (args .interface or "0.0.0.0" , parsed_port )
78
88
else :
79
- min_port , max_port = args .local_port .split ('-' , 1 )
89
+ if args .local_port .count ('-' ) != 1 :
90
+ raise ValueError (f'"{ args .local_port } " is not a valid port range. i.e. we accept value like "25441-65540".' )
91
+
92
+ try :
93
+ min_port , max_port = args .local_port .split ('-' , 1 )
94
+ except ValueError :
95
+ raise ValueError (f'The port range you gave in input "{ args .local_port } " is not a valid range.' )
96
+
97
+ if min_port == "" :
98
+ raise ValueError ("Negative port number are all invalid values." )
99
+ if max_port == "" :
100
+ raise ValueError ('Port range requires both start and end ports to be specified. e.g. "25441-65540".' )
101
+
102
+ try :
103
+ min_port , max_port = int (min_port ), int (max_port )
104
+ except ValueError :
105
+ raise ValueError (f'Either "{ min_port } " or/and "{ max_port } " is an invalid port number.' )
106
+
80
107
source_address = (args .interface or "0.0.0.0" , randint (int (min_port ), int (max_port )))
81
108
82
109
parsed_url = parse_url (args .url )
@@ -91,6 +118,20 @@ def collect_messages(
91
118
else :
92
119
resolver = [ensure_resolver , "system://" ]
93
120
121
+ force_opt_count = [args .force_http1 , args .force_http2 , args .force_http3 ].count (True )
122
+ disable_opt_count = [args .disable_http1 , args .disable_http2 , args .disable_http3 ].count (True )
123
+
124
+ if force_opt_count > 1 :
125
+ raise ValueError (
126
+ 'You may only force one of --http1, --http2 or --http3. Use --disable-http1, '
127
+ '--disable-http2 or --disable-http3 instead if you prefer the excluding logic.'
128
+ )
129
+ elif force_opt_count == 1 and disable_opt_count :
130
+ raise ValueError (
131
+ 'You cannot both force a http protocol version and disable some other. e.g. '
132
+ '--http2 already force HTTP/2, do not use --disable-http1 at the same time.'
133
+ )
134
+
94
135
if args .force_http1 :
95
136
args .disable_http1 = False
96
137
args .disable_http2 = True
@@ -245,11 +286,22 @@ def build_requests_session(
245
286
if quic_cache is not None :
246
287
requests_session .quic_cache_layer = QuicCapabilityCache (quic_cache )
247
288
289
+ if urllib3 .util .connection .HAS_IPV6 is False and disable_ipv4 is True :
290
+ raise ValueError ('Unable to force IPv6 because your system lack IPv6 support.' )
291
+ if disable_ipv4 and disable_ipv6 :
292
+ 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.' )
293
+
248
294
if resolver :
249
295
resolver_rebuilt = []
250
296
for r in resolver :
251
297
# assume it is the in-memory resolver
252
298
if "://" not in r :
299
+ if ":" not in r or r .count (':' ) != 1 :
300
+ raise ValueError ("The manual resolver for a specific host requires to be formatted like 'hostname:ip'. e.g. 'pie.dev:1.1.1.1'." )
301
+ hostname , override_ip = r .split (':' )
302
+ if hostname .strip () == "" or override_ip .strip () == "" :
303
+ raise ValueError ("The manual resolver for a specific host requires to be formatted like 'hostname:ip'. e.g. 'pie.dev:1.1.1.1'." )
304
+ ipaddress .ip_address (override_ip )
253
305
r = f"in-memory://default/?hosts={ r } "
254
306
resolver_rebuilt .append (r )
255
307
resolver = resolver_rebuilt
0 commit comments