Simple file server to serve current directory
python3 -m http.server
or if you don't want to use the default port 8000
python3 -m http.server 3333
or if you want to allow connections from localhost only
python3 -m http.server --bind 127.0.0.1
See the docs.
The equivalent Python 2 commands are
python -m SimpleHTTPServer
python -m SimpleHTTPServer 3333
There is no --bind
option.
See the Python 2 docs.
Node.js quick file server (static files over HTTP)
A good "ready-to-use tool" option could be http-server:
npm install http-server -g
To use it:
cd D:\Folder
http-server
Or, like this:
http-server D:\Folder
Check it out: https://github.com/nodeapps/http-server
Serve directory in Python 3
The simple way
You want to extend the functionality of SimpleHTTPRequestHandler
, so you subclass it! Check for your special condition(s), if none of them apply, call super().do_GET()
and let it do the rest.
Example:
class MyHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'up')
else:
super().do_GET()
The long way
To serve files, you basically just have to open them, read the contents and send it.
To serve directories (indexes), use os.listdir()
. (If you want, you can when receiving directories first check for an index.html and then, if that fails, serve an index listing).
Putting this into your code will give you:
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print(self.path)
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'Going up')
elif os.path.isdir(self.path):
try:
self.send_response(200)
self.end_headers()
self.wfile.write(str(os.listdir(self.path)).encode())
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
else:
try:
with open(self.path, 'rb') as f:
data = f.read()
self.send_response(200)
self.end_headers()
self.wfile.write(data)
except FileNotFoundError:
self.send_response(404)
self.end_headers()
self.wfile.write(b'not found')
except PermissionError:
self.send_response(403)
self.end_headers()
self.wfile.write(b'no permission')
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
This example has a lot of error handling. You might want to move it somewhere else.
The problem is this serves from your root directory. To stop this, you'll have to (easy way) just add the serving directory to the beginning of self.path
. Also check if ..
cause you to land higher than you want. A way to do this is os.path.abspath(serve_from+self.path).startswith(serve_from)
Putting this inside (after the check for /up):
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print(self.path)
path = serve_from + self.path
if self.path == '/up':
self.send_response(200)
self.end_headers()
self.wfile.write(b'Going up')
elif not os.path.abspath(path).startswith(serve_from):
self.send_response(403)
self.end_headers()
self.wfile.write(b'Private!')
elif os.path.isdir(path):
try:
self.send_response(200)
self.end_headers()
self.wfile.write(str(os.listdir(path)).encode())
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
else:
try:
with open(path, 'rb') as f:
data = f.read()
self.send_response(200)
self.end_headers()
self.wfile.write(data)
# error handling skipped
except Exception:
self.send_response(500)
self.end_headers()
self.wfile.write(b'error')
Note you define path
and use it subsequently, otherwise you will still serve from /
serve current directory from command line
Simplest way possible (thanks Aaron Patterson/n0kada):
ruby -run -e httpd . -p 9090
Alternate, more complex way:
ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 9090, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"
Even the first command is hard to remember, so I just have this in my .bashrc
:
function serve {
port="${1:-3000}"
ruby -run -e httpd . -p $port
}
It serves the current directory on port 3000 by default, but you can also specify the port:
~ $ cd tmp
~/tmp $ serve # ~/tmp served on port 3000
~/tmp $ cd ../www
~/www $ serve 5000 # ~/www served on port 5000
How to run a http server which serves a specific path?
In Python 3.7 SimpleHTTPRequestHandler
can take a directory
argument:
import http.server
import socketserver
PORT = 8000
DIRECTORY = "web"
class Handler(http.server.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=DIRECTORY, **kwargs)
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
and from the command line:
python -m http.server --directory web
To get a little crazy... you could make handlers for arbitrary directories:
def handler_from(directory):
def _init(self, *args, **kwargs):
return http.server.SimpleHTTPRequestHandler.__init__(self, *args, directory=self.directory, **kwargs)
return type(f'HandlerFrom<{directory}>',
(http.server.SimpleHTTPRequestHandler,),
{'__init__': _init, 'directory': directory})
with socketserver.TCPServer(("", PORT), handler_from("web")) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
Set the current directory when running a SimpleHTTPServer
If you're using SimpleHTTPServer
directly from command line, you can simply use shell features:
pushd /path/you/want/to/serve; python -m SimpleHTTPServer; popd
In Python 3 you have to use:
pushd /path/you/want/to/serve; python -m http.server; popd
The SimpleHTTPServer module has been merged into http.server in Python 3.0
http.server (SimpleHTTPServer) serve file.html instead of dir (using cmd)
SimpleHTTPServer
(or http.server
in Python3) will serve a directory unless that directory contains a file called index.html
, in which case it will serve that instead.
So just rename login.html
to index.html
and it should do what you want.
Node.js quick file server (static files over HTTPS)
Yes, it is possible.
Refer this answer npm http-server with SSL
OR
Step 1. Write a server
You can use pure node.js modules to serve static files or you can use an express framework to solve your issue. https://expressjs.com/en/starter/static-files.html
Step 2. Write a command-line script
You have to write a script and preferably saves into the bin folder, that accepts the command-line arguments such as folder path, port, etc. and starts the server. Also, you can use node.js to write such scripts using commander.js, etc.
How do I serve and log my current directory with a python web server?
You need to use dir_listing() to list directories.
Rather than writing it here, I would suggest you look at the python cookbook/ recipes for detailed directions and understanding.
- http://code.activestate.com/recipes/392879-my-first-application-server/
Is it possible to have SimpleHTTPServer serve files from two different directories?
I do not believe SimpleHTTPServer has this feature, however if you use a symbolic link inside of /test that points to /protected/public, that should effectively do the same thing.
Related Topics
Plotting of 2D Data:Heatmap with Different Colormaps
Integration Testing for a Web App
Python VS. Ruby for Metaprogramming
How to Import CSV Data into Django Models
Expand Python Search Path to Other Source
Typeerror: Can't Use a String Pattern on a Bytes-Like Object in Re.Findall()
Python 32-Bit Memory Limits on 64Bit Windows
Understanding _Getitem_ Method
Getting Number of Elements in an Iterator in Python
Control the Size Textarea Widget Look in Django Admin
Python(Or Numpy) Equivalent of Match in R
Is There a Python Equivalent for Rspec to Do Tdd
Iterate Over Object Attributes in Python
Python 3.7 Anaconda Environment - Import _Ssl Dll Load Fail Error
Blocking and Non Blocking Subprocess Calls
Module' Object Has No Attribute 'Loads' While Parsing JSON Using Python