やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

ローカルHTTPSサーバを立てる(Python + openssl)

 Webアプリ動作確認用。

成果物

動作要件

概要

 HTTPSサーバを立てるスクリプトを書いた。

 JavaScriptfetch()など一部のAPIHTTPSサーバ上でしか動作しないものがある。その動作確認デバッグ用にHTTPSサーバを立てる必要がある。

 また、SVGスプライトを外部参照する時もHTTPSサーバ上でしか動作しない。他にもES Moduleを使う時や、CORS制約など、様々な場面でHTTPSサーバ環境が必要になる。

 そこでHTTPSサーバを作るスクリプトを書いた。実行するだけでサーバを立ててくれる。

手順

  1. Codeをダウンロードする
  2. server.shを実行する

 上記は以下シェルコマンドで実行できる。

git clone https://github.com/ytyaru/Https.Server.Python.OpenSsl.20250330110350
cd Https.Server.Python.OpenSsl.20250330110350/docs
./server.sh
  1. ブラウザが起動する
    1. しなければ自分で起動する
    2. URL欄にhttps://localhost/を入力する
  2. ブラウザによっては警告が出るので解除する(以下Chromium 92の場合)
    1. 詳細設定ボタンを押す
    2. localhost にアクセスする(安全ではありません)リンクをクリックする
  3. HTTPSサーバが起動し結果表示される
  4. サーバを終了させるには起動させた端末上でCtrl+Cキー押下する

 サーバは一度に一つだけ起動できる。複数立ち上げようとするとバグるのでちゃんと終了させること。

ソースコード

 HTTPSサーバ作成コードは以下二ファイル。

  • run_server.py
  • server.sh

run_server.py

import ssl
from http.server import HTTPServer, SimpleHTTPRequestHandler

PORT = 443
CERTFILE = "./localhost.pem"

Handler = SimpleHTTPRequestHandler

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(CERTFILE)

with HTTPServer(("", PORT), Handler) as httpd:
    print("serving at address", httpd.server_address, "using cert file", CERTFILE)
    httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
    httpd.serve_forever()

server.sh

#!/usr/bin/env bash
set -Ceu
#---------------------------------------------------------------------------
# HTTPローカルサーバを起動する
# https://www.lifewithpython.com/2021/03/python-https-server.html
#---------------------------------------------------------------------------
Run() {
    THIS="$(realpath "${BASH_SOURCE:-0}")"; HERE="$(dirname "$THIS")"; PARENT="$(dirname "$HERE")"; THIS_NAME="$(basename "$THIS")"; APP_ROOT="$PARENT";
    cd "$HERE"
    PEM=localhost.pem
    SERVER=run_server.py
    makePem() {
        openssl req -x509 -new -days 365 -nodes \
          -keyout $PEM \
          -out localhost.pem \
          -subj "/CN=localhost"
    }
    Http() {
        PORT=8000
        URL="http://0.0.0.0:$PORT/"
        chromium-browser $URL
        python3 -m http.server $PORT
    }
    Https() {
        [ ! -f "./$PEM" ] && makePem || :
        URL="https://localhost/"
        chromium-browser $URL
        sudo python3 $SERVER
    }
    Https
}
Run "$@"