| Module | CGI::QueryExtension |
| In: |
lib/cgi.rb
|
Mixin module. It provides the follow functionality groups:
| path | -> | local_path |
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.
# File lib/cgi.rb, line 1160
1160: def [](key)
1161: params = @params[key]
1162: value = params[0]
1163: if @multipart
1164: if value
1165: return value
1166: elsif defined? StringIO
1167: StringIO.new("")
1168: else
1169: Tempfile.new("CGI")
1170: end
1171: else
1172: str = if value then value.dup else "" end
1173: str.extend(Value)
1174: str.set_params(params)
1175: str
1176: end
1177: end
Returns true if a given parameter key exists in the query.
# File lib/cgi.rb, line 1185
1185: def has_key?(*args)
1186: @params.has_key?(*args)
1187: end
Return all parameter keys as an array.
# File lib/cgi.rb, line 1180
1180: def keys(*args)
1181: @params.keys(*args)
1182: end
Get the raw cookies as a string.
# File lib/cgi.rb, line 945
945: def raw_cookie
946: env_table["HTTP_COOKIE"]
947: end
Get the raw RFC2965 cookies as a string.
# File lib/cgi.rb, line 950
950: def raw_cookie2
951: env_table["HTTP_COOKIE2"]
952: end
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.
# File lib/cgi.rb, line 1100
1100: def initialize_query()
1101: if ("POST" == env_table['REQUEST_METHOD']) and
1102: %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
1103: boundary = $1.dup
1104: @multipart = true
1105: @params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
1106: else
1107: @multipart = false
1108: @params = CGI::parse(
1109: case env_table['REQUEST_METHOD']
1110: when "GET", "HEAD"
1111: if defined?(MOD_RUBY)
1112: Apache::request.args or ""
1113: else
1114: env_table['QUERY_STRING'] or ""
1115: end
1116: when "POST"
1117: stdinput.binmode if defined? stdinput.binmode
1118: stdinput.read(Integer(env_table['CONTENT_LENGTH'])) or ''
1119: else
1120: read_from_cmdline
1121: end
1122: )
1123: end
1124:
1125: @cookies = CGI::Cookie::parse((env_table['HTTP_COOKIE'] or env_table['COOKIE']))
1126: end
offline mode. read name=value pairs on standard input.
# File lib/cgi.rb, line 1072
1072: def read_from_cmdline
1073: require "shellwords"
1074:
1075: string = unless ARGV.empty?
1076: ARGV.join(' ')
1077: else
1078: if STDIN.tty?
1079: STDERR.print(
1080: %|(offline mode: enter name=value pairs on standard input)\n|
1081: )
1082: end
1083: readlines.join(' ').gsub(/\n/n, '')
1084: end.gsub(/\\=/n, '%3D').gsub(/\\&/n, '%26')
1085:
1086: words = Shellwords.shellwords(string)
1087:
1088: if words.find{|x| /=/n.match(x) }
1089: words.join('&')
1090: else
1091: words.join('+')
1092: end
1093: end
# File lib/cgi.rb, line 967
967: def read_multipart(boundary, content_length)
968: params = Hash.new([])
969: boundary = "--" + boundary
970: quoted_boundary = Regexp.quote(boundary, "n")
971: buf = ""
972: bufsize = 10 * 1024
973:
974: # start multipart/form-data
975: stdinput.binmode if defined? stdinput.binmode
976: boundary_size = boundary.size + EOL.size
977: content_length -= boundary_size
978: status = stdinput.read(boundary_size)
979: if nil == status
980: raise EOFError, "no content body"
981: elsif boundary + EOL != status
982: raise EOFError, "bad content body"
983: end
984:
985: loop do
986: head = nil
987: if 10240 < content_length
988: require "tempfile"
989: body = Tempfile.new("CGI")
990: else
991: begin
992: require "stringio"
993: body = StringIO.new
994: rescue LoadError
995: require "tempfile"
996: body = Tempfile.new("CGI")
997: end
998: end
999: body.binmode if defined? body.binmode
1000:
1001: until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)
1002:
1003: if (not head) and /#{EOL}#{EOL}/n.match(buf)
1004: buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
1005: head = $1.dup
1006: ""
1007: end
1008: next
1009: end
1010:
1011: if head and ( (EOL + boundary + EOL).size < buf.size )
1012: body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
1013: buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
1014: end
1015:
1016: c = if bufsize < content_length
1017: stdinput.read(bufsize)
1018: else
1019: stdinput.read(content_length)
1020: end
1021: if c.nil? || c.empty?
1022: raise EOFError, "bad content body"
1023: end
1024: buf.concat(c)
1025: content_length -= c.size
1026: end
1027:
1028: buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
1029: body.print $1
1030: if "--" == $2
1031: content_length = -1
1032: end
1033: ""
1034: end
1035:
1036: body.rewind
1037:
1038: /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
1039: filename = ($1 or "")
1040: if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
1041: /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
1042: (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
1043: filename = CGI::unescape(filename)
1044: end
1045:
1046: /Content-Type: (.*)/ni.match(head)
1047: content_type = ($1 or "")
1048:
1049: (class << body; self; end).class_eval do
1050: alias local_path path
1051: define_method(:original_filename) {filename.dup.taint}
1052: define_method(:content_type) {content_type.dup.taint}
1053: end
1054:
1055: /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
1056: name = $1.dup
1057:
1058: if params.has_key?(name)
1059: params[name].push(body)
1060: else
1061: params[name] = [body]
1062: end
1063: break if buf.size == 0
1064: break if content_length === -1
1065: end
1066:
1067: params
1068: end