Module CGI::QueryExtension
In: lib/cgi.rb

Mixin module. It provides the follow functionality groups:

  1. Access to CGI environment variables as methods. See documentation to the CGI class for a list of these variables.
  2. Access to cookies, including the cookies attribute.
  3. Access to parameters, including the params attribute, and overloading
    to perform parameter value lookup by key.
  4. The initialize_query method, for initialising the above mechanisms, handling multipart forms, and allowing the class to be used in "offline" mode.

Methods

External Aliases

path -> local_path

Attributes

cookies  [RW]  Get the cookies as a hash of cookie-name=>Cookie pairs.
params  [R]  Get the parameters as a hash of name=>values pairs, where values is an Array.

Public Instance methods

Get the value for the parameter with a given key.

If the parameter has multiple values, only the first will be retrieved; use params() to get the array of values.

[Source]

      # File lib/cgi.rb, line 1174
1174:     def [](key)
1175:       params = @params[key]
1176:       return '' unless params
1177:       value = params[0]
1178:       if @multipart
1179:         if value
1180:           return value
1181:         elsif defined? StringIO
1182:           StringIO.new("")
1183:         else
1184:           Tempfile.new("CGI")
1185:         end
1186:       else
1187:         str = if value then value.dup else "" end
1188:         str.extend(Value)
1189:         str.set_params(params)
1190:         str
1191:       end
1192:     end

Returns true if a given parameter key exists in the query.

[Source]

      # File lib/cgi.rb, line 1200
1200:     def has_key?(*args)
1201:       @params.has_key?(*args)
1202:     end
include?(*args)

Alias for has_key?

key?(*args)

Alias for has_key?

Return all parameter keys as an array.

[Source]

      # File lib/cgi.rb, line 1195
1195:     def keys(*args)
1196:       @params.keys(*args)
1197:     end

[Source]

      # File lib/cgi.rb, line 1143
1143:     def multipart?
1144:       @multipart
1145:     end

Set all the parameters.

[Source]

     # File lib/cgi.rb, line 968
968:     def params=(hash)
969:       @params.clear
970:       @params.update(hash)
971:     end

Get the raw cookies as a string.

[Source]

     # File lib/cgi.rb, line 951
951:     def raw_cookie
952:       env_table["HTTP_COOKIE"]
953:     end

Get the raw RFC2965 cookies as a string.

[Source]

     # File lib/cgi.rb, line 956
956:     def raw_cookie2
957:       env_table["HTTP_COOKIE2"]
958:     end

Private Instance methods

Initialize the data from the query.

Handles multipart forms (in particular, forms that involve file uploads). Reads query parameters in the @params field, and cookies into @cookies.

[Source]

      # File lib/cgi.rb, line 1114
1114:     def initialize_query()
1115:       if ("POST" == env_table['REQUEST_METHOD']) and
1116:          %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
1117:         boundary = $1.dup
1118:         @multipart = true
1119:         @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
1120:       else
1121:         @multipart = false
1122:         @params = CGI::parse(
1123:                     case env_table['REQUEST_METHOD']
1124:                     when "GET", "HEAD"
1125:                       if defined?(MOD_RUBY)
1126:                         Apache::request.args or ""
1127:                       else
1128:                         env_table['QUERY_STRING'] or ""
1129:                       end
1130:                     when "POST"
1131:                       stdinput.binmode if defined? stdinput.binmode
1132:                       stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
1133:                     else
1134:                       read_from_cmdline
1135:                     end
1136:                   )
1137:       end
1138: 
1139:       @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
1140:     end

offline mode. read name=value pairs on standard input.

[Source]

      # File lib/cgi.rb, line 1081
1081:     def read_from_cmdline
1082:       require "shellwords"
1083: 
1084:       string = unless ARGV.empty?
1085:         ARGV.join(' ')
1086:       else
1087:         if STDIN.tty?
1088:           STDERR.print(
1089:             %|(offline mode: enter name=value pairs on standard input)\n|
1090:           )
1091:         end
1092:         array = readlines rescue nil
1093:         if not array.nil?
1094:           array.join(' ').gsub(/\n/n, '')
1095:         else
1096:           ""
1097:         end
1098:       end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26')
1099: 
1100:       words = Shellwords.shellwords(string)
1101: 
1102:       if words.find{|x| /=/n.match(x) }
1103:         words.join('&')
1104:       else
1105:         words.join('+')
1106:       end
1107:     end

[Source]

      # File lib/cgi.rb, line 973
 973:     def read_multipart(boundary, content_length)
 974:       params = Hash.new([])
 975:       boundary = "--" + boundary
 976:       quoted_boundary = Regexp.quote(boundary, "n")
 977:       buf = ""
 978:       bufsize = 10 * 1024
 979:       boundary_end=""
 980: 
 981:       # start multipart/form-data
 982:       stdinput.binmode if defined? stdinput.binmode
 983:       boundary_size = boundary.size + EOL.size
 984:       content_length -= boundary_size
 985:       status = stdinput.read(boundary_size)
 986:       if nil == status
 987:         raise EOFError, "no content body"
 988:       elsif boundary + EOL != status
 989:         raise EOFError, "bad content body"
 990:       end
 991: 
 992:       loop do
 993:         head = nil
 994:         if 10240 < content_length
 995:           require "tempfile"
 996:           body = Tempfile.new("CGI")
 997:         else
 998:           begin
 999:             require "stringio"
1000:             body = StringIO.new
1001:           rescue LoadError
1002:             require "tempfile"
1003:             body = Tempfile.new("CGI")
1004:           end
1005:         end
1006:         body.binmode if defined? body.binmode
1007: 
1008:         until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)
1009: 
1010:           if (not head) and /#{EOL}#{EOL}/n.match(buf)
1011:             buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
1012:               head = $1.dup
1013:               ""
1014:             end
1015:             next
1016:           end
1017: 
1018:           if head and ( (EOL + boundary + EOL).size < buf.size )
1019:             body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
1020:             buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
1021:           end
1022: 
1023:           c = if bufsize < content_length
1024:                 stdinput.read(bufsize)
1025:               else
1026:                 stdinput.read(content_length)
1027:               end
1028:           if c.nil? || c.empty?
1029:             raise EOFError, "bad content body"
1030:           end
1031:           buf.concat(c)
1032:           content_length -= c.size
1033:         end
1034: 
1035:         buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
1036:           body.print $1
1037:           if "--" == $2
1038:             content_length = -1
1039:           end
1040:           boundary_end = $2.dup
1041:           ""
1042:         end
1043: 
1044:         body.rewind
1045: 
1046:         /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni.match(head)
1047:         filename = ($1 or $2 or "")
1048:         if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
1049:             /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
1050:             (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
1051:           filename = CGI::unescape(filename)
1052:         end
1053:         
1054:         /Content-Type: ([^\s]*)/ni.match(head)
1055:         content_type = ($1 or "")
1056: 
1057:         (class << body; self; end).class_eval do
1058:           alias local_path path
1059:           define_method(:original_filename) {filename.dup.taint}
1060:           define_method(:content_type) {content_type.dup.taint}
1061:         end
1062: 
1063:         /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head)
1064:         name = $1.dup
1065: 
1066:         if params.has_key?(name)
1067:           params[name].push(body)
1068:         else
1069:           params[name] = [body]
1070:         end
1071:         break if buf.size == 0
1072:         break if content_length == -1
1073:       end
1074:       raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/
1075: 
1076:       params
1077:     end

[Validate]