概要
nimのPure実装されたasynchttpserverモジュールで遊んでみようとしたら、コアライブラリにパッチ入れることになった
まずはコード
サーバーのサンプルコードを動かしながら、Requestオブジェクトに何が入っているかを確認しようとしたのですが、ヘッダーをダンプしようとしたら、ヘッダーのキー名を取得できるapiが見つからず・・・
ないなら作ってしまえということで、httpcore.nimにパッチとして以下のコードを追加し、nimcacheをクリアして再コンパイル。
パッチソース
${nim_dir}/lib/pure/httpcore.nim
proc keys*(headers: HttpHeaders): seq[string] =
## Returns headers key
var ret:seq[string] = @[]
for key in headers.table.keys:
ret.add(key)
return ret
]#
サンプル
httpserver_test.nim
import asynchttpserver, asyncdispatch
import sequtils
import strutils
# サーバー作成
var server = newAsyncHttpServer()
# 処理ハンドラ
proc cb(req: Request) {.async.} =
echo "Headers = " , $req.headers.keys() # !! このkeys()を追加した
echo "Protocol = " , req.protocol
echo "Url = " , $req.url
echo "HttpMethod = " , req.reqMethod
echo "HostName = " , req.hostname
echo "Body = " , req.body
await req.respond(Http200, "Hello World")
# ずっと待つ
waitFor server.serve(Port(8080), cb)
curlコマンドで、POSTを実行する
$ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"user":{"first_name":"firstname","last_name":"lastname","email":"email@email.com","password":"app123","password_confirmation":"app123"}}' http://localhost:8080/api/1/users
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/1/users HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.1
> Accept: application/json
> Content-type: application/json
> Content-Length: 137
>
* upload completely sent off: 137 out of 137 bytes
< HTTP/1.1 200 OK
< Content-Length: 11
<
* Connection #0 to host localhost left intact
Hello World
nim側の表示
Headers = @[content-length, user-agent, accept, content-type, host]
Protocol = (orig: HTTP/1.1, major: 1, minor: 1)
Url = (scheme: , username: , password: , hostname: , port: , path: /api/1/users, query: , anchor: , opaque: false)
HttpMethod = POST
HostName = 127.0.0.1
Body = {"user":{"first_name":"firstname","last_name":"lastname","email":"email@email.com","password":"app123","password_confirmation":"app123"}}
本来の目的には届かなかったけど・・・
あ、ライブラリのソースも修正できちゃうのね・・という驚きでした