summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-07-16 19:21:39 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-07-16 19:21:39 +0900
commit9c56fe143399986061478f3167bcc13bececb73a (patch)
tree29c1f28a6303b05b1eae0a2df94eb526a6223244 /examples
parent5a8bc21d4056c95e98e7c176571728d4beaeddc7 (diff)
downloadplum-9c56fe143399986061478f3167bcc13bececb73a.tar.gz
examples: add simple server script
Diffstat (limited to 'examples')
-rw-r--r--examples/static_server.rb125
1 files changed, 125 insertions, 0 deletions
diff --git a/examples/static_server.rb b/examples/static_server.rb
new file mode 100644
index 0000000..1705870
--- /dev/null
+++ b/examples/static_server.rb
@@ -0,0 +1,125 @@
+$LOAD_PATH << File.expand_path("../../lib", __FILE__)
+require "plum"
+require "openssl"
+require "socket"
+require "cgi"
+
+begin
+ require "sslkeylog/autotrace" # for debug
+rescue
+end
+
+def log(con, stream, s)
+ prefix = "[%02x;%02x] " % [con, stream]
+ if s.is_a?(Enumerable)
+ puts s.map {|a| prefix + a.to_s }.join("\n")
+ else
+ puts prefix + s.to_s
+ end
+end
+
+ctx = OpenSSL::SSL::SSLContext.new
+ctx.alpn_select_cb = -> protocols {
+ raise "Client does not support HTTP/2." unless protocols.include?("h2")
+ "h2"
+}
+ctx.cert = OpenSSL::X509::Certificate.new File.read(".crt.local")
+ctx.key = OpenSSL::PKey::RSA.new File.read(".key.local")
+tcp_server = TCPServer.new("0.0.0.0", 40443)
+ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx)
+
+loop do
+ begin
+ sock = ssl_server.accept
+ id = sock.io.fileno
+ puts "#{id}: accept!"
+ rescue => e
+ puts e
+ next
+ end
+
+ plum = Plum::Server.new(sock)
+
+ plum.on_frame = proc do |frame|
+ log(id, frame.stream_id, "recv: #{frame.inspect}")
+ end
+
+ plum.on_send_frame = proc do |frame|
+ log(id, frame.stream_id, "send: #{frame.inspect}")
+ end
+
+ plum.on_stream = proc do |stream|
+ headers = data = nil
+
+ stream.on_open = proc do
+ headers = nil
+ data = ""
+ end
+
+ stream.on_headers = proc do |headers_|
+ log(id, stream.id, headers_.map {|name, value| "#{name}: #{value}" })
+ headers = headers_
+ end
+
+ stream.on_data = proc do |data_|
+ log(id, stream.id, data_)
+ data << data_
+ end
+
+ stream.on_complete = proc do
+ case [headers[":method"], headers[":path"]]
+ when ["GET", "/"]
+ body = "Hello World! <a href=/abc.html>ABC</a> <a href=/fgsd>Not found</a>"
+ body << <<-EOF
+ <form action=post.page method=post>
+ <input type=text name=key value=default_value>
+ <input type=submit>
+ </form>
+ EOF
+ stream.send_headers({
+ ":status": "200",
+ "server": "plum",
+ "content-type": "text/html",
+ "content-length": body.size
+ })
+ stream.send_body(body, [:end_stream])
+ when ["GET", "/abc.html"]
+ body = "ABC! <a href=/>Back to top page</a>"
+ stream.send_headers({
+ ":status": "200",
+ "server": "plum",
+ "content-type": "text/html",
+ "content-length": body.size
+ })
+ stream.send_body(body, [:end_stream])
+ when ["POST", "/post.page"]
+ body = "Posted value is: #{CGI.unescape(data).gsub("<", "&lt;").gsub(">", "&gt;")}<br> <a href=/>Back to top page</a>"
+ stream.send_headers({
+ ":status": "200",
+ "server": "plum",
+ "content-type": "text/html",
+ "content-length": body.size
+ })
+ stream.send_body(body, [:end_stream])
+ else
+ body = "Page not found! <a href=/>Back to top page</a>"
+ stream.send_headers({
+ ":status": "404",
+ "server": "plum",
+ "content-type": "text/html",
+ "content-length": body.size
+ })
+ stream.send_body(body, [:end_stream])
+ end
+ end
+ end
+
+ Thread.new {
+ begin
+ plum.start
+ rescue
+ puts $!
+ puts $!.backtrace
+ end
+ }
+end