* lib/cgi/core.rb: performance improvement.
From CGIAlt http://cgialt.rubyforge.org/ * test/cgi/test_cgi_header.rb: exception class fixed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19386 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8b31af74b7
commit
49f69c3f2e
@ -1,3 +1,10 @@
|
|||||||
|
Tue Sep 16 22:23:24 2008 Takeyuki Fujioka <xibbar@ruby-lang.org>
|
||||||
|
|
||||||
|
* lib/cgi/core.rb: performance improvement.
|
||||||
|
From CGIAlt http://cgialt.rubyforge.org/
|
||||||
|
|
||||||
|
* test/cgi/test_cgi_header.rb: exception class fixed.
|
||||||
|
|
||||||
Tue Sep 16 22:21:33 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Sep 16 22:21:33 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (rb_str_concat): fix rdoc. (codepoint is integer)
|
* string.c (rb_str_concat): fix rdoc. (codepoint is integer)
|
||||||
|
223
lib/cgi/core.rb
223
lib/cgi/core.rb
@ -1,6 +1,6 @@
|
|||||||
class CGI
|
class CGI
|
||||||
|
|
||||||
# :stopdoc:
|
$CGI_ENV = ENV # for FCGI support
|
||||||
|
|
||||||
# String for carriage return
|
# String for carriage return
|
||||||
CR = "\015"
|
CR = "\015"
|
||||||
@ -139,128 +139,131 @@ class CGI
|
|||||||
# "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates"
|
# "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates"
|
||||||
#
|
#
|
||||||
# This method does not perform charset conversion.
|
# This method does not perform charset conversion.
|
||||||
#
|
def header(options='text/html')
|
||||||
def header(options = "text/html")
|
if options.is_a?(String)
|
||||||
|
content_type = options
|
||||||
buf = ""
|
buf = _header_for_string(content_type)
|
||||||
|
elsif options.is_a?(Hash)
|
||||||
case options
|
if options.size == 1 && options.has_key?('type')
|
||||||
when String
|
content_type = options['type']
|
||||||
options = { "type" => options }
|
buf = _header_for_string(content_type)
|
||||||
when Hash
|
else
|
||||||
options = options.dup
|
buf = _header_for_hash(options.dup)
|
||||||
end
|
|
||||||
|
|
||||||
unless options.has_key?("type")
|
|
||||||
options["type"] = "text/html"
|
|
||||||
end
|
|
||||||
|
|
||||||
if options.has_key?("charset")
|
|
||||||
options["type"] += "; charset=" + options.delete("charset")
|
|
||||||
end
|
|
||||||
|
|
||||||
options.delete("nph") if defined?(MOD_RUBY)
|
|
||||||
if options.delete("nph") or
|
|
||||||
(/IIS\/(\d+)/.match(env_table['SERVER_SOFTWARE']) and $1.to_i < 5)
|
|
||||||
buf += (env_table["SERVER_PROTOCOL"] or "HTTP/1.0") + " " +
|
|
||||||
(HTTP_STATUS[options["status"]] or options["status"] or "200 OK") +
|
|
||||||
EOL +
|
|
||||||
"Date: " + CGI::rfc1123_date(Time.now) + EOL
|
|
||||||
|
|
||||||
unless options.has_key?("server")
|
|
||||||
options["server"] = (env_table['SERVER_SOFTWARE'] or "")
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
unless options.has_key?("connection")
|
raise ArgumentError.new("expected String or Hash but got #{options.class}")
|
||||||
options["connection"] = "close"
|
|
||||||
end
|
|
||||||
|
|
||||||
options.delete("status")
|
|
||||||
end
|
end
|
||||||
|
if defined?(MOD_RUBY)
|
||||||
if options.has_key?("status")
|
_header_for_modruby(buf)
|
||||||
buf += "Status: " +
|
return ''
|
||||||
(HTTP_STATUS[options["status"]] or options["status"]) + EOL
|
else
|
||||||
options.delete("status")
|
buf << EOL # empty line of separator
|
||||||
|
return buf
|
||||||
end
|
end
|
||||||
|
end # header()
|
||||||
|
|
||||||
if options.has_key?("server")
|
def _header_for_string(content_type) #:nodoc:
|
||||||
buf += "Server: " + options.delete("server") + EOL
|
buf = ''
|
||||||
|
if nph?()
|
||||||
|
buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||||
|
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||||
|
buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
|
||||||
|
buf << "Connection: close#{EOL}"
|
||||||
end
|
end
|
||||||
|
buf << "Content-Type: #{content_type}#{EOL}"
|
||||||
if options.has_key?("connection")
|
if @output_cookies
|
||||||
buf += "Connection: " + options.delete("connection") + EOL
|
@output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||||
end
|
end
|
||||||
|
return buf
|
||||||
|
end # _header_for_string
|
||||||
|
private :_header_for_string
|
||||||
|
|
||||||
buf += "Content-Type: " + options.delete("type") + EOL
|
def _header_for_hash(options) #:nodoc:
|
||||||
|
buf = ''
|
||||||
if options.has_key?("length")
|
## add charset to option['type']
|
||||||
buf += "Content-Length: " + options.delete("length").to_s + EOL
|
options['type'] ||= 'text/html'
|
||||||
|
charset = options.delete('charset')
|
||||||
|
options['type'] += "; charset=#{charset}" if charset
|
||||||
|
## NPH
|
||||||
|
options.delete('nph') if defined?(MOD_RUBY)
|
||||||
|
if options.delete('nph') || nph?()
|
||||||
|
protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
||||||
|
status = options.delete('status')
|
||||||
|
status = HTTP_STATUS[status] || status || '200 OK'
|
||||||
|
buf << "#{protocol} #{status}#{EOL}"
|
||||||
|
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||||
|
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
|
||||||
|
options['connection'] ||= 'close'
|
||||||
end
|
end
|
||||||
|
## common headers
|
||||||
if options.has_key?("language")
|
status = options.delete('status')
|
||||||
buf += "Content-Language: " + options.delete("language") + EOL
|
buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
|
||||||
end
|
server = options.delete('server')
|
||||||
|
buf << "Server: #{server}#{EOL}" if server
|
||||||
if options.has_key?("expires")
|
connection = options.delete('connection')
|
||||||
buf += "Expires: " + CGI::rfc1123_date( options.delete("expires") ) + EOL
|
buf << "Connection: #{connection}#{EOL}" if connection
|
||||||
end
|
type = options.delete('type')
|
||||||
|
buf << "Content-Type: #{type}#{EOL}" #if type
|
||||||
if options.has_key?("cookie")
|
length = options.delete('length')
|
||||||
if options["cookie"].kind_of?(String) or
|
buf << "Content-Length: #{length}#{EOL}" if length
|
||||||
options["cookie"].kind_of?(Cookie)
|
language = options.delete('language')
|
||||||
buf += "Set-Cookie: " + options.delete("cookie").to_s + EOL
|
buf << "Content-Language: #{language}#{EOL}" if language
|
||||||
elsif options["cookie"].kind_of?(Array)
|
expires = options.delete('expires')
|
||||||
options.delete("cookie").each{|cookie|
|
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
|
||||||
buf += "Set-Cookie: " + cookie.to_s + EOL
|
## cookie
|
||||||
}
|
if cookie = options.delete('cookie')
|
||||||
elsif options["cookie"].kind_of?(Hash)
|
case cookie
|
||||||
options.delete("cookie").each_value{|cookie|
|
when String, Cookie
|
||||||
buf += "Set-Cookie: " + cookie.to_s + EOL
|
buf << "Set-Cookie: #{cookie}#{EOL}"
|
||||||
}
|
when Array
|
||||||
|
arr = cookie
|
||||||
|
arr.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||||
|
when Hash
|
||||||
|
hash = cookie
|
||||||
|
hash.each {|name, cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if @output_cookies
|
if @output_cookies
|
||||||
for cookie in @output_cookies
|
@output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||||
buf += "Set-Cookie: " + cookie.to_s + EOL
|
end
|
||||||
|
## other headers
|
||||||
|
options.each do |key, value|
|
||||||
|
buf << "#{key}: #{value}#{EOL}"
|
||||||
|
end
|
||||||
|
return buf
|
||||||
|
end # _header_for_hash
|
||||||
|
private :_header_for_hash
|
||||||
|
|
||||||
|
def nph? #:nodoc:
|
||||||
|
return /IIS\/(\d+)/.match($CGI_ENV['SERVER_SOFTWARE']) && $1.to_i < 5
|
||||||
|
end
|
||||||
|
|
||||||
|
def _header_for_modruby(buf) #:nodoc:
|
||||||
|
request = Apache::request
|
||||||
|
buf.scan(/([^:]+): (.+)#{EOL}/o) do |name, value|
|
||||||
|
warn sprintf("name:%s value:%s\n", name, value) if $DEBUG
|
||||||
|
case name
|
||||||
|
when 'Set-Cookie'
|
||||||
|
request.headers_out.add(name, value)
|
||||||
|
when /^status$/i
|
||||||
|
request.status_line = value
|
||||||
|
request.status = value.to_i
|
||||||
|
when /^content-type$/i
|
||||||
|
request.content_type = value
|
||||||
|
when /^content-encoding$/i
|
||||||
|
request.content_encoding = value
|
||||||
|
when /^location$/i
|
||||||
|
request.status = 302 if request.status == 200
|
||||||
|
request.headers_out[name] = value
|
||||||
|
else
|
||||||
|
request.headers_out[name] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
request.send_http_header
|
||||||
options.each{|key, value|
|
return ''
|
||||||
buf += key + ": " + value.to_s + EOL
|
end
|
||||||
}
|
private :_header_for_modruby
|
||||||
|
#
|
||||||
if defined?(MOD_RUBY)
|
|
||||||
table = Apache::request.headers_out
|
|
||||||
buf.scan(/([^:]+): (.+)#{EOL}/){ |name, value|
|
|
||||||
warn sprintf("name:%s value:%s\n", name, value) if $DEBUG
|
|
||||||
case name
|
|
||||||
when 'Set-Cookie'
|
|
||||||
table.add(name, value)
|
|
||||||
when /^status$/i
|
|
||||||
Apache::request.status_line = value
|
|
||||||
Apache::request.status = value.to_i
|
|
||||||
when /^content-type$/i
|
|
||||||
Apache::request.content_type = value
|
|
||||||
when /^content-encoding$/i
|
|
||||||
Apache::request.content_encoding = value
|
|
||||||
when /^location$/i
|
|
||||||
if Apache::request.status == 200
|
|
||||||
Apache::request.status = 302
|
|
||||||
end
|
|
||||||
Apache::request.headers_out[name] = value
|
|
||||||
else
|
|
||||||
Apache::request.headers_out[name] = value
|
|
||||||
end
|
|
||||||
}
|
|
||||||
Apache::request.send_http_header
|
|
||||||
''
|
|
||||||
else
|
|
||||||
buf + EOL
|
|
||||||
end
|
|
||||||
|
|
||||||
end # header()
|
|
||||||
|
|
||||||
|
|
||||||
# Print an HTTP header and body to $DEFAULT_OUTPUT ($>)
|
# Print an HTTP header and body to $DEFAULT_OUTPUT ($>)
|
||||||
#
|
#
|
||||||
|
@ -71,7 +71,7 @@ class CGIHeaderTest < Test::Unit::TestCase
|
|||||||
def test_cgi_header_argerr
|
def test_cgi_header_argerr
|
||||||
cgi = CGI.new
|
cgi = CGI.new
|
||||||
#expected = NoMethodError # must be ArgumentError
|
#expected = NoMethodError # must be ArgumentError
|
||||||
if defined?(CGI::RELEASE)
|
if RUBY_VERSION>="1.9.0"
|
||||||
expected = ArgumentError # for CGIAlt
|
expected = ArgumentError # for CGIAlt
|
||||||
else
|
else
|
||||||
expected = NoMethodError # for Ruby1.8
|
expected = NoMethodError # for Ruby1.8
|
||||||
|
Loading…
x
Reference in New Issue
Block a user