年末にSPDYやHTTP2の勉強がてら、mrubyでSPDYやHTTP2通信可能なmrbgemを作りました。
これで、mrubyを組み込んだアプリケーションやデバイスからSPDY・HTTP2通信ができるようになって未来が広がりますね。
現状はクライアントのGETのみができます。これで、例えばmod_mrubyやngx_mrubyに組み込んで、あるURLにアクセスした場合はバックエンドでSPDYやHTTP2な通信をすることもできますね。
サンプル
SPDYやHTTP2通信をするためにはRubyで以下のように書きます。
SPDY通信
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
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
以下のようなレスポンスが得られます。
#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"
}
{
: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"
}
HTTP2通信
コードは以下になります。
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
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
レスポンスは以下のようにハッシュで得られます。
#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
{
: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
まとめ
このように簡単にmrubyでSPDY・HTTP2でGETが簡単にできるようになりました。是非遊んでみて下さい。今後やりたいこととしては、
- 通信中のコールバック関数をRubyで書けるようにする
- サーバ・プロキシ実装
- クライアント・サーバ・プロキシの細かい機能を追加
- httpパーサやsslをmrubyのクラスに分離
を考えています。また、pull-requestも大歓迎であります。
0 Comments.