A Summary of Simple Web Servers for Web Browser Application Development

  • UUID: 229fb30d-afd2-409f-8696-39711fd6c405
  • Status: Updated on 20211120
  • Previous title: No.01 A Summary of Simple Web Servers for Frontend Development

References

  • MDN > How do you set up a local testing server?, https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server
  • Python Docs > HTTP servers, https://docs.python.org/3/library/http.server.html

Built-ins in Environments

PHP

  • .php files can also be executed
php -S 0.0.0.0:5000

Python 3

python3 -m http.server
python3 -m http.server 5000
python3 -m http.server 0.0.0.0:5000

python -m http.server 5000 --cgi
# NOTE: New in version 3.4
python -m http.server 5000 --bind 127.0.0.1 
# NOTE: New in version 3.7
python -m http.server --directory /tmp/

Python 2

python2 -m SimpleHTTPServer
python2 -m SimpleHTTPServer 5000
python2 -m SimpleHTTPServer 0.0.0.0:5000

DIY on Only A Few Lines of Code Required Web Frameworks

Python Flask

pip3 install flask

python3 simple-sever.py

Node.js Express

npm install express

node simple-server.js

Do It Yourself Example

A Web Server which Provides JSON Responses

# -*- coding: utf-8 -*-

# AUTHOR: Johann Huang ([email protected])
# DATE: 20200525
# REFERENCE: https://docs.python.org/3/library/http.server.html
# REFERENCE: https://www.tutorialspoint.com/python/python_cgi_programming.htm
# REFERENCE: https://gist.github.com/nitaku/10d0662536f37a087e1b

import os
import cgi
import json

from http import HTTPStatus
from http.server import HTTPServer, BaseHTTPRequestHandler

class JSONHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        """Serve a GET request."""
        self.send_response(HTTPStatus.OK)
        self.flush_headers()
        self.send_header('Content-type', 'application/json')
        self.end_headers()

        path = self.path
        _uri, _, query_string = path.partition('?')
        decoded_query_string = query_string.replace('+', ' ')
        query_dict = {}
        if decoded_query_string:
            for parameter in decoded_query_string.split('&'):
                key = parameter.split('=')[0]
                value = True if '=' not in parameter else parameter.split('=')[1]
                query_dict[key] = value
            self.wfile.write(json.dumps(query_dict).encode('utf-8'))
        else:
            self.wfile.write(json.dumps({'error': 404, 'message': 'not found', 'path': path}).encode('utf-8'))

    def do_POST(self): # NOTE: not tested, highly possibly not working
        """Serve a POST request."""
        self.send_response(HTTPStatus.OK)
        self.flush_headers()
        self.send_header('Content-type', 'application/json')
        self.end_headers()

        ctype, _pdict = cgi.parse_header(self.headers.getheader('content-type'))

        # refuse to receive non-json content
        if ctype != 'application/json':
            self.send_response(400)
            self.end_headers()
            return

        # read the message and convert it into a python dictionary
        length = int(self.headers.getheader('content-length'))
        message = json.loads(self.rfile.read(length).decode('utf-8'))

        # add a property to the object, just to mess with data
        message['received'] = 'ok'
        self.wfile.write(json.dumps(message).encode('utf-8'))

def run(host='', port=4000, handler_class=JSONHTTPRequestHandler, server_class=HTTPServer, *args, **kwargs):
    server_address = (host, port)
    httpd = server_class(server_address, handler_class)

    print('MESSAGE: HTTPServer is listening at', server_address)
    httpd.serve_forever()

if __name__ == "__main__":
    # NOTE: empty also means every network interface, including loopback one, similar as '0.0.0.0'
    HOST = '0.0.0.0'
    PORT = 4000

    run(HOST, PORT, JSONHTTPRequestHandler)

* cached version, generated at 2024-01-09 07:25:58 UTC.

Subscribe by RSS