Module Merb::Parse
In: merb-core/lib/merb-core/dispatch/request_parsers.rb

Methods

Constants

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

Public Class methods

Parameters

s<String>:String to URL escape.

returns

String:The escaped string.

:api: public

[Source]

     # 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

Parameters

s<String>:String to XML escape.

returns

String:The escaped string.

:api: public

[Source]

     # File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 204
204:     def self.escape_xml(s)
205:       Erubis::XmlHelper.escape_xml(s)
206:     end

Parameters

request<IO>:The raw request.
boundary<String>:The boundary string.
content_length<Fixnum>:The length of the content.

Raises

ControllerExceptions::MultiPartParseError:Failed to parse request.

Returns

Hash:The parsed request.

:api: plugin

[Source]

     # 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

Parameters

value<Array, Hash, Dictionary ~to_s>:The value for the query string.
prefix<~to_s>:The prefix to add to the query string keys.

Returns

String:The query string.

Alternatives

If the value is a string, the prefix will be used as the key.

Examples

  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

[Source]

     # 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

Parameters

query_string<String>:The query string.
delimiter<String>:The query string divider. Defaults to "&".
preserve_order<Boolean>:Preserve order of args. Defaults to false.

Returns

Mash:The parsed query string (Dictionary if preserve_order is set).

Examples

  Merb::Parse.query("bar=nik&post[body]=heya")
    # => { :bar => "nik", :post => { :body => "heya" } }

:api: plugin

[Source]

    # 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

Parameter

s<String>:String to URL unescape.

returns

String:The unescaped string.

:api: public

[Source]

     # File merb-core/lib/merb-core/dispatch/request_parsers.rb, line 191
191:     def self.unescape(s)
192:       s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
193:         [$1.delete('%')].pack('H*')
194:       }
195:     end

Private Class methods

Converts a query string snippet to a hash and adds it to existing parameters.

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.

Returns

Hash:Normalized parameters

:api: private

[Source]

     # 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

[Validate]