1 # -*- encoding: binary -*-
6 # TODO: remove redundant names
7 Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
8 class Unicorn::HttpParser
10 # default parameters we merge into the request env for Rack handlers
12 "rack.errors" => $stderr,
13 "rack.multiprocess" => true,
14 "rack.multithread" => false,
15 "rack.run_once" => false,
16 "rack.version" => [1, 2],
17 "rack.hijack?" => true,
20 # this is not in the Rack spec, but some apps may rely on it
21 "SERVER_SOFTWARE" => "Unicorn #{Unicorn::Const::UNICORN_VERSION}"
24 RACK_HIJACK = "rack.hijack".freeze
25 RACK_HIJACK_IO = "rack.hijack_io".freeze
26 NULL_IO = StringIO.new("")
29 # A frozen format for this is about 15% faster
30 # Drop these frozen strings when Ruby 2.2 becomes more prevalent,
31 # 2.2+ optimizes hash assignments when used with literal string keys
32 REMOTE_ADDR = 'REMOTE_ADDR'.freeze
33 RACK_INPUT = 'rack.input'.freeze
34 UNICORN_SOCKET = 'unicorn.socket'.freeze
35 HTTP_RESPONSE_START = [ 'HTTP', '/1.1 ']
36 @@input_class = Unicorn::TeeInput
37 @@check_client_connection = false
43 def self.input_class=(klass)
47 def self.check_client_connection
48 @@check_client_connection
51 def self.check_client_connection=(bool)
52 @@check_client_connection = bool
57 # Does the majority of the IO processing. It has been written in
58 # Ruby using about 8 different IO processing strategies.
60 # It is currently carefully constructed to make sure that it gets
61 # the best possible performance for the common case: GET requests
62 # that are fully complete after a single read(2)
64 # Anyone who thinks they can make it faster is more than welcome to
67 # returns an environment hash suitable for Rack if successful
68 # This does minimal exception trapping and it is up to the caller
69 # to handle any socket errors (e.g. user aborted upload).
74 # From http://www.ietf.org/rfc/rfc3875:
75 # "Script authors should be aware that the REMOTE_ADDR and
76 # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
77 # may not identify the ultimate source of the request. They
78 # identify the client for the immediate request to the server;
79 # that client may be a proxy, gateway, or other intermediary
80 # acting on behalf of the actual source client."
81 e[REMOTE_ADDR] = socket.kgio_addr
83 # short circuit the common case with small GET requests first
84 socket.kgio_read!(16384, buf)
86 # Parser is not done, queue up more data to read and continue parsing
87 # an Exception thrown from the parser will throw us out of the loop
88 false until add_parse(socket.kgio_read!(16384))
91 # detect if the socket is valid by writing a partial response:
92 if @@check_client_connection && headers?
93 self.response_start_sent = true
94 HTTP_RESPONSE_START.each { |c| socket.write(c) }
97 e[RACK_INPUT] = 0 == content_length ?
98 NULL_IO : @@input_class.new(socket, self)
100 # for Rack hijacking in Rack 1.5 and later
101 e[UNICORN_SOCKET] = socket
102 e[RACK_HIJACK] = self
107 # for rack.hijack, we respond to this method so no extra allocation
110 env[RACK_HIJACK_IO] = env[UNICORN_SOCKET]
114 env.include?(RACK_HIJACK_IO)