rainbows.git  about / heads / tags
Unicorn for sleepy apps and slow clients
blob ac09d6c8e424e03eef97b8254aa0d2b1a401d805 1745 bytes (raw)
$ git show v0.97.0:lib/rainbows/response.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
# -*- encoding: binary -*-
# :enddoc:
require 'time' # for Time#httpdate

module Rainbows::Response
  autoload :Body, 'rainbows/response/body'
  autoload :Range, 'rainbows/response/range'

  CODES = Unicorn::HttpResponse::CODES
  CRLF = "\r\n"

  # freeze headers we may set as hash keys for a small speedup
  CONNECTION = "Connection".freeze
  CLOSE = "close"
  KEEP_ALIVE = "keep-alive"
  HH = Rack::Utils::HeaderHash

  def response_header(status, headers)
    status = CODES[status.to_i] || status
    rv = "HTTP/1.1 #{status}\r\n" \
         "Date: #{Time.now.httpdate}\r\n" \
         "Status: #{status}\r\n"
    headers.each do |key, value|
      next if %r{\A(?:X-Rainbows-|Date\z|Status\z)}i =~ key
      if value =~ /\n/
        # avoiding blank, key-only cookies with /\n+/
        rv << value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" }.join('')
      else
        rv << "#{key}: #{value}\r\n"
      end
    end
    rv << CRLF
  end

  # called after forking
  def self.setup(klass)
    Rainbows::G.kato == 0 and KEEP_ALIVE.replace(CLOSE)
    range_class = body_class = klass
    case Rainbows::Const::RACK_DEFAULTS['rainbows.model']
    when :WriterThreadSpawn
      body_class = Rainbows::WriterThreadSpawn::MySocket
      range_class = Rainbows::HttpServer
    when :EventMachine, :NeverBlock
      range_class = nil # :<
    end
    return if body_class.included_modules.include?(Body)
    body_class.__send__(:include, Body)
    sf = IO.respond_to?(:copy_stream) || IO.method_defined?(:sendfile_nonblock)
    if range_class
      range_class.__send__(:include, sf ? Range : NoRange)
    end
  end

  module NoRange
    # dummy method if we can't send range responses
    def make_range!(env, status, headers)
    end
  end
end

git clone https://yhbt.net/rainbows.git