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 1169
1169:     def [](key)
1170:       params = @params[key]
1171:       return '' unless params
1172:       value = params[0]
1173:       if @multipart
1174:         if value
1175:           return value
1176:         elsif defined? StringIO
1177:           StringIO.new("")
1178:         else
1179:           Tempfile.new("CGI")
1180:         end
1181:       else
1182:         str = if value then value.dup else "" end
1183:         str.extend(Value)
1184:         str.set_params(params)
1185:         str
1186:       end
1187:     end

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

[Source]

      # File lib/cgi.rb, line 1195
1195:     def has_key?(*args)
1196:       @params.has_key?(*args)
1197:     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 1190
1190:     def keys(*args)
1191:       @params.keys(*args)
1192:     end

[Source]

      # File lib/cgi.rb, line 1138
1138:     def multipart?
1139:       @multipart
1140:     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 1109
1109:     def initialize_query()
1110:       if ("POST" == env_table['REQUEST_METHOD']) and
1111:          %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
1112:         boundary = $1.dup
1113:         @multipart = true
1114:         @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
1115:       else
1116:         @multipart = false
1117:         @params = CGI::parse(
1118:                     case env_table['REQUEST_METHOD']
1119:                     when "GET", "HEAD"
1120:                       if defined?(MOD_RUBY)
1121:                         Apache::request.args or ""
1122:                       else
1123:                         env_table['QUERY_STRING'] or ""
1124:                       end
1125:                     when "POST"
1126:                       stdinput.binmode if defined? stdinput.binmode
1127:                       stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
1128:                     else
1129:                       read_from_cmdline
1130:                     end
1131:                   )
1132:       end
1133: 
1134:       @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
1135:     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:         readlines.join(' ').gsub(/\n/n, '')
1093:       end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26')
1094: 
1095:       words = Shellwords.shellwords(string)
1096: 
1097:       if words.find{|x| /=/n.match(x) }
1098:         words.join('&')
1099:       else
1100:         words.join('+')
1101:       end
1102:     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]