diff options
-rw-r--r-- | lib/rainbows.rb | 3 | ||||
-rw-r--r-- | lib/rainbows/base.rb | 4 | ||||
-rw-r--r-- | lib/rainbows/event_machine.rb | 4 | ||||
-rw-r--r-- | lib/rainbows/fiber/body.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/fiber/rev.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/http_response.rb | 48 | ||||
-rw-r--r-- | lib/rainbows/response.rb | 44 | ||||
-rw-r--r-- | lib/rainbows/response/body.rb (renamed from lib/rainbows/http_response/body.rb) | 2 | ||||
-rw-r--r-- | lib/rainbows/rev/client.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/rev/core.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/rev_fiber_spawn.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/writer_thread_pool.rb | 2 | ||||
-rw-r--r-- | lib/rainbows/writer_thread_spawn.rb | 4 | ||||
-rw-r--r-- | t/cramp/rainsocket.ru | 26 | ||||
-rwxr-xr-x | t/t0501-cramp-rainsocket.sh | 38 |
15 files changed, 130 insertions, 55 deletions
diff --git a/lib/rainbows.rb b/lib/rainbows.rb index 7bc9a92..4e9578b 100644 --- a/lib/rainbows.rb +++ b/lib/rainbows.rb @@ -33,7 +33,7 @@ module Rainbows require 'rainbows/const' require 'rainbows/http_server' - require 'rainbows/http_response' + require 'rainbows/response' require 'rainbows/base' require 'rainbows/tee_input' autoload :Sendfile, 'rainbows/sendfile' @@ -127,4 +127,5 @@ module Rainbows autoload :Fiber, 'rainbows/fiber' # core class autoload :ByteSlice, 'rainbows/byte_slice' autoload :StreamFile, 'rainbows/stream_file' + autoload :HttpResponse, 'rainbows/http_response' # deprecated end diff --git a/lib/rainbows/base.rb b/lib/rainbows/base.rb index cd719d2..a619b00 100644 --- a/lib/rainbows/base.rb +++ b/lib/rainbows/base.rb @@ -10,7 +10,7 @@ module Rainbows::Base # :stopdoc: include Rainbows::Const - include Rainbows::HttpResponse + include Rainbows::Response # shortcuts... G = Rainbows::G @@ -21,7 +21,7 @@ module Rainbows::Base # this method is called by all current concurrency models def init_worker_process(worker) super(worker) - Rainbows::HttpResponse.setup(self.class) + Rainbows::Response.setup(self.class) Rainbows::MaxBody.setup G.tmp = worker.tmp diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb index 0ad604e..0404493 100644 --- a/lib/rainbows/event_machine.rb +++ b/lib/rainbows/event_machine.rb @@ -50,7 +50,7 @@ module Rainbows class Client < EM::Connection include Rainbows::EvCore - include Rainbows::HttpResponse + include Rainbows::Response G = Rainbows::G def initialize(io) @@ -227,7 +227,7 @@ module Rainbows end def init_worker_process(worker) - Rainbows::HttpResponse.setup(Rainbows::EventMachine::Client) + Rainbows::Response.setup(Rainbows::EventMachine::Client) super end diff --git a/lib/rainbows/fiber/body.rb b/lib/rainbows/fiber/body.rb index b77e310..3de45ee 100644 --- a/lib/rainbows/fiber/body.rb +++ b/lib/rainbows/fiber/body.rb @@ -1,7 +1,7 @@ # -*- encoding: binary -*- # non-portable body handling for Fiber-based concurrency goes here # this module is required and included in worker processes only -# this is meant to be included _after_ Rainbows::HttpResponse::Body +# this is meant to be included _after_ Rainbows::Response::Body module Rainbows::Fiber::Body # :nodoc: # TODO non-blocking splice(2) under Linux diff --git a/lib/rainbows/fiber/rev.rb b/lib/rainbows/fiber/rev.rb index 2e8f076..a1ffe33 100644 --- a/lib/rainbows/fiber/rev.rb +++ b/lib/rainbows/fiber/rev.rb @@ -52,7 +52,7 @@ module Rainbows::Fiber include Unicorn include Rainbows include Rainbows::Const - include Rainbows::HttpResponse + include Rainbows::Response FIO = Rainbows::Fiber::IO def to_io diff --git a/lib/rainbows/http_response.rb b/lib/rainbows/http_response.rb index 677b5a7..cf17aa1 100644 --- a/lib/rainbows/http_response.rb +++ b/lib/rainbows/http_response.rb @@ -1,44 +1,10 @@ # -*- encoding: binary -*- -require 'time' # for Time#httpdate - -# :stopdoc: -module Rainbows::HttpResponse - - CODES = Unicorn::HttpResponse::CODES - - def response_header(response, out) - status, headers = response - status = CODES[status.to_i] || status - - headers.each do |key, value| - next if %r{\A(?:X-Rainbows-|Connection\z|Date\z|Status\z)}i =~ key - if value =~ /\n/ - # avoiding blank, key-only cookies with /\n+/ - out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" }) - else - out << "#{key}: #{value}\r\n" - end - end - - "HTTP/1.1 #{status}\r\n" \ - "Date: #{Time.now.httpdate}\r\n" \ - "Status: #{status}\r\n" \ - "#{out.join('')}\r\n" - end - - def write_header(socket, response, out) - out and socket.write(response_header(response, out)) - end - - def write_response(socket, response, out) - write_header(socket, response, out) - write_body(socket, response[2]) - end - - # called after forking - def self.setup(klass) - require('rainbows/http_response/body') and - klass.__send__(:include, Rainbows::HttpResponse::Body) +# deprecated, use Rainbows::Response instead +# Cramp 0.11 relies on this +# :enddoc: +class Rainbows::HttpResponse + class << self + include Rainbows::Response + alias write write_response end end -# :startdoc: diff --git a/lib/rainbows/response.rb b/lib/rainbows/response.rb new file mode 100644 index 0000000..8d131b0 --- /dev/null +++ b/lib/rainbows/response.rb @@ -0,0 +1,44 @@ +# -*- encoding: binary -*- +require 'time' # for Time#httpdate + +# :stopdoc: +module Rainbows::Response + + CODES = Unicorn::HttpResponse::CODES + + def response_header(response, out) + status, headers = response + status = CODES[status.to_i] || status + + headers.each do |key, value| + next if %r{\A(?:X-Rainbows-|Connection\z|Date\z|Status\z)}i =~ key + if value =~ /\n/ + # avoiding blank, key-only cookies with /\n+/ + out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" }) + else + out << "#{key}: #{value}\r\n" + end + end + + "HTTP/1.1 #{status}\r\n" \ + "Date: #{Time.now.httpdate}\r\n" \ + "Status: #{status}\r\n" \ + "#{out.join('')}\r\n" + end + + def write_header(socket, response, out) + out and socket.write(response_header(response, out)) + end + + def write_response(socket, response, out) + write_header(socket, response, out) + write_body(socket, response[2]) + end + + # called after forking + def self.setup(klass) + require('rainbows/response/body') and + klass.__send__(:include, Rainbows::Response::Body) + end +end +# :startdoc: diff --git a/lib/rainbows/http_response/body.rb b/lib/rainbows/response/body.rb index 2ce09da..8d8ec27 100644 --- a/lib/rainbows/http_response/body.rb +++ b/lib/rainbows/response/body.rb @@ -26,7 +26,7 @@ # `- write_body_file # `- write_body_stream # -module Rainbows::HttpResponse::Body # :nodoc: +module Rainbows::Response::Body # :nodoc: ALIASES = {} # to_io is not part of the Rack spec, but make an exception here diff --git a/lib/rainbows/rev/client.rb b/lib/rainbows/rev/client.rb index bc8d7fa..91947b6 100644 --- a/lib/rainbows/rev/client.rb +++ b/lib/rainbows/rev/client.rb @@ -6,7 +6,7 @@ module Rainbows class Client < ::Rev::IO include Rainbows::ByteSlice include Rainbows::EvCore - include Rainbows::HttpResponse + include Rainbows::Response G = Rainbows::G HH = Rack::Utils::HeaderHash diff --git a/lib/rainbows/rev/core.rb b/lib/rainbows/rev/core.rb index 2488cf2..4668cce 100644 --- a/lib/rainbows/rev/core.rb +++ b/lib/rainbows/rev/core.rb @@ -22,7 +22,7 @@ module Rainbows # for connections and doesn't die until the parent dies (or is # given a INT, QUIT, or TERM signal) def worker_loop(worker) - Rainbows::HttpResponse.setup(Rainbows::Rev::Client) + Rainbows::Response.setup(Rainbows::Rev::Client) require 'rainbows/rev/sendfile' Rainbows::Rev::Client.__send__(:include, Rainbows::Rev::Sendfile) init_worker_process(worker) diff --git a/lib/rainbows/rev_fiber_spawn.rb b/lib/rainbows/rev_fiber_spawn.rb index 4d64e39..e9ea1db 100644 --- a/lib/rainbows/rev_fiber_spawn.rb +++ b/lib/rainbows/rev_fiber_spawn.rb @@ -16,7 +16,7 @@ module Rainbows include Fiber::Rev def worker_loop(worker) - Rainbows::HttpResponse.setup(Rainbows::Fiber::Rev::Server) + Rainbows::Response.setup(Rainbows::Fiber::Rev::Server) init_worker_process(worker) Server.const_set(:MAX, @worker_connections) Rainbows::Fiber::Base.setup(Rainbows::Fiber::Rev::Server, nil) diff --git a/lib/rainbows/writer_thread_pool.rb b/lib/rainbows/writer_thread_pool.rb index a2ef1ba..84b750b 100644 --- a/lib/rainbows/writer_thread_pool.rb +++ b/lib/rainbows/writer_thread_pool.rb @@ -61,7 +61,7 @@ module Rainbows end def worker_loop(worker) - Rainbows::HttpResponse.setup(self.class) + Rainbows::Response.setup(self.class) self.class.__send__(:alias_method, :sync_write_body, :write_body) self.class.__send__(:include, Response) diff --git a/lib/rainbows/writer_thread_spawn.rb b/lib/rainbows/writer_thread_spawn.rb index 9e793fc..b9bbad2 100644 --- a/lib/rainbows/writer_thread_spawn.rb +++ b/lib/rainbows/writer_thread_spawn.rb @@ -28,7 +28,7 @@ module Rainbows # used to wrap a BasicSocket to use with +q+ for all writes # this is compatible with IO.select class MySocket < Struct.new(:to_io, :q, :thr) - include Rainbows::HttpResponse + include Rainbows::Response def readpartial(size, buf = "") to_io.readpartial(size, buf) @@ -100,7 +100,7 @@ module Rainbows def worker_loop(worker) MySocket.const_set(:MAX, worker_connections) - Rainbows::HttpResponse.setup(MySocket) + Rainbows::Response.setup(MySocket) super(worker) # accept loop from Unicorn CUR.delete_if do |t,q| q << nil diff --git a/t/cramp/rainsocket.ru b/t/cramp/rainsocket.ru new file mode 100644 index 0000000..0d26f70 --- /dev/null +++ b/t/cramp/rainsocket.ru @@ -0,0 +1,26 @@ +# based on examples/rainsocket.ru git://github.com/lifo/cramp +# Rack::Lint does not like async + EM stuff, so disable it: +#\ -E deployment +require 'cramp/controller' + +Cramp::Controller::Websocket.backend = :rainbows + +class WelcomeController < Cramp::Controller::Websocket + periodic_timer :send_hello_world, :every => 2 + on_data :received_data + + def received_data(data) + if data =~ /fuck/ + render "You cant say fuck in here" + finish + else + render "Got your #{data}" + end + end + + def send_hello_world + render "Hello from the Server!\n" + end +end + +run WelcomeController diff --git a/t/t0501-cramp-rainsocket.sh b/t/t0501-cramp-rainsocket.sh new file mode 100755 index 0000000..6e3aea4 --- /dev/null +++ b/t/t0501-cramp-rainsocket.sh @@ -0,0 +1,38 @@ +#!/bin/sh +. ./test-lib.sh +case $model in +EventMachine) ;; +*) + t_info "skipping $T since it's not compatible with $model" + exit 0 + ;; +esac +require_check cramp Cramp::VERSION + +t_plan 4 "WebSocket monkey patch validity test for Cramp" + +CONFIG_RU=cramp/rainsocket.ru + +t_begin "setup and start" && { + rainbows_setup + rtmpfiles curl_err + + # Like the rest of the EM/async stuff, it's not Rack::Lint compatible + rainbows -E deployment -D $CONFIG_RU -c $unicorn_config + rainbows_wait_start +} + +t_begin "wait for server to say hello to us" && { + ok=$((curl --no-buffer -sS http://$listen/ || :) | \ + awk '/Hello from the Server/ { print "ok"; exit 0 }') + + test x"$ok" = xok +} + +t_begin "termination signal sent" && { + kill $rainbows_pid +} + +t_begin "no errors in stderr" && check_stderr + +t_done |