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

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

[Source]

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

[Source]

      # File lib/cgi.rb, line 1133
1133:     def multipart?
1134:       @multipart
1135:     end

Set all the parameters.

[Source]

     # File lib/cgi.rb, line 963
963:     def params=(hash)
964:       @params.clear
965:       @params.update(hash)
966:     end

Get the raw cookies as a string.

[Source]

     # File lib/cgi.rb, line 946
946:     def raw_cookie
947:       env_table["HTTP_COOKIE"]
948:     end

Get the raw RFC2965 cookies as a string.

[Source]

     # File lib/cgi.rb, line 951
951:     def raw_cookie2
952:       env_table["HTTP_COOKIE2"]
953:     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 1104
1104:     def initialize_query()
1105:       if ("POST" == env_table['REQUEST_METHOD']) and
1106:          %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
1107:         boundary = $1.dup
1108:         @multipart = true
1109:         @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
1110:       else
1111:         @multipart = false
1112:         @params = CGI::parse(
1113:                     case env_table['REQUEST_METHOD']
1114:                     when "GET", "HEAD"
1115:                       if defined?(MOD_RUBY)
1116:                         Apache::request.args or ""
1117:                       else
1118:                         env_table['QUERY_STRING'] or ""
1119:                       end
1120:                     when "POST"
1121:                       stdinput.binmode if defined? stdinput.binmode
1122:                       stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
1123:                     else
1124:                       read_from_cmdline
1125:                     end
1126:                   )
1127:       end
1128: 
1129:       @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
1130:     end

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

[Source]

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

[Source]

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

[Validate]