この記事は?
ネタです!
Go言語とHTTPサーバーの作りを学ぶためにGoでステータスコード240 Exotic!
を返すシンプルなHTTPサーバーを作ってみました!
Goで作ったので名前はHiromiです🎤
ソースコードはこちら🔥
きっかけ
アドベントカレンダーのネタを考えていたら、@todokrさんからネタをもらいパクらせていただきました。(アドベントカレンダーには間に合わなかったけど。。)Swiftで書かれた「Taylor」というナイスな名前のHTTPサーバーがあったので、 Goで書かれた「Hiromi」があってもいいのではないか。リクエストのAccept-Languageがjaの場合、「2億6000万 Exotic」というステータスコードを返しちゃうようなやつ。https://t.co/kpo3Uvzg04
— Shunsuke Tadokoro (@todokr) 2018年9月28日
注意事項
ネタで作ったHTTPサーバーなので、セキュリティなどはあまり考慮できていません。
(ないとは思うけど)この実装を使用して発生して起きた問題には作者は一切責任を負いません。
仕様
-
localhost:5163
でHTTPリクエストを受け取り、HTTPレスポンスを返す - 対応するHTTPメソッドは
GET
のみ - リクエストはブロックしない(マルチスレッド)
- Keep-Aliveしない
- HTTP Cacheしない
- Accept-Languageが
ja
の場合、ステータスコード200 OK
が240 Exotic!
になる
郷ひろみについて
郷 ひろみ(ごう ひろみ、1955年10月18日 - )は、日本の男性歌手、俳優、タレントで新御三家の1人。本名は原武 裕美(はらたけ ひろみ)。血液型A型、身長178cm (Wikipediaより)
みなさんご存知ですよね!
2億4千万の瞳について
「2億4千万の瞳 -エキゾチック・ジャパン-」(におくよんせんまんのひとみ エキゾチック・ジャパン)は、郷ひろみの楽曲で、50枚目のシングル。1984年2月25日発売。
歌詞はこちらから🎧
メイン処理
メインの処理では大まかに以下のことを行なっています。
思っていたよりやることは少なくシンプルになりました。
- ソケットを作成
- ↑で作ったソケットでクライアントからの接続を待つ
- クライアントからのリクエストを読み込む
- パスがRootの場合は読み込むファイルを指定する
- ファイルを読み込む
- レスポンスのステータスコードを作成する
- ファイルの拡張子に合うContent-typeを設定する
- レスポンスを作成する
- レスポンスをクライアントに返却する
- コネクションを閉じる
func main() {
endpoint := strings.Join([]string{Host, Port}, ":")
listener, err := net.Listen("tcp", endpoint) // ソケット作成
if err != nil {
panic(err)
}
fmt.Printf("Server is running at %s\n", endpoint)
for {
conn, err := listener.Accept() // クライアントからの接続を待つ
if err != nil {
panic(err)
}
go func() {
request := parseRequest(conn) // クライアントからのリクエストを読み込む
filePath := convertPath(DocumentRoot + request.URL.Path) // パスがRootの場合は読み込むファイルを指定する
file := readFileFromUrlPath(filePath) // ファイルを読み込む
status := createStatus(filePath, request.Header.Get("Accept-Language")) // レスポンスのステータスコードを作成する
contentType, _ := contentTypeMap[path.Ext(filePath)] // ファイルの拡張子に合うContent-typeを設定する
response := createResponse(status, contentType, string(file)) // レスポンスを作成する
fmt.Fprint(conn, response) // レスポンスをクライアントに返却する
conn.Close() // コネクションを閉じる
}()
}
}
リクエストを送ってみる
サーバーを起動させた後、Chromeからlocalhost:5163
にリクエストを送ってみると以下のようなレスポンスが返ります。
HTTP/1.1 240 Exotic!
Server: Hiromi
Date: Tue, 25 Dec 2018 23:10:16 JST
Connection: close
Content-type: text/html
Accept-Language
がja-JP
じゃない場合はこうなります。
HTTP/1.1 200 OK
Server: Hiromi
Date: Tue, 25 Dec 2018 23:13:45 JST
Connection: close
Content-type: text/html
やりたかったけど断念したこと
-
ステータスコードは
2400000000(2億4千万) Exotic!
を返したかったが、RFCの仕様ではステータスコードは3桁である必要があったので、泣く泣く断念。ちなみに2400000000(2億4千万) Exotic!
を設定すると桁が溢れるからかChromeなどのブラウザでは2400000000(2億4千万)
を表示してくれませんでした😩 -
郷ひろみの写真を表示したかったけど権利の関係で断念😓
最後に
作ったものは結構なネタですが、HTTPサーバーを自作すると普段HTTP通信でどのようなことが行われているか理解できます。
シンプルなHTTPサーバーであれば処理自体もそこまで複雑ではないので、新しい言語の勉強にも使えるので一石二鳥です!
参考資料
簡単なHTTPサーバーを作る
todokr/simple-http-server
新しいプログラミング言語の学び方 HTTPサーバーを作って学ぶ Java, Scala, Clojure
GoでたたくTCPソケット(前編)
Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門
izqui/Taylor