gh-109096: Deprecate http.server.CGIHTTPRequestHandler (#109387)

Deprecate `http.server.CGIHTTPRequestHandler`.

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
Gregory P. Smith 2023-09-15 14:26:45 -07:00 committed by GitHub
parent 19f5effc27
commit 59073c9ab8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 7 deletions

View file

@ -502,11 +502,24 @@ following command runs an HTTP/1.1 conformant server::
Note that CGI scripts will be run with UID of user nobody, for security
reasons. Problems with the CGI script will be translated to error 403.
.. deprecated-removed:: 3.13 3.15
:class:`CGIHTTPRequestHandler` is being removed in 3.15. CGI has not
been considered a good way to do things for well over a decade. This code
has been unmaintained for a while now and sees very little practical use.
Retaining it could lead to further :ref:`security considerations
<http.server-security>`.
:class:`CGIHTTPRequestHandler` can be enabled in the command line by passing
the ``--cgi`` option::
python -m http.server --cgi
.. deprecated-removed:: 3.13 3.15
:mod:`http.server` command line ``--cgi`` support is being removed
because :class:`CGIHTTPRequestHandler` is being removed.
.. _http.server-security:
Security Considerations

View file

@ -248,6 +248,13 @@ Deprecated
practice.
(Contributed by Victor Stinner in :gh:`106535`.)
* :mod:`http.server`: :class:`http.server.CGIHTTPRequestHandler` now emits a
:exc:`DeprecationWarning` as it will be removed in 3.15. Process based CGI
http servers have been out of favor for a very long time. This code was
outdated, unmaintained, and rarely used. It has a high potential for both
security and functionality bugs. This includes removal of the ``--cgi``
flag to the ``python -m http.server`` command line in 3.15.
* :mod:`typing`: Creating a :class:`typing.NamedTuple` class using keyword arguments to denote
the fields (``NT = NamedTuple("NT", x=int, y=int)``) is deprecated, and will
be disallowed in Python 3.15. Use the class-based syntax or the functional
@ -414,6 +421,11 @@ Pending Removal in Python 3.14
Pending Removal in Python 3.15
------------------------------
* :class:`http.server.CGIHTTPRequestHandler` will be removed along with its
related ``--cgi`` flag to ``python -m http.server``. It was obsolete and
rarely used. No direct replacement exists. *Anything* is better than CGI
to interface a web server with a request handler.
* :class:`typing.NamedTuple`:
* The undocumented keyword argument syntax for creating NamedTuple classes

View file

@ -2,18 +2,18 @@
Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see
SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST,
and CGIHTTPRequestHandler for CGI scripts.
and (deprecated) CGIHTTPRequestHandler for CGI scripts.
It does, however, optionally implement HTTP/1.1 persistent connections,
as of version 0.3.
It does, however, optionally implement HTTP/1.1 persistent connections.
Notes on CGIHTTPRequestHandler
------------------------------
This class implements GET and POST requests to cgi-bin scripts.
This class is deprecated. It implements GET and POST requests to cgi-bin scripts.
If the os.fork() function is not present (e.g. on Windows),
subprocess.Popen() is used as a fallback, with slightly altered semantics.
If the os.fork() function is not present (Windows), subprocess.Popen() is used,
with slightly altered but never documented semantics. Use from a threaded
process is likely to trigger a warning at os.fork() time.
In all cases, the implementation is intentionally naive -- all
requests are executed synchronously.
@ -986,6 +986,12 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
"""
def __init__(self, *args, **kwargs):
import warnings
warnings._deprecated("http.server.CGIHTTPRequestHandler",
remove=(3, 15))
super().__init__(*args, **kwargs)
# Determine platform specifics
have_fork = hasattr(os, 'fork')

View file

@ -699,11 +699,20 @@ def test_html_escape_filename(self):
"This test can't be run reliably as root (issue #13308).")
class CGIHTTPServerTestCase(BaseTestCase):
class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
pass
_test_case_self = None # populated by each setUp() method call.
def __init__(self, *args, **kwargs):
with self._test_case_self.assertWarnsRegex(
DeprecationWarning,
r'http\.server\.CGIHTTPRequestHandler'):
# This context also happens to catch and silence the
# threading DeprecationWarning from os.fork().
super().__init__(*args, **kwargs)
linesep = os.linesep.encode('ascii')
def setUp(self):
self.request_handler._test_case_self = self # practical, but yuck.
BaseTestCase.setUp(self)
self.cwd = os.getcwd()
self.parent_dir = tempfile.mkdtemp()
@ -780,6 +789,7 @@ def setUp(self):
os.chdir(self.parent_dir)
def tearDown(self):
self.request_handler._test_case_self = None
try:
os.chdir(self.cwd)
if self._pythonexe_symlink:

View file

@ -0,0 +1,3 @@
:class:`http.server.CGIHTTPRequestHandler` has been deprecated for removal
in 3.15. Its design is old and the web world has long since moved beyond
CGI.