Module: Merb::Parse
- Defined in:
- lib/merb-core/dispatch/request_parsers.rb
Constant Summary collapse
- 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
Class Method Summary collapse
-
.escape(s) ⇒ Object
Parameters s<String>:: String to URL escape.
-
.escape_xml(s) ⇒ Object
Parameters s<String>:: String to XML escape.
-
.multipart(request, boundary, content_length) ⇒ Object
Parameters request<IO>:: The raw request.
-
.params_to_query_string(value, prefix = nil) ⇒ Object
Parameters value<Array, Hash, Dictionary ~to_s>:: The value for the query string.
-
.query(query_string, delimiter = '&;', preserve_order = false) ⇒ Object
Parameters query_string<String>:: The query string.
-
.unescape(s, encoding = nil) ⇒ Object
Parameter s<String>:: String to URL unescape.
Class Method Details
.escape(s) ⇒ Object
Parameters
- s<String>
-
String to URL escape.
returns
- String
-
The escaped string.
:api: public
187 188 189 190 191 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 187 def self.escape(s) s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { '%'+$1.unpack('H2'*$1.size).join('%').upcase }.tr(' ', '+') end |
.escape_xml(s) ⇒ Object
Parameters
- s<String>
-
String to XML escape.
returns
- String
-
The escaped string.
:api: public
222 223 224 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 222 def self.escape_xml(s) Erubis::XmlHelper.escape_xml(s) end |
.multipart(request, boundary, content_length) ⇒ Object
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
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 49 def self.multipart(request, boundary, content_length) boundary = "--#{boundary}" paramhsh = {} buf = "" input = request input.binmode if defined? input.binmode boundary_size = boundary.size + EOL.size bufsize = 16384 content_length -= boundary_size key_memo = [] # status is boundary delimiter line status = input.read(boundary_size) return {} if status == nil || status.empty? raise ControllerExceptions::MultiPartParseError, "bad content body:\n'#{status}' should == '#{boundary + EOL}'" unless status == boundary + EOL rx = /(?:#{EOL})?#{Regexp.quote(boundary)}(#{EOL}|--)/n loop { head = nil body = '' filename = content_type = name = nil read_size = 0 until head && buf =~ rx i = buf.index("\r\n\r\n") if( i == nil && read_size == 0 && content_length == 0 ) content_length = -1 break end if !head && i head = buf.slice!(0, i+2) # First \r\n buf.slice!(0, 2) # Second \r\n # String#[] with 2nd arg here is returning # a group from match data filename = head[FILENAME_REGEX, 1] content_type = head[CONTENT_TYPE_REGEX, 1] name = head[NAME_REGEX, 1] if filename && !filename.empty? body = Tempfile.new(:Merb) body.binmode if defined? body.binmode end next end # Save the read body part. if head && (boundary_size+4 < buf.size) body << buf.slice!(0, buf.size - (boundary_size+4)) end read_size = bufsize < content_length ? bufsize : content_length if( read_size > 0 ) c = input.read(read_size) raise ControllerExceptions::MultiPartParseError, "bad content body" if c.nil? || c.empty? buf << c content_length -= c.size end end # Save the rest. if i = buf.index(rx) # correct value of i for some edge cases if (i > 2) && (j = buf.index(rx, i-2)) && (j < i) i = j end body << buf.slice!(0, i) buf.slice!(0, boundary_size+2) content_length = -1 if $1 == "--" end if filename && !filename.empty? body.rewind data = { :filename => File.basename(filename), :content_type => content_type, :tempfile => body, :size => File.size(body.path) } else data = body end unless key_memo.include?(name) && name !~ /\[\]/ paramhsh = normalize_params(paramhsh,name,data) end # Prevent from double processing files but process other params key_memo << name if filename && !filename.empty? break if buf.empty? || content_length == -1 } paramhsh end |
.params_to_query_string(value, prefix = nil) ⇒ Object
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
165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 165 def self.params_to_query_string(value, prefix = nil) case value when Array value.map { |v| params_to_query_string(v, "#{prefix}[]") } * "&" when Hash, Dictionary value.map { |k, v| params_to_query_string(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) } * "&" else "#{prefix}=#{escape(value)}" end end |
.query(query_string, delimiter = '&;', preserve_order = false) ⇒ Object
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
17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 17 def self.query(query_string, delimiter = '&;', preserve_order = false) query = preserve_order ? Dictionary.new : {} for pair in (query_string || '').split(/[#{delimiter}] */n) key, value = unescape(pair).split('=',2) next if key.nil? if key.include?('[') normalize_params(query, key, value) else query[key] = value end end preserve_order ? query : query.to_mash end |
.unescape(s, encoding = nil) ⇒ Object
Parameter
- s<String>
-
String to URL unescape.
- encoding<String>
-
Encoding which we force to return. Only for Ruby 1.9. If encoding is not passed it defaults to Encoding.default_internal. When this is nil (default) no encoding forcing is done.
returns
- String
-
The unescaped string.
:api: public
204 205 206 207 208 209 210 211 212 213 |
# File 'lib/merb-core/dispatch/request_parsers.rb', line 204 def self.unescape(s, encoding = nil) s = s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') } if RUBY_VERSION >= '1.9' encoding ||= Encoding.default_internal s.force_encoding(encoding) if encoding end s end |