@@ -220,6 +220,41 @@ def test_absolute_url() -> None:
220220 assert req .rel_url == URL .build (path = "/path/to" , query = {"a" : "1" })
221221
222222
223+ def test_absolute_form_raw_path () -> None :
224+ # An absolute-form target (RFC 9112 3.2.2) must not leak the scheme/host
225+ # into raw_path. The path, query and fragment are kept byte-for-byte, the
226+ # same raw form an origin-form target yields.
227+ req = make_mocked_request ("GET" , "https://example.com/path/to?a=1#frag" )
228+ assert req .raw_path == "/path/to?a=1#frag"
229+ assert req .raw_path == make_mocked_request ("GET" , "/path/to?a=1#frag" ).raw_path
230+
231+
232+ def test_connect_authority_form_raw_path () -> None :
233+ # Authority-form is only used by CONNECT (RFC 9112 3.2.3); its target is a
234+ # bare host:port with no scheme prefix, so raw_path returns it unchanged.
235+ message = RawRequestMessage (
236+ "CONNECT" ,
237+ "example.com:443" ,
238+ HttpVersion (1 , 1 ),
239+ HeadersDictProxy (CIMultiDict ()),
240+ (),
241+ False ,
242+ None ,
243+ False ,
244+ False ,
245+ URL .build (authority = "example.com:443" , encoded = True ),
246+ )
247+ protocol = mock .Mock ()
248+ protocol .ssl_context = None
249+ protocol .peername = None
250+ protocol .sockname = ("127.0.0.1" , 80 )
251+ req = web .BaseRequest (
252+ message , mock .Mock (), protocol , mock .Mock (), mock .Mock (), mock .Mock ()
253+ )
254+ assert req ._message .url .absolute
255+ assert req .raw_path == "example.com:443"
256+
257+
223258def test_clone_absolute_scheme () -> None :
224259 req = make_mocked_request ("GET" , "https://example.com/path/to?a=1" )
225260 assert req .scheme == "https"
0 commit comments