Skip to content

Commit a17a2f5

Browse files
matrixisevstinner
authored andcommitted
bpo-28707: Add the directory parameter to http.server.SimpleHTTPRequestHandler and http.server module (#1776)
* bpo-28707: call the constructor of SimpleHTTPRequestHandler in the test with a mock object * bpo-28707: Add the directory parameter to http.server.SimpleHTTPRequestHandler and http.server module
1 parent 07244a8 commit a17a2f5

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

Doc/library/http.server.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ of which this module provides three different variants:
299299
delays, it now always returns the IP address.
300300

301301

302-
.. class:: SimpleHTTPRequestHandler(request, client_address, server)
302+
.. class:: SimpleHTTPRequestHandler(request, client_address, server, directory=None)
303303

304304
This class serves files from the current directory and below, directly
305305
mapping the directory structure to HTTP requests.
@@ -323,6 +323,10 @@ of which this module provides three different variants:
323323
``application/octet-stream``. The mapping is used case-insensitively,
324324
and so should contain only lower-cased keys.
325325

326+
.. attribute:: directory
327+
328+
If not specified, the directory to serve is the current working directory.
329+
326330
The :class:`SimpleHTTPRequestHandler` class defines the following methods:
327331

328332
.. method:: do_HEAD()
@@ -397,6 +401,14 @@ following command causes the server to bind to localhost only::
397401
.. versionadded:: 3.4
398402
``--bind`` argument was introduced.
399403

404+
By default, server uses the current directory. The option ``-d/--directory``
405+
specifies a directory to which it should serve the files. For example,
406+
the following command uses a specific directory::
407+
408+
python -m http.server --directory /tmp/
409+
410+
.. versionadded:: 3.7
411+
``--directory`` specify alternate directory
400412

401413
.. class:: CGIHTTPRequestHandler(request, client_address, server)
402414

@@ -442,4 +454,3 @@ following command causes the server to bind to localhost only::
442454
the ``--cgi`` option::
443455

444456
python -m http.server --cgi 8000
445-

Doc/whatsnew/3.7.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ If-Modified-Since header. The server returns the 304 response status if the
139139
target file was not modified after the time specified in the header.
140140
(Contributed by Pierre Quentel in :issue:`29654`.)
141141

142+
Add the parameter ``directory`` to the :class:`~http.server.SimpleHTTPRequestHandler`
143+
and the ``--directory`` to the command line of the module :mod:`~http.server`.
144+
With this parameter, the server serves the specified directory, by default it uses the current working directory.
145+
(Contributed by Stéphane Wirtel and Julien Palard in :issue:`28707`.)
146+
142147
locale
143148
------
144149

Lib/http/server.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
import sys
104104
import time
105105
import urllib.parse
106+
from functools import partial
106107

107108
from http import HTTPStatus
108109

@@ -634,6 +635,12 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
634635

635636
server_version = "SimpleHTTP/" + __version__
636637

638+
def __init__(self, *args, directory=None, **kwargs):
639+
if directory is None:
640+
directory = os.getcwd()
641+
self.directory = directory
642+
super().__init__(*args, **kwargs)
643+
637644
def do_GET(self):
638645
"""Serve a GET request."""
639646
f = self.send_head()
@@ -806,7 +813,7 @@ def translate_path(self, path):
806813
path = posixpath.normpath(path)
807814
words = path.split('/')
808815
words = filter(None, words)
809-
path = os.getcwd()
816+
path = self.directory
810817
for word in words:
811818
if os.path.dirname(word) or word in (os.curdir, os.pardir):
812819
# Ignore components that are not a simple file/directory name
@@ -1234,6 +1241,9 @@ def test(HandlerClass=BaseHTTPRequestHandler,
12341241
parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',
12351242
help='Specify alternate bind address '
12361243
'[default: all interfaces]')
1244+
parser.add_argument('--directory', '-d', default=os.getcwd(),
1245+
help='Specify alternative directory '
1246+
'[default:current directory]')
12371247
parser.add_argument('port', action='store',
12381248
default=8000, type=int,
12391249
nargs='?',
@@ -1242,5 +1252,6 @@ def test(HandlerClass=BaseHTTPRequestHandler,
12421252
if args.cgi:
12431253
handler_class = CGIHTTPRequestHandler
12441254
else:
1245-
handler_class = SimpleHTTPRequestHandler
1255+
handler_class = partial(SimpleHTTPRequestHandler,
1256+
directory=args.directory)
12461257
test(HandlerClass=handler_class, port=args.port, bind=args.bind)

Lib/test/test_httpservers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import tempfile
2323
import time
2424
import datetime
25+
from unittest import mock
2526
from io import BytesIO
2627

2728
import unittest
@@ -782,7 +783,11 @@ def test_query_with_continuous_slashes(self):
782783

783784

784785
class SocketlessRequestHandler(SimpleHTTPRequestHandler):
785-
def __init__(self):
786+
def __init__(self, *args, **kwargs):
787+
request = mock.Mock()
788+
request.makefile.return_value = BytesIO()
789+
super().__init__(request, None, None)
790+
786791
self.get_called = False
787792
self.protocol_version = "HTTP/1.1"
788793

0 commit comments

Comments
 (0)