ラズパイでgcc使ってHTTPサーバを作る

botman_green Pythonとかラズパイ

Raspbian-10

はじめに

今回作るやつは色々セキュリティホールがあるらしいので絶対に公開しないでください!あくまでローカル用です。

この本が読み終わったのでその集大成としてラズパイで HTTP サーバを作ってみました(Linux も C 言語もほぼ知らないので細かい部分はよくわかってないです。。。)。

ふつうのLinuxプログラミング 第2版 Linuxの仕組みから学べるgccプログラミングの王道

新品価格
¥2,722から
(2021/3/29 21:10時点)

必要な知識ざっくりまとめ

必要そうな知識のざっくりまとめです。
gcc やオプションに関しては前回の記事をどうぞ。

シグナル

シグナルは、ユーザ(端末)やカーネルがプロセス(動作中のプログラム)に何かを通知する目的で使われるやつです(Ctrl + C で停止するのもシグナルのおかげ)。

プロセスでシグナルを捕捉してシグナルを受けたときの処理を記述する(停止するとか)。

ソケット

ネットワーク通信と言っても結局扱うのはストリーム(バイト列の通り道)。ソケットとはストリームを接続できる口のこと。

サーバプロセス

サーバ側では接続を待っているプロセス(サーバプロセス)があり、サーバ(ホスト)とサーバプロセスを特定するのが IP アドレスとポート番号(IP アドレスでネットワーク上のマシンを特定してポート番号でサーバプロセスを特定する感じ。。。たぶん)。

デーモン

デーモンは制御端末を持たないプロセスのこと。通常のプロセスの場合、起動ユーザがログアウトするとプロセスも終了してしまうのでサーバの場合は困る。

HTTPリクエスト

リクエストの構成は下記(今回のやつはリクエストラインだけを読む)。

  • リクエストライン
    メソッドなど
  • HTTP ヘッダ
    付加情報
  • \r\n
    ヘッダの終わり
  • エンティティボディ
    POST とかで使う

ex.

HTTPレスポンス

レスポンスの構成は下記。

  • ステータスライン
    ステータスコードなど
  • HTTP ヘッダ
    付加情報
  • \r\n
    ヘッダの終わり
  • エンティティボディ
    HTML など

ex.

参考

  • 第12章 プロセスにかかわる API
  • 第13章 シグナルにかかわる API
  • 第15章 ネットワークプログラミングの基礎
  • 第16章 HTTP サーバを作る

HTTPサーバ概要

今回作るのは単純な GET リクエストで受けた指定の HTML ファイルを表示するだけのやつです。
下記のようにコマンドで起動してブラウザで http://pi@raspberrypi.local:8082/index.html と入力すると index.html を表示できるようにします。

  • 面倒なエラーが起きたら即 exit(1)
  • HTTP1.0 のみサポート
  • 設定ファイルは使わない(全部引数で渡す)
  • GET リクエストのみ対応
  • レスポンスは HTML のみ
    めんどくさいのですべて text/html 指定にする。
  • IPv4 のみ対応(色々めんどくさいらしいので)
  • ソケット接続
  • 接続を並列で扱う
    リクエスト処理中にも他のリクエストを受け付けないといけないので並列処理する。
  • デーモン化
    これでプロセス起動者がログアウトしてもプロセスが停止しない。
  • syslog を使ったロギング
    エラー時に syslog へ記録する(デーモン化してるので標準エラー出力が使えない)。
  • デバッグモード
    標準入出力使ってエラーを表示する。
  • ポートの指定
    --port=n のオプションで指定する。

参考

  • 第16章 HTTP サーバを作る
  • 第17章 HTTP サーバを本格化する

ソース

全体の処理の流れは下記。

  1. オプション解析
  2. デバッグモードでなければデーモン化
  3. ソケット作成して接続待機
  4. リクエストの文字列を解析してリクエストラインを取得
  5. リクエストラインを解析してメソッド、パス、プロトコルを取得
  6. 引数のパスとリクエストを解析したパスからファイルへのパス作成
  7. ファイルを読み込んでレスポンス出力

make コマンド使いたかったのでファイルを5つに分けてみました(コードは基本的に第17章参考に書いてます)。

  • common.h
  • main.c
  • server.c
  • request.c
  • response.c

common.h

main.c

server.c

request.c

response.c

make

フォルダ構成は下記。

Makefile はこんな感じ。

make コマンド実行で httpd ファイルが生成されます。

実行

下記コマンドを実行!(--debug なしの場合デーモン化の影響でカレントディレクトリがルートになるので渡すパスはフルパスにする必要があります。pwd するとパスがとれるよ)

ブラウザでこちら http://pi@raspberrypi.local:8082/index.html にアクセスすると下記のように表示されます。

pi

おわりに

冒頭でもいいましたが色々セキュリティホールがあるのでこのまま公開するのはやめましょう!!
(リクエストで ../ とか指定すると指定ディレクトリ外のファイルをみれたり、CPU、メモリをこのプロセスが占有してしまう可能性があるなど色々問題があるらしいです。)

色々わからない部分もありますがとりあえず HTTP サーバができました。

デーモン化したプロセスってどうやって止めるんだろう??わからないので毎回下記のようにプロセス検索して kill してます。。。

コメント

タイトルとURLをコピーしました