本を更新しました: 「HTMLファイルを配信できるようにする」
本を更新しました
チャプター「HTMLファイルを配信できるようにする」 を更新しました。
続きを読みたい方は、ぜひBookの「いいね」か「筆者フォロー」をお願いします ;-)
以下、書籍の内容の抜粋です。
リクエストを解釈し、指定されたHTMLファイルを返せるようにする
前章までで、まずはHTTPのフォーマットでレスポンスを返せるサーバーを作ることができました。
しかし、ブラウザから送られてきたリクエストを解釈するような処理は一切実装していないため、どんなリクエストが来てもボディはいつも It works!
を返しています。
これではあんまりなので、あらかじめプログラムのソースコードとは別にHTMLファイルを用意しておき、リクエストのpathで指定されたファイルをレスポンスボディとして返せるようにしていきましょう。
所謂、静的ファイル配信と呼ばれる機能です。
サーバーのソースコードなどはサーバを通じて公開する必要はありませんので、 サーバーを通じて公開したいファイルはstudy/static/
というディレクトリに入れる ことにして、
例)リクエストのpathが/index.html
=> study/static/index.html
の内容がレスポンスボディとして返される
といった具合です。
ソースコード
他にくだくだと説明することもありませんので、いきなりソースコードにいってみましょう。
あらかじめ用意したHTMLファイルをレスポンスボディとして返せるように改良したものがこちらです。
ソースコードも長くなってきましたので、今回からソースコード全体は転載しないことにします。
各章、Githubにソースコード全体がアップロードされていますので、そちらをご参照ください。
study/webserver.py
また、プログラムが正常に動いているか確認するにはHTMLファイルを別途用意する必要があるので、そちらも作成しておきます。
study
ディレクトリ直下にstatic
ディレクトリを新しく作成し、その中にindex.html
を作成します。
せっかくなので、Apacheのパクりではない内容に変えておきました。皆さんの好きな内容にしていただいて構いません。
ただし、ファイル名を変えてしまうと本書の説明通りでは動かなくなってしまうので、ファイル名はindex.html
のままにしておいてください。
study/static/index.html
解説
10-13行目: HTMLファイルを置くディレクトリの定義
で、HTMLファイルを置くディレクトリ(STATIC_ROOT
と呼ぶことにしています)を定義しています。
# 実行ファイルのあるディレクトリ
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 静的配信するファイルを置くディレクトリ
STATIC_ROOT = os.path.join(BASE_DIR, "static")
pythonでファイルパスを扱いなれてない方は読みづらいかもしれませんが、
-
BASE_DIR
:study
ディレクトリの絶対パス -
STATIC_ROOT
:study/static
ディレクトリの絶対パス
が格納されています。
43-61行目: ファイルからレスポンスボディを生成する
こちらがメインです。
HTTPリクエストをパース(分解)して、pathの情報を抜き出しています。
その後、pathをもとにファイルを読み込み、レスポンスボディを生成しています。
# リクエスト全体を
# 1. リクエストライン(1行目)
# 2. リクエストヘッダー(2行目〜空行)
# 3. リクエストボディ(空行〜)
# にパースする
request_line, remain = request.split(b"\r\n", maxsplit=1)
request_header, request_body = remain.split(b"\r\n\r\n", maxsplit=1)
# リクエストラインをパースする
method, path, http_version = request_line.decode().split(" ")
# pathの先頭の/を削除し、相対パスにしておく
relative_path = path.lstrip("/")
# ファイルのpathを取得
static_file_path = os.path.join(self.STATIC_ROOT, relative_path)
# ファイルからレスポンスボディを生成
with open(static_file_path, "rb") as f:
response_body = f.read()
pathを取得したあとSTATIC_ROOT
と結合してstatic_file_path
を取得するのですが、その前に先頭の/
を削除していることに注意してください。
これは、pythonのos.path.join(base, path)
の仕様として、第2引数path
に/
で始まる絶対パスを与えると第一引数base
を無視してしまうためです。
動かしてみる
やりたいことがわかっていれば、ソースコードは難しいものではないと思いますので、早速動かしてみましょう。
続きはBookで!
Author And Source
この問題について(本を更新しました: 「HTMLファイルを配信できるようにする」), 我々は、より多くの情報をここで見つけました https://zenn.dev/bigen1925/articles/publish-delivery-static-html著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol