Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Doc/library/http.server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 12 additions & 6 deletions Lib/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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')

Expand Down
12 changes: 11 additions & 1 deletion Lib/test/test_httpservers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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.