Class: Unicorn::CGIWrapper
- Inherits:
-
CGI
- Object
- CGI
- Unicorn::CGIWrapper
- Defined in:
- lib/unicorn/cgi_wrapper.rb
Overview
The beginning of a complete wrapper around Unicorn’s internal HTTP processing system but maintaining the original Ruby CGI module. Use this only as a crutch to get existing CGI based systems working. It should handle everything, but please notify us if you see special warnings. This work is still very alpha so we need testers to help work out the various corner cases.
Constant Summary collapse
- NPH =
these are stripped out of any keys passed to CGIWrapper.header function
'nph'.freeze
- CONNECTION =
Completely ignored, Unicorn outputs the date regardless
'connection'.freeze
- CHARSET =
Completely ignored. Why is CGI doing this?
'charset'.freeze
- COOKIE =
this gets appended to Content-Type
'cookie'.freeze
- STATUS =
maps (Hash,Array,String) to “Set-Cookie” headers
'status'.freeze
- Status =
stored as @status
'Status'.freeze
- SET_COOKIE =
some of these are common strings, but this is the only module using them and the reason they’re not in Unicorn::Const
'Set-Cookie'.freeze
- CONTENT_TYPE =
'Content-Type'.freeze
- CONTENT_LENGTH =
this is NOT Const::CONTENT_LENGTH
'Content-Length'.freeze
- RACK_INPUT =
'rack.input'.freeze
- RACK_ERRORS =
'rack.errors'.freeze
- HEADER_MAP =
this maps CGI header names to HTTP header names
{ 'status' => Status, 'type' => CONTENT_TYPE, 'server' => 'Server'.freeze, 'language' => 'Content-Language'.freeze, 'expires' => 'Expires'.freeze, 'length' => CONTENT_LENGTH, }
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#env_table ⇒ Object
readonly
Returns the value of attribute env_table.
Instance Method Summary collapse
-
#header(options = "text/html") ⇒ Object
The header is typically called to send back the header.
-
#initialize(rack_env, *args) ⇒ CGIWrapper
constructor
Takes an a Rackable environment, plus any additional CGI.new arguments These are used internally to create a wrapper around the real CGI while maintaining Rack/Unicorn’s view of the world.
-
#out(options = "text/html") ⇒ Object
The dumb thing is people can call header or this or both and in any order.
-
#rack_response ⇒ Object
finalizes the response in a way Rack applications would expect.
-
#stdinput ⇒ Object
Used to wrap the normal stdinput variable used inside CGI.
-
#stdoutput ⇒ Object
return a pointer to the StringIO body since it’s STDOUT-like.
Constructor Details
#initialize(rack_env, *args) ⇒ CGIWrapper
Takes an a Rackable environment, plus any additional CGI.new arguments These are used internally to create a wrapper around the real CGI while maintaining Rack/Unicorn’s view of the world. This this will NOT deal well with large responses that take up a lot of memory, but neither does the CGI nor the original CGIWrapper from Mongrel…
57 58 59 60 61 62 63 64 |
# File 'lib/unicorn/cgi_wrapper.rb', line 57 def initialize(rack_env, *args) @env_table = rack_env @status = nil @head = {} @headv = Hash.new { |hash,key| hash[key] = [] } @body = StringIO.new("") super(*args) end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
23 24 25 |
# File 'lib/unicorn/cgi_wrapper.rb', line 23 def body @body end |
#env_table ⇒ Object (readonly)
Returns the value of attribute env_table.
22 23 24 |
# File 'lib/unicorn/cgi_wrapper.rb', line 22 def env_table @env_table end |
Instance Method Details
#header(options = "text/html") ⇒ Object
The header is typically called to send back the header. In our case we collect it into a hash for later usage. This can be called multiple times to set different cookies.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/unicorn/cgi_wrapper.rb', line 83 def header( = "text/html") # if they pass in a string then just write the Content-Type if String === @head[CONTENT_TYPE] ||= else HEADER_MAP.each_pair do |from, to| from = .delete(from) or next @head[to] = from.to_s end @head[CONTENT_TYPE] ||= "text/html" if charset = .delete(CHARSET) @head[CONTENT_TYPE] << "; charset=#{charset}" end # lots of ways to set cookies if = .delete(COOKIE) = @headv[SET_COOKIE] case when Array .each { |c| << c.to_s } when Hash .each_value { |c| << c.to_s } else << .to_s end end @status ||= .delete(STATUS) # all lower-case # drop the keys we don't want anymore .delete(NPH) .delete(CONNECTION) # finally, set the rest of the headers as-is, allowing duplicates .each_pair { |k,v| @headv[k] << v } end # doing this fakes out the cgi library to think the headers are empty # we then do the real headers in the out function call later "" end |
#out(options = "text/html") ⇒ Object
The dumb thing is people can call header or this or both and in any order. So, we just reuse header and then finalize the HttpResponse the right way. This will have no effect if called the second time if the first “outputted” anything.
129 130 131 132 133 |
# File 'lib/unicorn/cgi_wrapper.rb', line 129 def out( = "text/html") header() @body.size == 0 or return @body << yield if block_given? end |
#rack_response ⇒ Object
finalizes the response in a way Rack applications would expect
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/unicorn/cgi_wrapper.rb', line 67 def rack_response # @head[CONTENT_LENGTH] ||= @body.size @headv[SET_COOKIE].concat(@output_cookies) if @output_cookies @headv.each_pair do |key,value| @head[key] ||= value.join("\n") unless value.empty? end # Capitalized "Status:", with human-readable status code (e.g. "200 OK") @status ||= @head.delete(Status) [ @status || 500, @head, [ @body.string ] ] end |
#stdinput ⇒ Object
Used to wrap the normal stdinput variable used inside CGI.
136 137 138 |
# File 'lib/unicorn/cgi_wrapper.rb', line 136 def stdinput @env_table[RACK_INPUT] end |
#stdoutput ⇒ Object
return a pointer to the StringIO body since it’s STDOUT-like
141 142 143 |
# File 'lib/unicorn/cgi_wrapper.rb', line 141 def stdoutput @body end |