年末にSPDYやHTTP2の勉強がてら、mrubyでSPDYやHTTP2通信可能なmrbgemを作りました。
これで、mrubyを組み込んだアプリケーションやデバイスからSPDY・HTTP2通信ができるようになって未来が広がりますね。
現状はクライアントのGETのみができます。これで、例えばmod_mrubyやngx_mrubyに組み込んで、あるURLにアクセスした場合はバックエンドでSPDYやHTTP2な通信をすることもできますね。
サンプル
SPDYやHTTP2通信をするためにはRubyで以下のように書きます。
SPDY通信
[program lang=’ruby’ escaped=’true’]
r = SPDY::Client.get 'https://www.google.co.jp/' p r p r.body p r.body_length p r.spdy_version p r.stream_id p r.syn_reply p r.syn_stream
[/program]
以下のようなレスポンスが得られます。
[program lang=’ruby’ escaped=’true’]
#r { :syn_reply=>{ "x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "expires"=>"-1", "p3p"=>"CP=¥"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.¥"", "server"=>"gws", "set-cookie"=>"; expires=Sun, 29-Jun-2014 17:16:55 GMT; path=/; domain=.google.co.jp; HttpOnly", ":version"=>"HTTP/1.1", "alternate-protocol"=>"443:quic", "cache-control"=>"private, max-age=0", "content-type"=>"text/html; charset=Shift_JIS", "date"=>"Sat, 28 Dec 2013 17:16:55 GMT", ":status"=>"200 OK" }, :recieve_bytes=>953.0, :body=>"<html> - (snip) - </html>", :body_length=>953, :spdy_proto_version=>4, :stream_id=>1, :syn_stream=>{ ":method"=>"GET", ":path"=>"/", ":scheme"=>"https", ":version"=>"HTTP/1.1", ":host"=>"www.google.co.jp", "accept"=>"*/*", "user-agent"=>"mruby-spdy/0.0.1" } } #r.body "<html> - (snip) - </html>" #r.body_length 953 #r.spdy_version 4 #r.syn_stream { ":method"=>"GET", ":path"=>"/", ":scheme"=>"https", ":version"=>"HTTP/1.1", ":host"=>"www.google.co.jp", "accept"=>"*/*", "user-agent"=>"mruby-spdy/0.0.1" } #r.syn_reply { "x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "expires"=>"-1", "p3p"=>"CP=¥"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.¥"", "server"=>"gws", "set-cookie"=>"; expires=Sun, 29-Jun-2014 17:16:55 GMT; path=/; domain=.google.co.jp; HttpOnly", ":version"=>"HTTP/1.1", "alternate-protocol"=>"443:quic", "cache-control"=>"private, max-age=0", "content-type"=>"text/html; charset=Shift_JIS", "date"=>"Sat, 28 Dec 2013 17:16:55 GMT", ":status"=>"200 OK" }
[/program]
HTTP2通信
コードは以下になります。
[program lang=’ruby’ escaped=’true’]
r = HTTP2::Client.get 'https://106.186.112.116/' p r p r.body p r.request_headers p r.response_headers p r.status p r.body p r.body_length p r.stream_id
[/program]
レスポンスは以下のようにハッシュで得られます。
[program lang=’ruby’ escaped=’true’]
#r { :body=>"---- snip ----", :body_length=>1400, :stream_id=>1, :frame_send_header_goway=>true, :recieve_bytes=>1400.0, :request_headers=>{ ":path"=>"/", ":scheme"=>"https", "user-agent"=>"mruby-http2/0.0.1", ":authority"=>"106.186.112.116", ":method"=>"GET", "accept"=>"*/*" }, :response_headers=>{ "last-modified"=>"Wed, 18 Dec 2013 15:12:23 GMT", "etag"=>"¥"52b1bb57-2450¥"", "x-varnish"=>"340171131", "content-length"=>"9296", "date"=>"Tue, 31 Dec 2013 11:04:13 GMT", "age"=>"0", "accept-ranges"=>"bytes", "content-type"=>"text/html", ":status"=>"200", "server"=>"nginx/1.4.1 (Ubuntu)", "via"=>"1.1 varnish, 1.1 nghttpx" } } #r,status 200 #r.request_headers { ":path"=>"/", ":scheme"=>"https", "user-agent"=>"mruby-http2/0.0.1", ":authority"=>"106.186.112.116", ":method"=>"GET", "accept"=>"*/*" } #r.response_headers { "last-modified"=>"Wed, 18 Dec 2013 15:12:23 GMT", "etag"=>"¥"52b1bb57-2450¥"", "x-varnish"=>"340171131", "content-length"=>"9296", "date"=>"Tue, 31 Dec 2013 11:04:13 GMT", "age"=>"0", "accept-ranges"=>"bytes", "content-type"=>"text/html", ":status"=>"200", "server"=>"nginx/1.4.1 (Ubuntu)", "via"=>"1.1 varnish, 1.1 nghttpx" } #r.body
[/program]
まとめ
このように簡単にmrubyでSPDY・HTTP2でGETが簡単にできるようになりました。是非遊んでみて下さい。今後やりたいこととしては、
- 通信中のコールバック関数をRubyで書けるようにする
- サーバ・プロキシ実装
- クライアント・サーバ・プロキシの細かい機能を追加
- httpパーサやsslをmrubyのクラスに分離
を考えています。また、pull-requestも大歓迎であります。