Pythonで簡易HTTPSサーバー

ちょっとダミーのHTTPSサーバーを起動させて疎通させたいときなど、Pythonでサクッとやりたい。

HTTPサーバー

こちらはコマンドラインでできる。アクセスすると、実行したディレクトリに一覧がブラウザで参照できる。

sudo python3 -m http.server 80

HTTPSサーバー

HTTPSの場合、証明書が必要になるので、通称オレオレ証明書と言われる証明書を2個をまず準備する。

# キー
openssl genrsa -out server.pem 2048
# サーバー証明書
openssl req -new -x509 -key server.pem -out ca.pem -days 1095

HTTPServerBaseHTTPRequestHandlerを使って実装。BaseHTTPRequestHandlerを継承したMyHTTPRequestHandlerを作成して、GETやPOSTを実装する。そうしないとアクセスしてもエラーになるので。

下記の場合、POSTやGETでアクセスすると、サーバー側にはURLやリクエストヘッダをダンプして、テキストをレスポンスで返すだけの簡易サーバーになる。

from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse

import ssl

class MyHTTPRequestHandler(BaseHTTPRequestHandler):
  def do_GET(self):
    print("[path] %s"%(self.path))
    parsed_path = urlparse(self.path)
    print('[parsed path] %s, [query] %s'%(parsed_path.path, parse_qs(parsed_path.query)))
    print('[headers]\r\n-----\r\n%s-----'%(self.headers))
    self.send_response(200)
    self.send_header('Content-Type', 'text/plain; charset=utf-8')
    self.end_headers()
    self.wfile.write(b'do_GET page.')

  def do_POST(self):
    print("[path] %s"%(self.path))
    parsed_path = urlparse(self.path)
    print('[parsed path] %s, [query] %s'%(parsed_path.path, parse_qs(parsed_path.query)))
    print('[headers]\r\n-----\r\n%s-----'%(self.headers))
    content_length = int(self.headers['content-length'])
    print("[content length] %d"%(content_length))
    print('[body] %s'%(self.rfile.read(content_length).decode('utf-8')))
    self.send_response(200)
    self.send_header('Content-Type', 'text/plain; charset=utf-8')
    self.end_headers()
    self.wfile.write(b'do_POST page.')

httpd = HTTPServer(('', 443), MyHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(
  httpd.socket,
  keyfile="./server.pem",
  certfile='./ca.pem',
  server_side=True)
httpd.serve_forever()