Skip to content

Commit 59073c9

Browse files
gh-109096: Deprecate http.server.CGIHTTPRequestHandler (#109387)
Deprecate `http.server.CGIHTTPRequestHandler`. Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 19f5eff commit 59073c9

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

Doc/library/http.server.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,11 +502,24 @@ following command runs an HTTP/1.1 conformant server::
502502
Note that CGI scripts will be run with UID of user nobody, for security
503503
reasons. Problems with the CGI script will be translated to error 403.
504504

505+
.. deprecated-removed:: 3.13 3.15
506+
507+
:class:`CGIHTTPRequestHandler` is being removed in 3.15. CGI has not
508+
been considered a good way to do things for well over a decade. This code
509+
has been unmaintained for a while now and sees very little practical use.
510+
Retaining it could lead to further :ref:`security considerations
511+
<http.server-security>`.
512+
505513
:class:`CGIHTTPRequestHandler` can be enabled in the command line by passing
506514
the ``--cgi`` option::
507515

508516
python -m http.server --cgi
509517

518+
.. deprecated-removed:: 3.13 3.15
519+
520+
:mod:`http.server` command line ``--cgi`` support is being removed
521+
because :class:`CGIHTTPRequestHandler` is being removed.
522+
510523
.. _http.server-security:
511524

512525
Security Considerations

Doc/whatsnew/3.13.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ Deprecated
248248
practice.
249249
(Contributed by Victor Stinner in :gh:`106535`.)
250250

251+
* :mod:`http.server`: :class:`http.server.CGIHTTPRequestHandler` now emits a
252+
:exc:`DeprecationWarning` as it will be removed in 3.15. Process based CGI
253+
http servers have been out of favor for a very long time. This code was
254+
outdated, unmaintained, and rarely used. It has a high potential for both
255+
security and functionality bugs. This includes removal of the ``--cgi``
256+
flag to the ``python -m http.server`` command line in 3.15.
257+
251258
* :mod:`typing`: Creating a :class:`typing.NamedTuple` class using keyword arguments to denote
252259
the fields (``NT = NamedTuple("NT", x=int, y=int)``) is deprecated, and will
253260
be disallowed in Python 3.15. Use the class-based syntax or the functional
@@ -414,6 +421,11 @@ Pending Removal in Python 3.14
414421
Pending Removal in Python 3.15
415422
------------------------------
416423

424+
* :class:`http.server.CGIHTTPRequestHandler` will be removed along with its
425+
related ``--cgi`` flag to ``python -m http.server``. It was obsolete and
426+
rarely used. No direct replacement exists. *Anything* is better than CGI
427+
to interface a web server with a request handler.
428+
417429
* :class:`typing.NamedTuple`:
418430

419431
* The undocumented keyword argument syntax for creating NamedTuple classes

Lib/http/server.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
33
Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see
44
SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST,
5-
and CGIHTTPRequestHandler for CGI scripts.
5+
and (deprecated) CGIHTTPRequestHandler for CGI scripts.
66
7-
It does, however, optionally implement HTTP/1.1 persistent connections,
8-
as of version 0.3.
7+
It does, however, optionally implement HTTP/1.1 persistent connections.
98
109
Notes on CGIHTTPRequestHandler
1110
------------------------------
1211
13-
This class implements GET and POST requests to cgi-bin scripts.
12+
This class is deprecated. It implements GET and POST requests to cgi-bin scripts.
1413
15-
If the os.fork() function is not present (e.g. on Windows),
16-
subprocess.Popen() is used as a fallback, with slightly altered semantics.
14+
If the os.fork() function is not present (Windows), subprocess.Popen() is used,
15+
with slightly altered but never documented semantics. Use from a threaded
16+
process is likely to trigger a warning at os.fork() time.
1717
1818
In all cases, the implementation is intentionally naive -- all
1919
requests are executed synchronously.
@@ -986,6 +986,12 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
986986
987987
"""
988988

989+
def __init__(self, *args, **kwargs):
990+
import warnings
991+
warnings._deprecated("http.server.CGIHTTPRequestHandler",
992+
remove=(3, 15))
993+
super().__init__(*args, **kwargs)
994+
989995
# Determine platform specifics
990996
have_fork = hasattr(os, 'fork')
991997

Lib/test/test_httpservers.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,11 +699,20 @@ def test_html_escape_filename(self):
699699
"This test can't be run reliably as root (issue #13308).")
700700
class CGIHTTPServerTestCase(BaseTestCase):
701701
class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
702-
pass
702+
_test_case_self = None # populated by each setUp() method call.
703+
704+
def __init__(self, *args, **kwargs):
705+
with self._test_case_self.assertWarnsRegex(
706+
DeprecationWarning,
707+
r'http\.server\.CGIHTTPRequestHandler'):
708+
# This context also happens to catch and silence the
709+
# threading DeprecationWarning from os.fork().
710+
super().__init__(*args, **kwargs)
703711

704712
linesep = os.linesep.encode('ascii')
705713

706714
def setUp(self):
715+
self.request_handler._test_case_self = self # practical, but yuck.
707716
BaseTestCase.setUp(self)
708717
self.cwd = os.getcwd()
709718
self.parent_dir = tempfile.mkdtemp()
@@ -780,6 +789,7 @@ def setUp(self):
780789
os.chdir(self.parent_dir)
781790

782791
def tearDown(self):
792+
self.request_handler._test_case_self = None
783793
try:
784794
os.chdir(self.cwd)
785795
if self._pythonexe_symlink:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:class:`http.server.CGIHTTPRequestHandler` has been deprecated for removal
2+
in 3.15. Its design is old and the web world has long since moved beyond
3+
CGI.

0 commit comments

Comments
 (0)