| Module | WEBrick::HTTPUtils |
| In: |
lib/webrick/httputils.rb
|
| DefaultMimeTypes | = | { "ai" => "application/postscript", "asc" => "text/plain", "avi" => "video/x-msvideo", "bin" => "application/octet-stream", "bmp" => "image/bmp", "class" => "application/octet-stream", "cer" => "application/pkix-cert", "crl" => "application/pkix-crl", "crt" => "application/x-x509-ca-cert", #"crl" => "application/x-pkcs7-crl", "css" => "text/css", "dms" => "application/octet-stream", "doc" => "application/msword", "dvi" => "application/x-dvi", "eps" => "application/postscript", "etx" => "text/x-setext", "exe" => "application/octet-stream", "gif" => "image/gif", "htm" => "text/html", "html" => "text/html", "jpe" => "image/jpeg", "jpeg" => "image/jpeg", "jpg" => "image/jpeg", "lha" => "application/octet-stream", "lzh" => "application/octet-stream", "mov" => "video/quicktime", "mpe" => "video/mpeg", "mpeg" => "video/mpeg", "mpg" => "video/mpeg", "pbm" => "image/x-portable-bitmap", "pdf" => "application/pdf", "pgm" => "image/x-portable-graymap", "png" => "image/png", "pnm" => "image/x-portable-anymap", "ppm" => "image/x-portable-pixmap", "ppt" => "application/vnd.ms-powerpoint", "ps" => "application/postscript", "qt" => "video/quicktime", "ras" => "image/x-cmu-raster", "rb" => "text/plain", "rd" => "text/plain", "rtf" => "application/rtf", "sgm" => "text/sgml", "sgml" => "text/sgml", "tif" => "image/tiff", "tiff" => "image/tiff", "txt" => "text/plain", "xbm" => "image/x-xbitmap", "xls" => "application/vnd.ms-excel", "xml" => "text/xml", "xpm" => "image/x-xpixmap", "xwd" => "image/x-xwindowdump", "zip" => "application/zip", } | ||
| UNESCAPED | = | _make_regex(control+space+delims+unwise+nonascii) | ||
| UNESCAPED_FORM | = | _make_regex(reserved+control+delims+unwise+nonascii) | ||
| NONASCII | = | _make_regex(nonascii) | ||
| ESCAPED | = | /%([0-9a-fA-F]{2})/ | ||
| UNESCAPED_PCHAR | = | _make_regex!(unreserved+":@&=+$,") |
# File lib/webrick/httputils.rb, line 360
360: def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end
# File lib/webrick/httputils.rb, line 358
358: def _make_regex(str) /([#{Regexp.escape(str)}])/n end
359: def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
360: def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end
361: def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end
362:
363: UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
364: UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
365: NONASCII = _make_regex(nonascii)
366: ESCAPED = /%([0-9a-fA-F]{2})/
367: UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
368:
369: def escape(str)
370: _escape(str, UNESCAPED)
371: end
372:
373: def unescape(str)
374: _unescape(str, ESCAPED)
375: end
376:
377: def escape_form(str)
378: ret = _escape(str, UNESCAPED_FORM)
379: ret.gsub!(/ /, "+")
380: ret
381: end
382:
383: def unescape_form(str)
384: _unescape(str.gsub(/\+/, " "), ESCAPED)
385: end
386:
387: def escape_path(str)
388: result = ""
389: str.scan(%r{/([^/]*)}).each{|i|
390: result << "/" << _escape(i[0], UNESCAPED_PCHAR)
391: }
392: return result
393: end
394:
395: def escape8bit(str)
396: _escape(str, NONASCII)
397: end
398: end
399: end
# File lib/webrick/httputils.rb, line 359
359: def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
360: def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1[0] } end
361: def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end
362:
363: UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
364: UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
365: NONASCII = _make_regex(nonascii)
366: ESCAPED = /%([0-9a-fA-F]{2})/
367: UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
368:
369: def escape(str)
370: _escape(str, UNESCAPED)
371: end
372:
373: def unescape(str)
374: _unescape(str, ESCAPED)
375: end
376:
377: def escape_form(str)
378: ret = _escape(str, UNESCAPED_FORM)
379: ret.gsub!(/ /, "+")
380: ret
381: end
382:
383: def unescape_form(str)
384: _unescape(str.gsub(/\+/, " "), ESCAPED)
385: end
386:
387: def escape_path(str)
388: result = ""
389: str.scan(%r{/([^/]*)}).each{|i|
390: result << "/" << _escape(i[0], UNESCAPED_PCHAR)
391: }
392: return result
393: end
394:
395: def escape8bit(str)
396: _escape(str, NONASCII)
397: end
398: end
# File lib/webrick/httputils.rb, line 361
361: def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end
# File lib/webrick/httputils.rb, line 197
197: def dequote(str)
198: ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
199: ret.gsub!(/\\(.)/, "\\1")
200: ret
201: end
# File lib/webrick/httputils.rb, line 369
369: def escape(str)
370: _escape(str, UNESCAPED)
371: end
# File lib/webrick/httputils.rb, line 395
395: def escape8bit(str)
396: _escape(str, NONASCII)
397: end
# File lib/webrick/httputils.rb, line 377
377: def escape_form(str)
378: ret = _escape(str, UNESCAPED_FORM)
379: ret.gsub!(/ /, "+")
380: ret
381: end
# File lib/webrick/httputils.rb, line 387
387: def escape_path(str)
388: result = ""
389: str.scan(%r{/([^/]*)}).each{|i|
390: result << "/" << _escape(i[0], UNESCAPED_PCHAR)
391: }
392: return result
393: end
Load Apache compatible mime.types file.
# File lib/webrick/httputils.rb, line 101
101: def load_mime_types(file)
102: open(file){ |io|
103: hash = Hash.new
104: io.each{ |line|
105: next if /^#/ =~ line
106: line.chomp!
107: mimetype, ext0 = line.split(/\s+/, 2)
108: next unless ext0
109: next if ext0.empty?
110: ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
111: }
112: hash
113: }
114: end
# File lib/webrick/httputils.rb, line 117
117: def mime_type(filename, mime_tab)
118: suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
119: suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
120: mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
121: end
# File lib/webrick/httputils.rb, line 21
21: def normalize_path(path)
22: raise "abnormal path `#{path}'" if path[0] != ?/
23: ret = path.dup
24:
25: ret.gsub!(%r{/+}o, '/') # // => /
26: while ret.sub!(%r{/\.(/|\Z)}o, '/'); end # /. => /
27: begin # /foo/.. => /foo
28: match = ret.sub!(%r{/([^/]+)/\.\.(/|\Z)}o){
29: if $1 == ".."
30: raise "abnormal path `#{path}'"
31: else
32: "/"
33: end
34: }
35: end while match
36:
37: raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
38: ret
39: end
# File lib/webrick/httputils.rb, line 314
314: def parse_form_data(io, boundary)
315: boundary_regexp = /\A--#{boundary}(--)?#{CRLF}\z/
316: form_data = Hash.new
317: return form_data unless io
318: data = nil
319: io.each{|line|
320: if boundary_regexp =~ line
321: if data
322: data.chop!
323: key = data.name
324: if form_data.has_key?(key)
325: form_data[key].append_data(data)
326: else
327: form_data[key] = data
328: end
329: end
330: data = FormData.new
331: next
332: else
333: if data
334: data << line
335: end
336: end
337: }
338: return form_data
339: end
# File lib/webrick/httputils.rb, line 126
126: def parse_header(raw)
127: header = Hash.new([].freeze)
128: field = nil
129: raw.each{|line|
130: case line
131: when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
132: field, value = $1, $2
133: field.downcase!
134: header[field] = [] unless header.has_key?(field)
135: header[field] << value
136: when /^\s+(.*?)\s*\z/om
137: value = $1
138: unless field
139: raise "bad header '#{line.inspect}'."
140: end
141: header[field][-1] << " " << value
142: else
143: raise "bad header '#{line.inspect}'."
144: end
145: }
146: header.each{|key, values|
147: values.each{|value|
148: value.strip!
149: value.gsub!(/\s+/, " ")
150: }
151: }
152: header
153: end
# File lib/webrick/httputils.rb, line 293
293: def parse_query(str)
294: query = Hash.new
295: if str
296: str.split(/[&;]/).each{|x|
297: next if x.empty?
298: key, val = x.split(/=/,2)
299: key = unescape_form(key)
300: val = unescape_form(val.to_s)
301: val = FormData.new(val)
302: val.name = key
303: if query.has_key?(key)
304: query[key].append_data(val)
305: next
306: end
307: query[key] = val
308: }
309: end
310: query
311: end
# File lib/webrick/httputils.rb, line 177
177: def parse_qvalues(value)
178: tmp = []
179: if value
180: parts = value.split(/,\s*/)
181: parts.each {|part|
182: if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
183: val = m[1]
184: q = (m[2] or 1).to_f
185: tmp.push([val, q])
186: end
187: }
188: tmp = tmp.sort_by{|val, q| -q}
189: tmp.collect!{|val, q| val}
190: end
191: return tmp
192: end
# File lib/webrick/httputils.rb, line 162
162: def parse_range_header(ranges_specifier)
163: if /^bytes=(.*)/ =~ ranges_specifier
164: byte_range_set = split_header_value($1)
165: byte_range_set.collect{|range_spec|
166: case range_spec
167: when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
168: when /^(\d+)-/ then $1.to_i .. -1
169: when /^-(\d+)/ then -($1.to_i) .. -1
170: else return nil
171: end
172: }
173: end
174: end
# File lib/webrick/httputils.rb, line 204
204: def quote(str)
205: '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
206: end
# File lib/webrick/httputils.rb, line 156
156: def split_header_value(str)
157: str.scan(/((?:"(?:\\.|[^"])+?"|[^",]+)+)
158: (?:,\s*|\Z)/xn).collect{|v| v[0] }
159: end
# File lib/webrick/httputils.rb, line 373
373: def unescape(str)
374: _unescape(str, ESCAPED)
375: end