title: Trivial Http Servers tags: python net web http server # One Liner ```bash python -m http.server 8000 ``` Note also that PHP supplies something similar (useful if your source contains php pages). ```bash php -S localhost:8000 ``` # Basic Examples ```py #!/usr/bin/env python3 # Python 3 server example from http.server import BaseHTTPRequestHandler, HTTPServer from subprocess import run, PIPE import time import sys import re from datetime import datetime from threading import Thread hostName = "" serverPort = 4041 class MyServer(BaseHTTPRequestHandler): def homepage(self): self.homepage_html = open("homepage.html").read() self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(bytes(self.homepage_html, "utf-8")) def do_GET(self): if self.path == "/favicon.ico": self.send_response(404) self.end_headers() self.wfile.write(b"No favicon") return if self.path.strip("/") == "": return self.homepage() print(datetime.now().strftime("%c:")) print(f"Request path: {self.path}") reply = f"You requested: {self.path}" self.send_response(200) self.end_headers() self.wfile.write(reply.encode()) return if __name__ == "__main__": webServer = HTTPServer((hostName, serverPort), MyServer) print("Server started http://%s:%s" % (hostName, serverPort)) try: webServer.serve_forever() except KeyboardInterrupt: pass webServer.server_close() print("Server stopped.") ``` # Bobbins Server This serves an index.html, and all other paths are passed to a shell script. This is useful to make a simple webpage that triggers stuff over the LAN, such as media players. The beauty here is that you can modify the script and the `index.html` without restarting the server. (This includes using symlinks so that the script that is run, and possibly the `index.html` is changed dynamically by other scripts.) ```py #!/usr/bin/env python3 # Python 3 server example from http.server import BaseHTTPRequestHandler, HTTPServer from subprocess import run, PIPE import time import sys import re import random import os import json from glob import glob from datetime import datetime from threading import Thread hostName = "" serverPort = 8989 args = sys.argv[1:] if len(args) == 0: bobbins = "./bobbins" else: bobbins = args[0] if len(args) > 1: try: p = int(args[1]) if p >= 1024 and p <= 64000: serverPort = p except ValueError: pass class MyServer(BaseHTTPRequestHandler): def homepage(self): index_html = open("index.html").read() self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(bytes(index_html, "utf-8")) def do_GET(self): if self.path == "/favicon.ico": self.send_response(404) self.end_headers() self.wfile.write(b"No favicon") p = self.path.strip("/") if p == "": return self.homepage() elif p == "quit": self.send_response(400) self.end_headers() self.wfile.write(b"Quitting") self.server.server_close() else: run([bobbins,p]) self.send_response(303) self.send_header("Location","/") self.end_headers() self.wfile.write(b"") if __name__ == "__main__": print(f"Starting server") webServer = HTTPServer((hostName, serverPort), MyServer) print("Server started http://%s:%s" % (hostName, serverPort)) try: webServer.serve_forever() except KeyboardInterrupt: pass webServer.server_close() print("Server stopped.") ``` ### Example `bobbins` script Note that `mp` and `tvlcmd` are scripts I use to control `mpd` and VLC respectively. I use multiple instances so as to have concurrent playlists in each, so the `C` and `H` select between them. ```bash #!/bin/bash I=1 H=mrhex # vlc host N=20 # vlc channel on frodo3 C=1 # mpd channel run() { case "$1" in start) mp %pause mp "$C",clear,load mytracks,stop tvlcmd "$H" "$N" play "seek 0" "f on" "volume 255" mp "$C",random on,consume on,play ;; restart) mp "$C",seek 0,play tvlcmd "$H" "$N" "seek 0" ;; esac } for s; do echo "$((I++)): $s" run "$s" done ```