bpo-38216, bpo-36274: Allow subclasses to separately override validation and encoding behavior (GH-16448)
* bpo-38216: Allow bypassing input validation
* bpo-36274: Also allow the URL encoding to be overridden.
* bpo-38216, bpo-36274: Add tests demonstrating a hook for overriding validation, test demonstrating override encoding, and a test to capture expectation of the interface for the URL.
* Call with skip_host to avoid tripping on the host checking in the URL.
* Remove obsolete comment.
* Make _prepare_path_encoding its own attr.
This makes overriding just that simpler.
Also, don't use the := operator to make backporting easier.
* Add a news entry.
* _prepare_path_encoding -> _encode_prepared_path()
* Once again separate the path validation and request encoding, drastically simplifying the behavior. Drop the guarantee that all processing happens in _prepare_path.
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 1121224..e1aa414 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -1155,6 +1155,34 @@
thread.join()
self.assertEqual(result, b"proxied data\n")
+ def test_putrequest_override_validation(self):
+ """
+ It should be possible to override the default validation
+ behavior in putrequest (bpo-38216).
+ """
+ class UnsafeHTTPConnection(client.HTTPConnection):
+ def _validate_path(self, url):
+ pass
+
+ conn = UnsafeHTTPConnection('example.com')
+ conn.sock = FakeSocket('')
+ conn.putrequest('GET', '/\x00')
+
+ def test_putrequest_override_encoding(self):
+ """
+ It should be possible to override the default encoding
+ to transmit bytes in another encoding even if invalid
+ (bpo-36274).
+ """
+ class UnsafeHTTPConnection(client.HTTPConnection):
+ def _encode_request(self, str_url):
+ return str_url.encode('utf-8')
+
+ conn = UnsafeHTTPConnection('example.com')
+ conn.sock = FakeSocket('')
+ conn.putrequest('GET', '/☃')
+
+
class ExtendedReadTest(TestCase):
"""
Test peek(), read1(), readline()
@@ -1279,6 +1307,7 @@
p = self.resp.peek(0)
self.assertLessEqual(0, len(p))
+
class ExtendedReadTestChunked(ExtendedReadTest):
"""
Test peek(), read1(), readline() in chunked mode