Module | Merb::Parse |
In: |
merb-core/lib/merb-core/dispatch/request_parsers.rb
|
NAME_REGEX | = | /Content-Disposition:.* name="?([^\";]*)"?/ni.freeze |
CONTENT_TYPE_REGEX | = | /Content-Type: (.*)\r\n/ni.freeze |
FILENAME_REGEX | = | /Content-Disposition:.* filename="?([^\";]*)"?/ni.freeze |
CRLF | = | "\r\n".freeze |
EOL | = | CRLF |
s<String>: | String to URL escape. |
String: | The escaped string. |
:api: public
# File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 178 178: def self.escape(s) 179: s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { 180: '%'+$1.unpack('H2'*$1.size).join('%').upcase 181: }.tr(' ', '+') 182: end
request<IO>: | The raw request. |
boundary<String>: | The boundary string. |
content_length<Fixnum>: | The length of the content. |
ControllerExceptions::MultiPartParseError: | Failed to parse request. |
Hash: | The parsed request. |
:api: plugin
# File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 49 49: def self.multipart(request, boundary, content_length) 50: boundary = "--#{boundary}" 51: paramhsh = {} 52: buf = "" 53: input = request 54: input.binmode if defined? input.binmode 55: boundary_size = boundary.size + EOL.size 56: bufsize = 16384 57: content_length -= boundary_size 58: # status is boundary delimiter line 59: status = input.read(boundary_size) 60: return {} if status == nil || status.empty? 61: raise ControllerExceptions::MultiPartParseError, "bad content body:\n'#{status}' should == '#{boundary + EOL}'" unless status == boundary + EOL 62: # second argument to Regexp.quote is for KCODE 63: rx = /(?:#{EOL})?#{Regexp.quote(boundary,'n')}(#{EOL}|--)/ 64: loop { 65: head = nil 66: body = '' 67: filename = content_type = name = nil 68: read_size = 0 69: until head && buf =~ rx 70: i = buf.index("\r\n\r\n") 71: if( i == nil && read_size == 0 && content_length == 0 ) 72: content_length = -1 73: break 74: end 75: if !head && i 76: head = buf.slice!(0, i+2) # First \r\n 77: buf.slice!(0, 2) # Second \r\n 78: 79: # String#[] with 2nd arg here is returning 80: # a group from match data 81: filename = head[FILENAME_REGEX, 1] 82: content_type = head[CONTENT_TYPE_REGEX, 1] 83: name = head[NAME_REGEX, 1] 84: 85: if filename && !filename.empty? 86: body = Tempfile.new(:Merb) 87: body.binmode if defined? body.binmode 88: end 89: next 90: end 91: 92: # Save the read body part. 93: if head && (boundary_size+4 < buf.size) 94: body << buf.slice!(0, buf.size - (boundary_size+4)) 95: end 96: 97: read_size = bufsize < content_length ? bufsize : content_length 98: if( read_size > 0 ) 99: c = input.read(read_size) 100: raise ControllerExceptions::MultiPartParseError, "bad content body" if c.nil? || c.empty? 101: buf << c 102: content_length -= c.size 103: end 104: end 105: 106: # Save the rest. 107: if i = buf.index(rx) 108: # correct value of i for some edge cases 109: if (i > 2) && (j = buf.index(rx, i-2)) && (j < i) 110: i = j 111: end 112: body << buf.slice!(0, i) 113: buf.slice!(0, boundary_size+2) 114: 115: content_length = -1 if $1 == "--" 116: end 117: 118: if filename && !filename.empty? 119: body.rewind 120: data = { 121: :filename => File.basename(filename), 122: :content_type => content_type, 123: :tempfile => body, 124: :size => File.size(body.path) 125: } 126: else 127: data = body 128: end 129: paramhsh = normalize_params(paramhsh,name,data) 130: break if buf.empty? || content_length == -1 131: } 132: paramhsh 133: end
value<Array, Hash, Dictionary ~to_s>: | The value for the query string. |
prefix<~to_s>: | The prefix to add to the query string keys. |
String: | The query string. |
If the value is a string, the prefix will be used as the key.
params_to_query_string(10, "page") # => "page=10" params_to_query_string({ :page => 10, :word => "ruby" }) # => "page=10&word=ruby" params_to_query_string({ :page => 10, :word => "ruby" }, "search") # => "search[page]=10&search[word]=ruby" params_to_query_string([ "ice-cream", "cake" ], "shopping_list") # => "shopping_list[]=ice-cream&shopping_list[]=cake"
:api: plugin
# File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 156 156: def self.params_to_query_string(value, prefix = nil) 157: case value 158: when Array 159: value.map { |v| 160: params_to_query_string(v, "#{prefix}[]") 161: } * "&" 162: when Hash, Dictionary 163: value.map { |k, v| 164: params_to_query_string(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) 165: } * "&" 166: else 167: "#{prefix}=#{escape(value)}" 168: end 169: end
query_string<String>: | The query string. |
delimiter<String>: | The query string divider. Defaults to "&". |
preserve_order<Boolean>: | Preserve order of args. Defaults to false. |
Mash: | The parsed query string (Dictionary if preserve_order is set). |
Merb::Parse.query("bar=nik&post[body]=heya") # => { :bar => "nik", :post => { :body => "heya" } }
:api: plugin
# File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 17 17: def self.query(query_string, delimiter = '&;', preserve_order = false) 18: query = preserve_order ? Dictionary.new : {} 19: for pair in (query_string || '').split(/[#{delimiter}] */n) 20: key, value = unescape(pair).split('=',2) 21: next if key.nil? 22: if key.include?('[') 23: normalize_params(query, key, value) 24: else 25: query[key] = value 26: end 27: end 28: preserve_order ? query : query.to_mash 29: end
Converts a query string snippet to a hash and adds it to existing parameters.
parms<Hash>: | Parameters to add the normalized parameters to. |
name<String>: | The key of the parameter to normalize. |
val<String>: | The value of the parameter. |
Hash: | Normalized parameters |
:api: private
# File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 222 222: def self.normalize_params(parms, name, val=nil) 223: name =~ %r([\[\]]*([^\[\]]+)\]*) 224: key = $1 || '' 225: after = $' || '' 226: 227: if after == "" 228: parms[key] = val 229: elsif after == "[]" 230: (parms[key] ||= []) << val 231: elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) 232: child_key = $1 233: parms[key] ||= [] 234: if parms[key].last.is_a?(Hash) && !parms[key].last.key?(child_key) 235: parms[key].last.update(child_key => val) 236: else 237: parms[key] << { child_key => val } 238: end 239: else 240: parms[key] ||= {} 241: parms[key] = normalize_params(parms[key], after, val) 242: end 243: parms 244: end