Adding websocket support :)

This commit is contained in:
Sdogruyol 2015-12-15 23:11:21 +02:00
parent 0cc66cc9de
commit 06ced7790b
4 changed files with 83 additions and 0 deletions

View file

@ -0,0 +1,61 @@
require "./spec_helper"
describe "Kemal::WebsocketHandler" do
it "doesn't match on wrong route" do
handler = Kemal::WebsocketHandler.new "/" { }
headers = HTTP::Headers{
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": "dGhlIHNhbXBsZSBub25jZQ==",
}
request = HTTP::Request.new("GET", "/asd", headers)
response = handler.call request
response.status_code.should eq(404)
end
it "matches on given route" do
handler = Kemal::WebsocketHandler.new "/" { }
headers = HTTP::Headers{
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": "dGhlIHNhbXBsZSBub25jZQ==",
}
request = HTTP::Request.new("GET", "/", headers)
response = handler.call request
response.status_code.should eq(101)
response.headers["Upgrade"].should eq("websocket")
response.headers["Connection"].should eq("Upgrade")
response.headers["Sec-WebSocket-Accept"].should eq("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
response.upgrade_handler.should_not be_nil
end
it "doesn't mix http and ws on same route" do
kemal = Kemal::Handler.new
kemal.add_route "GET", "/" do |env|
"hello #{env.params["message"]}"
end
ws_handler = Kemal::WebsocketHandler.new "/" { }
headers = HTTP::Headers{
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": "dGhlIHNhbXBsZSBub25jZQ==",
}
# HTTP Request
request = HTTP::Request.new("GET", "/?message=world")
response = kemal.call(request)
response.body.should eq("hello world")
# Websocket request
request = HTTP::Request.new("GET", "/", headers)
response = ws_handler.call request
response.status_code.should eq(101)
response.headers["Upgrade"].should eq("websocket")
response.headers["Connection"].should eq("Upgrade")
response.headers["Sec-WebSocket-Accept"].should eq("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
response.upgrade_handler.should_not be_nil
end
end

View file

@ -4,6 +4,7 @@ module Kemal
class Config class Config
INSTANCE = Config.new INSTANCE = Config.new
HANDLERS = [] of HTTP::Handler HANDLERS = [] of HTTP::Handler
WS_HANDLERS = [] of HTTP::Handler
property ssl, port, env, workers, public_folder property ssl, port, env, workers, public_folder
def initialize def initialize
@ -26,6 +27,10 @@ module Kemal
HANDLERS << handler HANDLERS << handler
end end
def add_ws_handler(handler : HTTP::WebSocketHandler)
HANDLERS << handler
end
# Reads configuration from config.yml. Currently it only supports the public_folder # Reads configuration from config.yml. Currently it only supports the public_folder
# option. # option.
# config.yml # config.yml

View file

@ -5,3 +5,7 @@ HTTP_METHODS = %w(get post put patch delete)
Kemal::Handler::INSTANCE.add_route({{method}}.upcase, path, &block) Kemal::Handler::INSTANCE.add_route({{method}}.upcase, path, &block)
end end
{% end %} {% end %}
def ws(path, &block : HTTP::WebSocketHandler::WebSocketSession -> _)
Kemal::WebsocketHandler.new path, &block
end

View file

@ -0,0 +1,13 @@
class Kemal::WebsocketHandler < HTTP::WebSocketHandler
getter handler
def initialize(@path, &@proc : WebSocketSession ->)
@handler = @proc
Kemal.config.add_ws_handler self
end
def call(request)
return call_next(request) unless request.path.not_nil! == @path
super
end
end