diff options
Diffstat (limited to 'lib/cgi.rb')
| -rw-r--r-- | lib/cgi.rb | 2100 |
1 files changed, 6 insertions, 2094 deletions
diff --git a/lib/cgi.rb b/lib/cgi.rb index 7d27cecd67..bb306d2e06 100644 --- a/lib/cgi.rb +++ b/lib/cgi.rb @@ -1,2095 +1,7 @@ -=begin +# frozen_string_literal: true -== NAME - -cgi.rb - cgi support library - -Version 2.1.2 - -Copyright (C) 2000 Network Applied Communication Laboratory, Inc. - -Copyright (C) 2000 Information-technology Promotion Agency, Japan - -Wakou Aoyama <wakou@fsinet.or.jp> - - - -== EXAMPLE - -=== GET FORM VALUES - - require "cgi" - cgi = CGI.new - values = cgi['field_name'] # <== array of 'field_name' - # if not 'field_name' included, then return []. - fields = cgi.keys # <== array of field names - - # returns true if form has 'field_name' - cgi.has_key?('field_name') - cgi.has_key?('field_name') - cgi.include?('field_name') - - -=== GET FORM VALUES AS HASH - - require "cgi" - cgi = CGI.new - params = cgi.params - -cgi.params is a hash. - - cgi.params['new_field_name'] = ["value"] # add new param - cgi.params['field_name'] = ["new_value"] # change value - cgi.params.delete('field_name') # delete param - cgi.params.clear # delete all params - - -=== SAVE FORM VALUES TO FILE - - require "pstore" - db = PStore.new("query.db") - db.transaction do - db["params"] = cgi.params - end - - -=== RESTORE FORM VALUES FROM FILE - - require "pstore" - db = PStore.new("query.db") - db.transaction do - cgi.params = db["params"] - end - - -=== GET MULTIPART FORM VALUES - - require "cgi" - cgi = CGI.new - values = cgi['field_name'] # <== array of 'field_name' - values[0].read # <== body of values[0] - values[0].local_path # <== path to local file of values[0] - values[0].original_filename # <== original filename of values[0] - values[0].content_type # <== content_type of values[0] - -and values[0] has Tempfile class methods. -(Tempfile class object has File class methods) - - -=== GET COOKIE VALUES - - require "cgi" - cgi = CGI.new - values = cgi.cookies['name'] # <== array of 'name' - # if not 'name' included, then return []. - names = cgi.cookies.keys # <== array of cookie names - -and cgi.cookies is a hash. - - -=== GET COOKIE OBJECTS - - require "cgi" - cgi = CGI.new - for name, cookie in cgi.cookies - cookie.expires = Time.now + 30 - end - cgi.out("cookie" => cgi.cookies){"string"} - - cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... } - - require "cgi" - cgi = CGI.new - cgi.cookies['name'].expires = Time.now + 30 - cgi.out("cookie" => cgi.cookies['name']){"string"} - -and see MAKE COOKIE OBJECT. - - -=== GET ENVIRONMENT VALUE - - require "cgi" - cgi = CGI.new - value = cgi.auth_type - # ENV["AUTH_TYPE"] - -see http://www.w3.org/CGI/ - -AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO -PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST REMOTE_IDENT -REMOTE_USER REQUEST_METHOD SCRIPT_NAME SERVER_NAME SERVER_PORT -SERVER_PROTOCOL SERVER_SOFTWARE - -content_length and server_port return Integer. and the others return String. - -and HTTP_COOKIE, HTTP_COOKIE2 - - value = cgi.raw_cookie - # ENV["HTTP_COOKIE"] - value = cgi.raw_cookie2 - # ENV["HTTP_COOKIE2"] - -and other HTTP_* - - value = cgi.accept - # ENV["HTTP_ACCEPT"] - value = cgi.accept_charset - # ENV["HTTP_ACCEPT_CHARSET"] - -HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE -HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST HTTP_NEGOTIATE HTTP_PRAGMA -HTTP_REFERER HTTP_USER_AGENT - - -=== PRINT HTTP HEADER AND HTML STRING TO $DEFAULT_OUTPUT ($>) - - require "cgi" - cgi = CGI.new("html3") # add HTML generation methods - cgi.out() do - cgi.html() do - cgi.head{ cgi.title{"TITLE"} } + - cgi.body() do - cgi.form() do - cgi.textarea("get_text") + - cgi.br + - cgi.submit - end + - cgi.pre() do - CGI::escapeHTML( - "params: " + cgi.params.inspect + "\n" + - "cookies: " + cgi.cookies.inspect + "\n" + - ENV.collect() do |key, value| - key + " --> " + value + "\n" - end.join("") - ) - end - end - end - end - - # add HTML generation methods - CGI.new("html3") # html3.2 - CGI.new("html4") # html4.0 (Strict) - CGI.new("html4Tr") # html4.0 Transitional - CGI.new("html4Fr") # html4.0 Frameset - - -=end - -raise "Please, use ruby1.5.4 or later." if RUBY_VERSION < "1.5.4" - -require 'English' - -class CGI - - CR = "\015" - LF = "\012" - EOL = CR + LF - VERSION = "2.1.2" - RELEASE_DATE = "2000-12-25" - VERSION_CODE = 212 - RELEASE_CODE = 20001225 - - NEEDS_BINMODE = true if /WIN/ni === RUBY_PLATFORM - PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'} - - HTTP_STATUS = { - "OK" => "200 OK", - "PARTIAL_CONTENT" => "206 Partial Content", - "MULTIPLE_CHOICES" => "300 Multiple Choices", - "MOVED" => "301 Moved Permanently", - "REDIRECT" => "302 Found", - "NOT_MODIFIED" => "304 Not Modified", - "BAD_REQUEST" => "400 Bad Request", - "AUTH_REQUIRED" => "401 Authorization Required", - "FORBIDDEN" => "403 Forbidden", - "NOT_FOUND" => "404 Not Found", - "METHOD_NOT_ALLOWED" => "405 Method Not Allowed", - "NOT_ACCEPTABLE" => "406 Not Acceptable", - "LENGTH_REQUIRED" => "411 Length Required", - "PRECONDITION_FAILED" => "412 Rrecondition Failed", - "SERVER_ERROR" => "500 Internal Server Error", - "NOT_IMPLEMENTED" => "501 Method Not Implemented", - "BAD_GATEWAY" => "502 Bad Gateway", - "VARIANT_ALSO_VARIES" => "506 Variant Also Negotiates" - } - - RFC822_DAYS = %w[ Sun Mon Tue Wed Thu Fri Sat ] - RFC822_MONTHS = %w[ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ] - - def env_table - ENV - end - - def stdinput - $stdin - end - - def stdoutput - $DEFAULT_OUTPUT - end - - private :env_table, :stdinput, :stdoutput - -=begin -== METHODS -=end - -=begin -=== ESCAPE URL ENCODE - url_encoded_string = CGI::escape("string") -=end - def CGI::escape(string) - string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do - '%' + $1.unpack('H2' * $1.size).join('%').upcase - end.tr(' ', '+') - end - - -=begin -=== UNESCAPE URL ENCODED - string = CGI::unescape("url encoded string") -=end - def CGI::unescape(string) - string.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) do - [$1.delete('%')].pack('H*') - end - end - - -=begin -=== ESCAPE HTML &\"<> - CGI::escapeHTML("string") -=end - def CGI::escapeHTML(string) - string.gsub(/&/n, '&').gsub(/\"/n, '"').gsub(/>/n, '>').gsub(/</n, '<') - end - - -=begin -=== UNESCAPE HTML - CGI::unescapeHTML("HTML escaped string") -=end - def CGI::unescapeHTML(string) - string.gsub(/&(.*?);/n) do - match = $1.dup - case match - when /\Aamp\z/ni then '&' - when /\Aquot\z/ni then '"' - when /\Agt\z/ni then '>' - when /\Alt\z/ni then '<' - when /\A#0*(\d+)\z/n then - if Integer($1) < 256 - Integer($1).chr - else - if Integer($1) < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U) - [Integer($1)].pack("U") - else - "&##{$1};" - end - end - when /\A#x([0-9a-f]+)\z/ni then - if $1.hex < 256 - $1.hex.chr - else - if $1.hex < 65536 and ($KCODE[0] == ?u or $KCODE[0] == ?U) - [$1.hex].pack("U") - else - "&#x#{$1};" - end - end - else - "&#{match};" - end - end - end - - -=begin -=== ESCAPE ELEMENT - print CGI::escapeElement('<BR><A HREF="url"></A>', "A", "IMG") - # "<BR><A HREF="url"></A>" - - print CGI::escapeElement('<BR><A HREF="url"></A>', ["A", "IMG"]) - # "<BR><A HREF="url"></A>" -=end - def CGI::escapeElement(string, *elements) - elements = elements[0] if elements[0].kind_of?(Array) - unless elements.empty? - string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do - CGI::escapeHTML($&) - end - else - string - end - end - - -=begin -=== UNESCAPE ELEMENT - print CGI::unescapeElement( - CGI::escapeHTML('<BR><A HREF="url"></A>'), "A", "IMG") - # "<BR><A HREF="url"></A>" - - print CGI::unescapeElement( - CGI::escapeHTML('<BR><A HREF="url"></A>'), ["A", "IMG"]) - # "<BR><A HREF="url"></A>" -=end - def CGI::unescapeElement(string, *elements) - elements = elements[0] if elements[0].kind_of?(Array) - unless elements.empty? - string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/ni) do - CGI::unescapeHTML($&) - end - else - string - end - end - - -=begin -=== MAKE RFC1123 DATE STRING - CGI::rfc1123_date(Time.now) - # Sat, 1 Jan 2000 00:00:00 GMT -=end - def CGI::rfc1123_date(time) - t = time.clone.gmtime - return format("%s, %d %s %d %.2d:%.2d:%.2d GMT", - RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year, - t.hour, t.min, t.sec) - end - - -=begin -=== MAKE HTTP HEADER STRING - header - # Content-Type: text/html - - header("text/plain") - # Content-Type: text/plain - - header({"nph" => true, - "status" => "OK", # == "200 OK" - # "status" => "200 GOOD", - "server" => ENV['SERVER_SOFTWARE'], - "connection" => "close", - "type" => "text/html", - "charset" => "iso-2022-jp", - # Content-Type: text/html; charset=iso-2022-jp - "language" => "ja", - "expires" => Time.now + 30, - "cookie" => [cookie1, cookie2], - "my_header1" => "my_value" - "my_header2" => "my_value"}) - -header will not convert charset. - -status: - - "OK" --> "200 OK" - "PARTIAL_CONTENT" --> "206 Partial Content" - "MULTIPLE_CHOICES" --> "300 Multiple Choices" - "MOVED" --> "301 Moved Permanently" - "REDIRECT" --> "302 Found" - "NOT_MODIFIED" --> "304 Not Modified" - "BAD_REQUEST" --> "400 Bad Request" - "AUTH_REQUIRED" --> "401 Authorization Required" - "FORBIDDEN" --> "403 Forbidden" - "NOT_FOUND" --> "404 Not Found" - "METHOD_NOT_ALLOWED" --> "405 Method Not Allowed" - "NOT_ACCEPTABLE" --> "406 Not Acceptable" - "LENGTH_REQUIRED" --> "411 Length Required" - "PRECONDITION_FAILED" --> "412 Rrecondition Failed" - "SERVER_ERROR" --> "500 Internal Server Error" - "NOT_IMPLEMENTED" --> "501 Method Not Implemented" - "BAD_GATEWAY" --> "502 Bad Gateway" - "VARIANT_ALSO_VARIES" --> "506 Variant Also Negotiates" - -=end - def header(options = "text/html") - - buf = "" - - if options.kind_of?(String) - options = { "type" => options } - end - - unless options.has_key?("type") - options["type"] = "text/html" - end - - if options.has_key?("charset") - options["type"].concat( "; charset=" ) - options["type"].concat( options.delete("charset") ) - end - - if options.delete("nph") or (/IIS/n === env_table['SERVER_SOFTWARE']) - buf.concat( (env_table["SERVER_PROTOCOL"] or "HTTP/1.0") + " " ) - buf.concat( (HTTP_STATUS[options["status"]] or - options["status"] or - "200 OK" - ) + EOL - ) - buf.concat( - "Date: " + CGI::rfc1123_date(Time.now) + EOL - ) - - unless options.has_key?("server") - options["server"] = (env_table['SERVER_SOFTWARE'] or "") - end - - unless options.has_key?("connection") - options["connection"] = "close" - end - - options.delete("status") - end - - if options.has_key?("status") - buf.concat("Status: " + options.delete("status") + EOL) - end - - if options.has_key?("server") - buf.concat("Server: " + options.delete("server") + EOL) - end - - if options.has_key?("connection") - buf.concat("Connection: " + options.delete("connection") + EOL) - end - - buf.concat("Content-Type: " + options.delete("type") + EOL) - - if options.has_key?("length") - buf.concat("Content-Length: " + options.delete("length").to_s + EOL) - end - - if options.has_key?("language") - buf.concat("Content-Language: " + options.delete("language") + EOL) - end - - if options.has_key?("expires") - buf.concat("Expires: " + CGI::rfc1123_date( options.delete("expires") ) + EOL) - end - - if options.has_key?("cookie") - if options["cookie"].kind_of?(String) or - options["cookie"].kind_of?(Cookie) - buf.concat("Set-Cookie: " + options.delete("cookie").to_s + EOL) - elsif options["cookie"].kind_of?(Array) - options.delete("cookie").each{|cookie| - buf.concat("Set-Cookie: " + cookie.to_s + EOL) - } - elsif options["cookie"].kind_of?(Hash) - options.delete("cookie").each_value{|cookie| - buf.concat("Set-Cookie: " + cookie.to_s + EOL) - } - end - end - if @output_cookies - for cookie in @output_cookies - buf.concat("Set-Cookie: " + cookie.to_s + EOL) - end - end - - options.each{|key, value| - buf.concat(key + ": " + value + EOL) - } - - if defined?(MOD_RUBY) - buf.scan(/([^:]+): (.+)#{EOL}/n){ - Apache::request[$1] = $2 - } - Apache::request.send_http_header - '' - else - buf + EOL - end - - end # header() - - -=begin -=== PRINT HTTP HEADER AND STRING TO $DEFAULT_OUTPUT ($>) - cgi = CGI.new - cgi.out{ "string" } - # Content-Type: text/html - # Content-Length: 6 - # - # string - - cgi.out("text/plain"){ "string" } - # Content-Type: text/plain - # Content-Length: 6 - # - # string - - cgi.out({"nph" => true, - "status" => "OK", # == "200 OK" - "server" => ENV['SERVER_SOFTWARE'], - "connection" => "close", - "type" => "text/html", - "charset" => "iso-2022-jp", - # Content-Type: text/html; charset=iso-2022-jp - "language" => "ja", - "expires" => Time.now + (3600 * 24 * 30), - "cookie" => [cookie1, cookie2], - "my_header1" => "my_value", - "my_header2" => "my_value"}){ "string" } - -if "HEAD" == REQUEST_METHOD then output only HTTP header. - -if charset is "iso-2022-jp" or "euc-jp" or "shift_jis" then -convert string charset, and set language to "ja". - -=end - def out(options = "text/html") - - options = { "type" => options } if options.kind_of?(String) - content = yield - - if options.has_key?("charset") - require "nkf" - case options["charset"] - when /iso-2022-jp/ni - content = NKF::nkf('-j', content) - options["language"] = "ja" unless options.has_key?("language") - when /euc-jp/ni - content = NKF::nkf('-e', content) - options["language"] = "ja" unless options.has_key?("language") - when /shift_jis/ni - content = NKF::nkf('-s', content) - options["language"] = "ja" unless options.has_key?("language") - end - end - - options["length"] = content.length.to_s - output = stdoutput - output.binmode if defined? output.binmode - output.print header(options) - output.print content unless "HEAD" == env_table['REQUEST_METHOD'] - end - - -=begin -=== PRINT - cgi = CGI.new - cgi.print # default: cgi.print == $DEFAULT_OUTPUT.print -=end - def print(*options) - stdoutput.print(*options) - end - - -=begin -=== MAKE COOKIE OBJECT - cookie1 = CGI::Cookie::new("name", "value1", "value2", ...) - cookie1 = CGI::Cookie::new({"name" => "name", "value" => "value"}) - cookie1 = CGI::Cookie::new({'name' => 'name', - 'value' => ['value1', 'value2', ...], - 'path' => 'path', # optional - 'domain' => 'domain', # optional - 'expires' => Time.now, # optional - 'secure' => true # optional - }) - - cgi.out({"cookie" => [cookie1, cookie2]}){ "string" } - - name = cookie1.name - values = cookie1.value - path = cookie1.path - domain = cookie1.domain - expires = cookie1.expires - secure = cookie1.secure - - cookie1.name = 'name' - cookie1.value = ['value1', 'value2', ...] - cookie1.path = 'path' - cookie1.domain = 'domain' - cookie1.expires = Time.now + 30 - cookie1.secure = true -=end - require "delegate" - class Cookie < SimpleDelegator - - def initialize(name = "", *value) - options = if name.kind_of?(String) - { "name" => name, "value" => value } - else - name - end - unless options.has_key?("name") - raise ArgumentError, "`name' required" - end - - @name = options["name"] - @value = Array(options["value"]) - # simple support for IE - if options["path"] - @path = options["path"] - elsif ENV["REQUEST_URI"] - @path = ENV["REQUEST_URI"].sub(/\?.*/n,'') - if ENV["PATH_INFO"] - @path = @path[0...@path.rindex(ENV["PATH_INFO"])] - end - else - @path = (ENV["SCRIPT_NAME"] or "") - end - @domain = options["domain"] - @expires = options["expires"] - @secure = options["secure"] == true ? true : false - - super(@value) - end - - attr_accessor("name", "value", "path", "domain", "expires") - attr_reader("secure") - def secure=(val) - @secure = val if val == true or val == false - @secure - end - - def to_s - buf = "" - buf.concat(@name + '=') - - if @value.kind_of?(String) - buf.concat CGI::escape(@value) - else - buf.concat(@value.collect{|v| CGI::escape(v) }.join("&")) - end - - if @domain - buf.concat('; domain=' + @domain) - end - - if @path - buf.concat('; path=' + @path) - end - - if @expires - buf.concat('; expires=' + CGI::rfc1123_date(@expires)) - end - - if @secure == true - buf.concat('; secure') - end - - buf - end - - end # class Cookie - - -=begin -=== PARSE RAW COOKIE STRING - cookies = CGI::Cookie::parse("raw_cookie_string") - # { "name1" => cookie1, "name2" => cookie2, ... } -=end - def Cookie::parse(raw_cookie) - cookies = Hash.new([]) - return cookies unless raw_cookie - - raw_cookie.split('; ').each do |pairs| - name, values = pairs.split('=',2) - name = CGI::unescape(name) - values ||= "" - values = values.split('&').collect{|v| CGI::unescape(v) } - if cookies.has_key?(name) - cookies[name].value.push(*values) - else - cookies[name] = Cookie::new({ "name" => name, "value" => values }) - end - end - - cookies - end - - -=begin -=== PARSE QUERY STRING - params = CGI::parse("query_string") - # {"name1" => ["value1", "value2", ...], - # "name2" => ["value1", "value2", ...], ... } -=end - def CGI::parse(query) - params = Hash.new([]) - - query.split(/[&;]/n).each do |pairs| - key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) } - if params.has_key?(key) - params[key].push(value) - else - params[key] = [value] - end - end - - params - end - - - module QueryExtension - - for env in %w[ CONTENT_LENGTH SERVER_PORT ] - eval( <<-END ) - def #{env.sub(/^HTTP_/n, '').downcase} - env_table["#{env}"] && Integer(env_table["#{env}"]) - end - END - end - - for env in %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO - PATH_TRANSLATED QUERY_STRING REMOTE_ADDR REMOTE_HOST - REMOTE_IDENT REMOTE_USER REQUEST_METHOD SCRIPT_NAME - SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE - - HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING - HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_HOST - HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ] - eval( <<-END ) - def #{env.sub(/^HTTP_/n, '').downcase} - env_table["#{env}"] - end - END - end - - def raw_cookie - env_table["HTTP_COOKIE"] - end - - def raw_cookie2 - env_table["HTTP_COOKIE2"] - end - - attr_accessor("cookies") - attr("params") - def params=(hash) - @params.clear - @params.update(hash) - end - - def param(name) - @params[name].join("\0") - end - - def read_multipart(boundary, content_length) - params = Hash.new([]) - boundary = "--" + boundary - buf = "" - bufsize = 10 * 1024 - - # start multipart/form-data - stdinput.binmode - boundary_size = boundary.size + EOL.size - content_length -= boundary_size - status = stdinput.read(boundary_size) - if nil == status - raise EOFError, "no content body" - end - - require "tempfile" - - until -1 == content_length - head = nil - body = Tempfile.new("CGI") - body.binmode - - until head and (/#{boundary}(?:#{EOL}|--)/n === buf) - - if (not head) and (/#{EOL}#{EOL}/n === buf) - buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do - head = $1.dup - "" - end - next - end - - if head and ( (EOL + boundary + EOL).size < buf.size ) - body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)] - buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = "" - end - - c = if bufsize < content_length - stdinput.read(bufsize) or '' - else - stdinput.read(content_length) or '' - end - buf.concat c - content_length -= c.size - - end - - buf = buf.sub(/\A((?:.|\n)*?)(?:#{EOL})?#{boundary}(#{EOL}|--)/n) do - body.print $1 - if "--" == $2 - content_length = -1 - end - "" - end - - body.rewind - - eval <<-END - def body.local_path - #{body.path.dump} - end - END - - /Content-Disposition:.* filename="?([^\";]*)"?/ni === head - eval <<-END - def body.original_filename - #{ - filename = ($1 or "").dup - if (/Mac/ni === env_table['HTTP_USER_AGENT']) and - (/Mozilla/ni === env_table['HTTP_USER_AGENT']) and - (not /MSIE/ni === env_table['HTTP_USER_AGENT']) - CGI::unescape(filename) - else - filename - end.dump.untaint - }.taint - end - END - - /Content-Type: (.*)/ni === head - eval <<-END - def body.content_type - #{($1 or "").dump.untaint}.taint - end - END - - /Content-Disposition:.* name="?([^\";]*)"?/ni === head - name = $1.dup - - if params.has_key?(name) - params[name].push(body) - else - params[name] = [body] - end - - end - - params - end # read_multipart - private :read_multipart - - # offline mode. read name=value pairs on standard input. - def read_from_cmdline - require "shellwords" - - string = unless ARGV.empty? - ARGV.join(' ') - else - if STDIN.tty? - STDERR.print( - %|(offline mode: enter name=value pairs on standard input)\n| - ) - end - readlines.join(' ').gsub(/\n/n, '') - end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26') - - words = Shellwords.shellwords(string) - - if words.find{|x| /=/n === x } - words.join('&') - else - words.join('+') - end - end - private :read_from_cmdline - - def initialize_query() - if ("POST" == env_table['REQUEST_METHOD']) and - (%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n === - env_table['CONTENT_TYPE']) - boundary = $1.dup - @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH'])) - else - @params = CGI::parse( - case env_table['REQUEST_METHOD'] - when "GET", "HEAD" - if defined?(MOD_RUBY) - Apache::request.args or "" - else - env_table['QUERY_STRING'] or "" - end - when "POST" - stdinput.binmode - stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or '' - else - read_from_cmdline - end - ) - end - - @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE'])) - - end - private :initialize_query - - def [](*args) - @params[*args] - end - - def keys(*args) - @params.keys(*args) - end - - def has_key?(*args) - @params.has_key?(*args) - end - alias key? has_key? - alias include? has_key? - - end # QueryExtension - - -=begin -=== HTML PRETTY FORMAT - print CGI::pretty("<HTML><BODY></BODY></HTML>") - # <HTML> - # <BODY> - # </BODY> - # </HTML> - - print CGI::pretty("<HTML><BODY></BODY></HTML>", "\t") - # <HTML> - # <BODY> - # </BODY> - # </HTML> -=end - def CGI::pretty(string, shift = " ") - lines = string.gsub(/(?!\A)<(?:.|\n)*?>/n, "\n\\0").gsub(/<(?:.|\n)*?>(?!\n)/n, "\\0\n") - end_pos = 0 - while end_pos = lines.index(/^<\/(\w+)/n, end_pos) - element = $1.dup - start_pos = lines.rindex(/^\s*<#{element}/ni, end_pos) - lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/n, "\n" + shift) + "__" - end - lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/n, '\1') - end - - -=begin -== HTML ELEMENTS - - cgi = CGI.new("html3") # add HTML generation methods - cgi.element - cgi.element{ "string" } - cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" }) - cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" }){ "string" } - - # add HTML generation methods - CGI.new("html3") # html3.2 - CGI.new("html4") # html4.0 (Strict) - CGI.new("html4Tr") # html4.0 Transitional - CGI.new("html4Fr") # html4.0 Frameset - -=end - - - module TagMaker - - # - - - def nn_element_def(element) - <<-END.gsub(/element\.downcase/n, element.downcase).gsub(/element\.upcase/n, element.upcase) - "<element.upcase" + attributes.collect{|name, value| - next unless value - " " + CGI::escapeHTML(name) + - if true == value - "" - else - '="' + CGI::escapeHTML(value) + '"' - end - }.to_s + ">" + - if block_given? - yield.to_s - else - "" - end + - "</element.upcase>" - END - end - - # - O EMPTY - def nOE_element_def(element) - <<-END.gsub(/element\.downcase/n, element.downcase).gsub(/element\.upcase/n, element.upcase) - "<element.upcase" + attributes.collect{|name, value| - next unless value - " " + CGI::escapeHTML(name) + - if true == value - "" - else - '="' + CGI::escapeHTML(value) + '"' - end - }.to_s + ">" - END - end - - # O O or - O - def nO_element_def(element) - <<-END.gsub(/element\.downcase/n, element.downcase).gsub(/element\.upcase/n, element.upcase) - "<element.upcase" + attributes.collect{|name, value| - next unless value - " " + CGI::escapeHTML(name) + - if true == value - "" - else - '="' + CGI::escapeHTML(value) + '"' - end - }.to_s + ">" + - if block_given? - yield.to_s + "</element.upcase>" - else - "" - end - END - end - - end # TagMaker - - - module HtmlExtension - - -=begin -=== A ELEMENT - a("url") - # = a({ "HREF" => "url" }) -=end - def a(href = "") - attributes = if href.kind_of?(String) - { "HREF" => href } - else - href - end - if block_given? - super(attributes){ yield } - else - super(attributes) - end - end - - -=begin -=== BASE ELEMENT - base("url") - # = base({ "HREF" => "url" }) -=end - def base(href = "") - attributes = if href.kind_of?(String) - { "HREF" => href } - else - href - end - if block_given? - super(attributes){ yield } - else - super(attributes) - end - end - - -=begin -=== BLOCKQUOTE ELEMENT - blockquote("url"){ "string" } - # = blockquote({ "CITE" => "url" }){ "string" } -=end - def blockquote(cite = nil) - attributes = if cite.kind_of?(String) - { "CITE" => cite } - else - cite or "" - end - if block_given? - super(attributes){ yield } - else - super(attributes) - end - end - - -=begin -=== CAPTION ELEMENT - caption("align"){ "string" } - # = caption({ "ALIGN" => "align" }){ "string" } -=end - def caption(align = nil) - attributes = if align.kind_of?(String) - { "ALIGN" => align } - else - align or "" - end - if block_given? - super(attributes){ yield } - else - super(attributes) - end - end - - -=begin -=== CHECKBOX - checkbox("name") - # = checkbox({ "NAME" => "name" }) - - checkbox("name", "value") - # = checkbox({ "NAME" => "name", "VALUE" => "value" }) - - checkbox("name", "value", true) - # = checkbox({ "NAME" => "name", "VALUE" => "value", "CHECKED" => true }) -=end - def checkbox(name = "", value = nil, checked = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "checkbox", "NAME" => name, - "VALUE" => value, "CHECKED" => checked } - else - name["TYPE"] = "checkbox" - name - end - input(attributes) - end - - -=begin -=== CHECKBOX_GROUP - checkbox_group("name", "foo", "bar", "baz") - # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo - # <INPUT TYPE="checkbox" NAME="name" VALUE="bar">bar - # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz - - checkbox_group("name", ["foo"], ["bar", true], "baz") - # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo - # <INPUT TYPE="checkbox" SELECTED NAME="name" VALUE="bar">bar - # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz - - checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") - # <INPUT TYPE="checkbox" NAME="name" VALUE="1">Foo - # <INPUT TYPE="checkbox" SELECTED NAME="name" VALUE="2">Bar - # <INPUT TYPE="checkbox" NAME="name" VALUE="Baz">Baz - - checkbox_group({ "NAME" => "name", - "VALUES" => ["foo", "bar", "baz"] }) - - checkbox_group({ "NAME" => "name", - "VALUES" => [["foo"], ["bar", true], "baz"] }) - - checkbox_group({ "NAME" => "name", - "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) -=end - def checkbox_group(name = "", *values) - if name.kind_of?(Hash) - values = name["VALUES"] - name = name["NAME"] - end - values.collect{|value| - if value.kind_of?(String) - checkbox(name, value) + value - else - if value[value.size - 1] == true - checkbox(name, value[0], true) + - value[value.size - 2] - else - checkbox(name, value[0]) + - value[value.size - 1] - end - end - }.to_s - end - - -=begin -=== FILE_FIELD - file_field("name") - # <INPUT TYPE="file" NAME="name" SIZE="20"> - - file_field("name", 40) - # <INPUT TYPE="file" NAME="name" SIZE="40"> - - file_field("name", 40, 100) - # <INPUT TYPE="file" NAME="name" SIZE="40", MAXLENGTH="100"> - - file_field({ "NAME" => "name", "SIZE" => 40 }) - # <INPUT TYPE="file" NAME="name" SIZE="40"> -=end - def file_field(name = "", size = 20, maxlength = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "file", "NAME" => name, - "SIZE" => size.to_s } - else - name["TYPE"] = "file" - name - end - attributes["MAXLENGTH"] = maxlength.to_s if maxlength - input(attributes) - end - - -=begin -=== FORM ELEMENT - form{ "string" } - # <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">string</FORM> - - form("get"){ "string" } - # <FORM METHOD="get" ENCTYPE="application/x-www-form-urlencoded">string</FORM> - - form("get", "url"){ "string" } - # <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM> - - form({"METHOD" => "post", ENCTYPE => "enctype"}){ "string" } - # <FORM METHOD="post" ENCTYPE="enctype">string</FORM> -=end - def form(method = "post", action = nil, enctype = "application/x-www-form-urlencoded") - attributes = if method.kind_of?(String) - { "METHOD" => method, "ACTION" => action, - "ENCTYPE" => enctype } - else - unless method.has_key?("METHOD") - method["METHOD"] = method - end - unless method.has_key?("ENCTYPE") - method["ENCTYPE"] = enctype - end - method - end - if block_given? - body = yield - else - body = "" - end - if @output_hidden - hidden = @output_hidden.collect{|k,v| - "<INPUT TYPE=HIDDEN NAME=\"#{k}\" VALUE=\"#{v}\">" - }.to_s - body.concat hidden - end - super(attributes){body} - end - -=begin -=== HIDDEN FIELD - hidden("name") - # <INPUT TYPE="hidden" NAME="name"> - - hidden("name", "value") - # <INPUT TYPE="hidden" NAME="name" VALUE="value"> - - hidden({ "NAME" => "name", "VALUE" => "reset", "ID" => "foo" }) - # <INPUT TYPE="hidden" NAME="name" VALUE="value" ID="foo"> -=end - def hidden(name = "", value = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "hidden", "NAME" => name, "VALUE" => value } - else - name["TYPE"] = "hidden" - name - end - input(attributes) - end - - -=begin -=== HTML ELEMENT - - html{ "string" } - # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML>string</HTML> - - html({ "LANG" => "ja" }){ "string" } - # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML LANG="ja">string</HTML> - - html({ "DOCTYPE" => false }){ "string" } - # <HTML>string</HTML> - - html({ "DOCTYPE" => '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">' }){ "string" } - # <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><HTML>string</HTML> - - html({ "PRETTY" => " " }){ "<BODY></BODY>" } - # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> - # <HTML> - # <BODY> - # </BODY> - # </HTML> - - html({ "PRETTY" => "\t" }){ "<BODY></BODY>" } - # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> - # <HTML> - # <BODY> - # </BODY> - # </HTML> - - html("PRETTY"){ "<BODY></BODY>" } - # = html({ "PRETTY" => " " }){ "<BODY></BODY>" } - - html(if $VERBOSE then "PRETTY" end){ "HTML string" } - -=end - def html(attributes = {}) - if nil == attributes - attributes = {} - elsif "PRETTY" == attributes - attributes = { "PRETTY" => true } - end - pretty = attributes.delete("PRETTY") - pretty = " " if true == pretty - buf = "" - - if attributes.has_key?("DOCTYPE") - if attributes["DOCTYPE"] - buf.concat( attributes.delete("DOCTYPE") ) - else - attributes.delete("DOCTYPE") - end - else - buf.concat( doctype ) - end - - if block_given? - buf.concat( super(attributes){ yield } ) - else - buf.concat( super(attributes) ) - end - - if pretty - CGI::pretty(buf, pretty) - else - buf - end - - end - - -=begin -=== IMAGE_BUTTON - image_button("url") - # <INPUT TYPE="image" SRC="url"> - - image_button("url", "name", "string") - # <INPUT TYPE="image" SRC="url" NAME="name", ALT="string"> - - image_button({ "SRC" => "url", "ATL" => "strng" }) - # <INPUT TYPE="image" SRC="url" ALT="string"> -=end - def image_button(src = "", name = nil, alt = nil) - attributes = if src.kind_of?(String) - { "TYPE" => "image", "SRC" => src, "NAME" => name, - "ALT" => alt } - else - src["TYPE"] = "image" - src["SRC"] ||= "" - src - end - input(attributes) - end - - -=begin -=== IMG ELEMENT - img("src", "alt", 100, 50) - # <IMG SRC="src" ALT="alt" WIDTH="100", HEIGHT="50"> - - img({ "SRC" => "src", "ALT" => "alt", "WIDTH" => 100, "HEIGHT" => 50 }) - # <IMG SRC="src" ALT="alt" WIDTH="100", HEIGHT="50"> -=end - def img(src = "", alt = "", width = nil, height = nil) - attributes = if src.kind_of?(String) - { "SRC" => src, "ALT" => alt } - else - src - end - attributes["WIDTH"] = width.to_s if width - attributes["HEIGHT"] = height.to_s if height - super(attributes) - end - - -=begin -=== MULTIPART FORM - multipart_form{ "string" } - # <FORM METHOD="post" ENCTYPE="multipart/form-data">string</FORM> - - multipart_form("url"){ "string" } - # <FORM METHOD="post" ACTION="url" ENCTYPE="multipart/form-data">string</FORM> -=end - def multipart_form(action = nil, enctype = "multipart/form-data") - attributes = if action == nil - { "METHOD" => "post", "ENCTYPE" => enctype } - elsif action.kind_of?(String) - { "METHOD" => "post", "ACTION" => action, - "ENCTYPE" => enctype } - else - unless action.has_key?("METHOD") - action["METHOD"] = "post" - end - unless action.has_key?("ENCTYPE") - action["ENCTYPE"] = enctype - end - action - end - if block_given? - form(attributes){ yield } - else - form(attributes) - end - end - - -=begin -=== PASSWORD_FIELD - password_field("name") - # <INPUT TYPE="password" NAME="name" SIZE="40"> - - password_field("name", "value") - # <INPUT TYPE="password" NAME="name" VALUE="value" SIZE="40"> - - password_field("password", "value", 80, 200) - # <INPUT TYPE="password" NAME="name" VALUE="value", SIZE="80", MAXLENGTH="200"> - - password_field({ "NAME" => "name", "VALUE" => "value" }) - # <INPUT TYPE="password" NAME="name" VALUE="value"> -=end - def password_field(name = "", value = nil, size = 40, maxlength = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "password", "NAME" => name, - "VALUE" => value, "SIZE" => size.to_s } - else - name["TYPE"] = "password" - name - end - attributes["MAXLENGTH"] = maxlength.to_s if maxlength - input(attributes) - end - - -=begin -=== POPUP_MENU - popup_menu("name", "foo", "bar", "baz") - # <SELECT NAME="name"> - # <OPTION VALUE="foo">foo</OPTION> - # <OPTION VALUE="bar">bar</OPTION> - # <OPTION VALUE="baz">baz</OPTION> - # </SELECT> - - popup_menu("name", ["foo"], ["bar", true], "baz") - # <SELECT NAME="name"> - # <OPTION VALUE="foo">foo</OPTION> - # <OPTION VALUE="bar" SELECTED>bar</OPTION> - # <OPTION VALUE="baz">baz</OPTION> - # </SELECT> - - popup_menu("name", ["1", "Foo"], ["2", "Bar", true], "Baz") - # <SELECT NAME="name"> - # <OPTION VALUE="1">Foo</OPTION> - # <OPTION SELECTED VALUE="2">Bar</OPTION> - # <OPTION VALUE="Baz">Baz</OPTION> - # </SELECT> - - popup_menu({"NAME" => "name", "SIZE" => 2, "MULTIPLE" => true, - "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) - # <SELECT NAME="name" MULTIPLE SIZE="2"> - # <OPTION VALUE="1">Foo</OPTION> - # <OPTION SELECTED VALUE="2">Bar</OPTION> - # <OPTION VALUE="Baz">Baz</OPTION> - # </SELECT> -=end - def popup_menu(name = "", *values) - - if name.kind_of?(Hash) - values = name["VALUES"] - size = name["SIZE"].to_s if name["SIZE"] - multiple = name["MULTIPLE"] - name = name["NAME"] - else - size = nil - multiple = nil - end - - select({ "NAME" => name, "SIZE" => size, - "MULTIPLE" => multiple }){ - values.collect{|value| - if value.kind_of?(String) - option({ "VALUE" => value }){ value } - else - if value[value.size - 1] == true - option({ "VALUE" => value[0], "SELECTED" => true }){ - value[value.size - 2] - } - else - option({ "VALUE" => value[0] }){ - value[value.size - 1] - } - end - end - }.to_s - } - - end - - -=begin -=== RADIO_BUTTON - radio_button("name", "value") - # <INPUT TYPE="radio" NAME="name", VALUE="value"> - - radio_button("name", "value", true) - # <INPUT TYPE="radio" NAME="name", VALUE="value", CHECKED> - - radio_button({ "NAME" => "name", "VALUE" => "value", "ID" => "foo" }) - # <INPUT TYPE="radio" NAME="name" VALUE="value" ID="foo"> -=end - def radio_button(name = "", value = nil, checked = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "radio", "NAME" => name, - "VALUE" => value, "CHECKED" => checked } - else - name["TYPE"] = "radio" - name - end - input(attributes) - end - - -=begin -=== RADIO_GROUP - radio_group("name", "foo", "bar", "baz") - # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo - # <INPUT TYPE="radio" NAME="name" VALUE="bar">bar - # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz - - radio_group("name", ["foo"], ["bar", true], "baz") - # <INPUT TYPE="radio" NAME="name" VALUE="foo">foo - # <INPUT TYPE="radio" SELECTED NAME="name" VALUE="bar">bar - # <INPUT TYPE="radio" NAME="name" VALUE="baz">baz - - radio_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz") - # <INPUT TYPE="radio" NAME="name" VALUE="1">Foo - # <INPUT TYPE="radio" SELECTED NAME="name" VALUE="2">Bar - # <INPUT TYPE="radio" NAME="name" VALUE="Baz">Baz - - radio_group({ "NAME" => "name", - "VALUES" => ["foo", "bar", "baz"] }) - - radio_group({ "NAME" => "name", - "VALUES" => [["foo"], ["bar", true], "baz"] }) - - radio_group({ "NAME" => "name", - "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) -=end - def radio_group(name = "", *values) - if name.kind_of?(Hash) - values = name["VALUES"] - name = name["NAME"] - end - values.collect{|value| - if value.kind_of?(String) - radio_button(name, value) + value - else - if value[value.size - 1] == true - radio_button(name, value[0], true) + - value[value.size - 2] - else - radio_button(name, value[0]) + - value[value.size - 1] - end - end - }.to_s - end - - -=begin -=== RESET BUTTON - reset - # <INPUT TYPE="reset"> - - reset("reset") - # <INPUT TYPE="reset" VALUE="reset"> - - reset({ "VALUE" => "reset", "ID" => "foo" }) - # <INPUT TYPE="reset" VALUE="reset" ID="foo"> -=end - def reset(value = nil, name = nil) - attributes = if (not value) or value.kind_of?(String) - { "TYPE" => "reset", "VALUE" => value, "NAME" => name } - else - value["TYPE"] = "reset" - value - end - input(attributes) - end - - -=begin -=== SCROLLING_LIST - scrolling_list({"NAME" => "name", "SIZE" => 2, "MULTIPLE" => true, - "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"] }) - # <SELECT NAME="name" MULTIPLE SIZE="2"> - # <OPTION VALUE="1">Foo</OPTION> - # <OPTION SELECTED VALUE="2">Bar</OPTION> - # <OPTION VALUE="Baz">Baz</OPTION> - # </SELECT> -=end - alias scrolling_list popup_menu - - -=begin -=== SUBMIT BUTTON - submit - # <INPUT TYPE="submit"> - - submit("ok") - # <INPUT TYPE="submit" VALUE="ok"> - - submit("ok", "button1") - # <INPUT TYPE="submit" VALUE="ok" NAME="button1"> - - submit({ "VALUE" => "ok", "NAME" => "button1", "ID" => "foo" }) - # <INPUT TYPE="submit" VALUE="ok" NAME="button1" ID="foo"> -=end - def submit(value = nil, name = nil) - attributes = if (not value) or value.kind_of?(String) - { "TYPE" => "submit", "VALUE" => value, "NAME" => name } - else - value["TYPE"] = "submit" - value - end - input(attributes) - end - - -=begin -=== TEXT_FIELD - text_field("name") - # <INPUT TYPE="text" NAME="name" SIZE="40"> - - text_field("name", "value") - # <INPUT TYPE="text" NAME="name" VALUE="value" SIZE="40"> - - text_field("name", "value", 80) - # <INPUT TYPE="text" NAME="name" VALUE="value", SIZE="80"> - - text_field("name", "value", 80, 200) - # <INPUT TYPE="text" NAME="name" VALUE="value", SIZE="80", MAXLENGTH="200"> - - text_field({ "NAME" => "name", "VALUE" => "value" }) - # <INPUT TYPE="text" NAME="name" VALUE="value"> -=end - def text_field(name = "", value = nil, size = 40, maxlength = nil) - attributes = if name.kind_of?(String) - { "TYPE" => "text", "NAME" => name, "VALUE" => value, - "SIZE" => size.to_s } - else - name["TYPE"] = "text" - name - end - attributes["MAXLENGTH"] = maxlength.to_s if maxlength - input(attributes) - end - - -=begin -=== TEXTAREA ELEMENT - textarea("name") - # = textarea({ "NAME" => "name", "COLS" => 70, "ROWS" => 10 }) - - textarea("name", 40, 5) - # = textarea({ "NAME" => "name", "COLS" => 40, "ROWS" => 5 }) -=end - def textarea(name = "", cols = 70, rows = 10) - attributes = if name.kind_of?(String) - { "NAME" => name, "COLS" => cols.to_s, - "ROWS" => rows.to_s } - else - name - end - if block_given? - super(attributes){ yield } - else - super(attributes) - end - end - - end # HtmlExtension - - - module Html3 - - def doctype - %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">| - end - - def element_init - extend TagMaker - methods = "" - # - - - for element in %w[ A TT I B U STRIKE BIG SMALL SUB SUP EM STRONG - DFN CODE SAMP KBD VAR CITE FONT ADDRESS DIV center MAP - APPLET PRE XMP LISTING DL OL UL DIR MENU SELECT table TITLE - STYLE SCRIPT H1 H2 H3 H4 H5 H6 TEXTAREA FORM BLOCKQUOTE - CAPTION ] - methods.concat( <<-BEGIN + nn_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # - O EMPTY - for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT - ISINDEX META ] - methods.concat( <<-BEGIN + nOE_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # O O or - O - for element in %w[ HTML HEAD BODY P PLAINTEXT DT DD LI OPTION tr - th td ] - methods.concat( <<-BEGIN + nO_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - eval(methods) - end - - end # Html3 - - - module Html4 - - def doctype - %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">| - end - - def element_init - extend TagMaker - methods = "" - # - - - for element in %w[ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD - VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT - H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP - FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT - TEXTAREA FORM A BLOCKQUOTE CAPTION ] - methods.concat( <<-BEGIN + nn_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # - O EMPTY - for element in %w[ IMG BASE BR AREA LINK PARAM HR INPUT COL META ] - methods.concat( <<-BEGIN + nOE_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # O O or - O - for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY - COLGROUP TR TH TD HEAD] - methods.concat( <<-BEGIN + nO_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - eval(methods) - end - - end # Html4 - - - module Html4Tr - - def doctype - %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">| - end - - def element_init - extend TagMaker - methods = "" - # - - - for element in %w[ TT I B U S STRIKE BIG SMALL EM STRONG DFN - CODE SAMP KBD VAR CITE ABBR ACRONYM FONT SUB SUP SPAN BDO - ADDRESS DIV CENTER MAP OBJECT APPLET H1 H2 H3 H4 H5 H6 PRE Q - INS DEL DL OL UL DIR MENU LABEL SELECT OPTGROUP FIELDSET - LEGEND BUTTON TABLE IFRAME NOFRAMES TITLE STYLE SCRIPT - NOSCRIPT TEXTAREA FORM A BLOCKQUOTE CAPTION ] - methods.concat( <<-BEGIN + nn_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # - O EMPTY - for element in %w[ IMG BASE BASEFONT BR AREA LINK PARAM HR INPUT - COL ISINDEX META ] - methods.concat( <<-BEGIN + nOE_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # O O or - O - for element in %w[ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY - COLGROUP TR TH TD HEAD ] - methods.concat( <<-BEGIN + nO_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - eval(methods) - end - - end # Html4Tr - - - module Html4Fr - - def doctype - %|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">| - end - - def element_init - extend TagMaker - extend Html4Tr - element_init() - methods = "" - # - - - for element in %w[ FRAMESET ] - methods.concat( <<-BEGIN + nn_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - - # - O EMPTY - for element in %w[ FRAME ] - methods.concat( <<-BEGIN + nOE_element_def(element) + <<-END ) - def #{element.downcase}(attributes = {}) - BEGIN - end - END - end - eval(methods) - end - - end # Html4Fr - - - def initialize(type = "query") - extend QueryExtension - if defined?(CGI_PARAMS) - @params = CGI_PARAMS.nil? ? nil : CGI_PARAMS.dup - @cookies = CGI_COOKIES.nil? ? nil : CGI_COOKIES.dup - else - initialize_query() # set @params, @cookies - eval "CGI_PARAMS = @params.nil? ? nil : @params.dup" - eval "CGI_COOKIES = @cookies.nil? ? nil : @cookies.dup" - end - @output_cookies = nil - @output_hidden = nil - - case type - when "html3" - extend Html3 - element_init() - extend HtmlExtension - when "html4" - extend Html4 - element_init() - extend HtmlExtension - when "html4Tr" - extend Html4Tr - element_init() - extend HtmlExtension - when "html4Fr" - extend Html4Fr - element_init() - extend HtmlExtension - end - - end - - if defined?(MOD_RUBY) and (RUBY_VERSION < "1.4.3") - raise "Please, use ruby1.4.3 or later." - else - at_exit() do - if defined?(CGI_PARAMS) - remove_const(:CGI_PARAMS) - remove_const(:CGI_COOKIES) - end - end - end -end - - -=begin - -== HISTORY - -* Mon Dec 25 05:02:27 JST 2000 - wakou - * version 2.1.2 - * bug fix: CGI::escapeElement(): didn't accept empty element. - * bug fix: CGI::unescapeElement(): ditto. - * bug fix: CGI::unescapeHTML(): support for "©, ♥, ..." - thanks to YANAGAWA Kazuhisa <kjana@os.xaxon.ne.jp> - * bug fix: CGI::unescapeHTML(): support for "	" - thanks to OHSHIMA Ryunosuke <ryu@jaist.ac.jp> - * Regexp::last_match[0] --> $& - * Regexp::last_match[1] --> $1 - * Regexp::last_match[2] --> $2 - * add: CGI#param(): test implement. undocumented. - -* Mon Dec 11 00:16:51 JST 2000 - wakou - * version 2.1.1 - * support -T1 on ruby 1.6.2 - * body.original_filename: eval(str.dump.untaint).taint - * body.content_type: eval(str.dump.untaint).taint - * $& --> Regexp::last_match[0] - * $1 --> Regexp::last_match[1] - * $2 --> Regexp::last_match[2] - -* Thu Oct 12 01:16:59 JST 2000 - wakou - * version 2.1.0 - * bug fix: CGI::html(): PRETTY option didn't work. - thanks to akira yamada <akira@ruby-lang.org> - -* Wed Sep 13 06:09:26 JST 2000 - wakou - * version 2.0.1 - * bug fix: CGI::header(): output status header. - thanks to Yasuhiro Fukuma <yasuf@bsdclub.org> - -* Tue Sep 12 06:56:51 JST 2000 - wakou - * version 2.0.0 - * require ruby1.5.4 or later. (ruby1.4 doesn't have block_given? method.) - * improvement: CGI::escape(), CGI::unescape(). - thanks to WATANABE Hirofumi <eban@os.rim.or.jp> - * bug fix: CGI::escapeElement(). - * improvement: CGI::unescapeHTML(). - thanks to Kazuhiro NISHIYAMA <zn@mbf.nifty.com> - -* 2000/08/09 04:32:22 - matz - * improvement: CGI::pretty() - -* 2000/06/23 07:01:34 - matz - * change: iterator? --> block_given? - -* Sun Jun 18 23:31:44 JST 2000 - wakou - * version 1.7.0 - * change: version syntax. old: x.yz, now: x.y.z - -* 2000/06/13 15:49:27 - wakou - * version 1.61 - * read_multipart(): if no content body then raise EOFError. - -* 2000/06/03 18:16:17 - wakou - * version 1.60 - * improve: CGI::pretty() - -* 2000/05/30 19:04:08 - wakou - * version 1.50 - * CGI#out(): if "HEAD" == REQUEST_METHOD then output only HTTP header. - -* 2000/05/24 06:58:51 - wakou - * version 1.40 - * typo: CGI::Cookie::new() - * bug fix: CGI::escape(): bad: " " --> "%2B"; true: " " --> "+"; - thanks to Ryunosuke Ohshima <ryu@jaist.ac.jp> - -* 2000/05/08 21:51:30 - wakou - * version 1.31 - * improvement of time forming new CGI object accompanied with HTML generation methods. - -* 2000/05/07 21:51:14 - wakou - * version 1.30 - * require English.rb - * improvement of load time. - -* 2000/05/02 21:44:12 - wakou - * version 1.21 - * support for ruby 1.5.3 (2000-05-01) (Array#filter --> Array#collect!) - -* 2000/04/03 18:31:42 - wakou - * version 1.20 - * bug fix: CGI#image_button() can't get Hash option. - thanks to Takashi Ikeda <ikeda@auc.co.jp> - * CGI::unescapeHTML(): simple support for "〹" - * CGI::Cookie::new(): simple support for IE - * CGI::escape(): ' ' replaced by '+' - -* 1999/12/06 20:16:34 - wakou - * version 1.10 - * can make many CGI objects. - * if use mod_ruby, then require ruby1.4.3 or later. - -* 1999/11/29 21:35:58 - wakou - * version 1.01 - * support for ruby 1.5.0 (1999-11-20) - -* 1999/09/13 23:00:58 - wakou - * version 1.00 - * COUTION! name change. CGI.rb --> cgi.rb - * CGI#auth_type, CGI#content_length, CGI#content_type, ... - if not ENV included it, then return nil. - * CGI#content_length and CGI#server_port return Integer. - * if not CGI#params.include?('name'), then CGI#params['name'] return []. - * if not CGI#cookies.include?('name'), then CGI#cookies['name'] return []. - -* 1999/08/05 18:04:59 - wakou - * version 0.41 - * typo. thanks to MJ Ray <markj@altern.org> - HTTP_STATUS["NOT_INPLEMENTED"] --> HTTP_STATUS["NOT_IMPLEMENTED"] - -* 1999/07/20 20:44:31 - wakou - * version 0.40 - * COUTION! incompatible change. - sorry, but probably this change is last big incompatible change. - * CGI::print --> CGI#out - cgi = CGI.new - cgi.out{"string"} # old: CGI::print{"string"} - * CGI::cookie --> CGI::Cookie::new - cookie1 = CGI::Cookie::new # old: CGI::cookie - * CGI::header --> CGI#header - -* 1999/06/29 06:50:21 - wakou - * version 0.30 - * COUTION! incompatible change. - query = CGI.new - cookies = query.cookies # old: query.cookie - values = query.cookies[name] # old: query.cookie[name] - -* 1999/06/21 21:05:57 - wakou - * version 0.24 - * CGI::Cookie::parse() return { name => CGI::Cookie object } pairs. - -* 1999/06/20 23:29:12 - wakou - * version 0.23 - * modified a bit to clear module separation. - -* Mon Jun 14 17:49:32 JST 1999 - matz - * version 0.22 - * Cookies are now CGI::Cookie objects. - * Cookie modeled after CGI::Cookie.pm. - -* Fri Jun 11 11:19:11 JST 1999 - matz - * version 0.21 - * modified a bit to clear module separation. - -* 1999/06/03 06:48:15 - wakou - * version 0.20 - * support for multipart form. - -* 1999/05/24 07:05:41 - wakou - * version 0.10 - * first release. - -$Date$ -=end +require "cgi/escape" +warn <<-WARNING, uplevel: Gem::BUNDLED_GEMS.uplevel if $VERBOSE +CGI library is removed from Ruby 4.0. Please use cgi/escape instead for CGI.escape and CGI.unescape features. +If you need to use the full features of CGI library, Please install cgi gem. +WARNING |
