Simple File Server to Serve Current Directory

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.

  1. 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



Leave a reply



Submit