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