Module: Waxx::Http
Overview
Waxx Copyright © 2016 ePark labs Inc. & Daniel J. Fitzpatrick <dan@eparklabs.com> All rights reserved. Released under the Apache Version 2 License. See LICENSE.txt.
Constant Summary collapse
- Status =
{ "200"=>"OK", "206"=>"Partial Content", "300"=>"Multiple Choices", "301"=>"Moved Permanently", "302"=>"Found", "304"=>"Not Modified", "400"=>"Bad Request", "401"=>"Authorization Required", "403"=>"Forbidden", "404"=>"Not Found", "405"=>"Method Not Allowed", "406"=>"Not Acceptable", "411"=>"Length Required", "412"=>"Precondition Failed", "500"=>"Internal Server Error", "501"=>"Method Not Implemented", "502"=>"Bad Gateway", "506"=>"Variant Also Negotiates" }
- ContentTypes =
{ css: "text/css; charset=utf-8", csv: "text/csv; charset=utf-8", htm: "text/html; charset=utf-8", html: "text/html; charset=utf-8", jpg: "image/jpeg", js: "application/javascript; charset=utf-8", json: "application/json; charset=utf-8", tab: "text/tab-separated-values; charset=utf-8", txt: "text/plain; charset=utf-8", xml: "text/xml", gif: "image/gif", jpeg: "image/jpeg", atom: "application/atom+xml", rss: "application/rss+xml", mml: "text/mathml", jad: "text/vnd.sun.j2me.app-descriptor", wml: "text/vnd.wap.wml", htc: "text/x-component", png: "image/png", tif: "image/tiff", tiff: "image/tiff", wbmp: "image/vnd.wap.wbmp", ico: "image/x-icon", jng: "image/x-jng", bmp: "image/x-ms-bmp", svg: "image/svg+xml", svgz: "image/svg+xml", webp: "image/webp", woff: "application/font-woff", jar: "application/java-archive", war: "application/java-archive", ear: "application/java-archive", hqx: "application/mac-binhex40", doc: "application/msword", pdf: "application/pdf", ps: "application/postscript", eps: "application/postscript", ai: "application/postscript", rtf: "application/rtf", m3u8: "application/vnd.apple.mpegurl", xls: "application/vnd.ms-excel", eot: "application/vnd.ms-fontobject", ppt: "application/vnd.ms-powerpoint", wmlc: "application/vnd.wap.wmlc", kml: "application/vnd.google-earth.kml+xml", kmz: "application/vnd.google-earth.kmz", cco: "application/x-cocoa", jardiff: "application/x-java-archive-diff", jnlp: "application/x-java-jnlp-file", run: "application/x-makeself", pl: "application/x-perl", pm: "application/x-perl", prc: "application/x-pilot", pdb: "application/x-pilot", rar: "application/x-rar-compressed", rpm: "application/x-redhat-package-manager", sea: "application/x-sea", swf: "application/x-shockwave-flash", sit: "application/x-stuffit", tcl: "application/x-tcl", tk: "application/x-tcl", der: "application/x-x509-ca-cert", pem: "application/x-x509-ca-cert", crt: "application/x-x509-ca-cert", xpi: "application/x-xpinstall", xhtml: "application/xhtml+xml", xspf: "application/xspf+xml", zip: "application/zip", bin: "application/octet-stream", exe: "application/octet-stream", dll: "application/octet-stream", deb: "application/octet-stream", dmg: "application/octet-stream", iso: "application/octet-stream", img: "application/octet-stream", msi: "application/octet-stream", msp: "application/octet-stream", msm: "application/octet-stream", docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", mid: "audio/midi", midi: "audio/midi", kar: "audio/midi", mp3: "audio/mpeg", ogg: "audio/ogg", m4a: "audio/x-m4a", ra: "audio/x-realaudio", ts: "video/mp2t", mp4: "video/mp4", mpeg: "video/mpeg", mpg: "video/mpeg", mov: "video/quicktime", webm: "video/webm", flv: "video/x-flv", m4v: "video/x-m4v", mng: "video/x-mng", asx: "video/x-ms-asf", asf: "video/x-ms-asf", wmv: "video/x-ms-wmv", avi: "video/x-msvideo", }
Instance Method Summary collapse
- #content_type(t, default = "application/octet-stream") ⇒ Object (also: #ctype)
- #content_types ⇒ Object
- #escape(str) ⇒ Object (also: #qs)
- #parse_cookie(str) ⇒ Object
- #parse_data(env, meth, io, head) ⇒ Object
- #parse_head(io) ⇒ Object
- #parse_multipart(env, data) ⇒ Object
- #query_string_to_hash(str, base = {}) ⇒ Object
- #time(t = Time.new.utc) ⇒ Object
- #unescape(str) ⇒ Object
Instance Method Details
#content_type(t, default = "application/octet-stream") ⇒ Object Also known as: ctype
11 12 13 |
# File 'waxx/http.rb', line 11 def content_type(t, default="application/octet-stream") ContentTypes[t.to_sym] || default end |
#content_types ⇒ Object
7 8 9 |
# File 'waxx/http.rb', line 7 def content_types ContentTypes end |
#escape(str) ⇒ Object Also known as: qs
20 21 22 23 24 |
# File 'waxx/http.rb', line 20 def escape(str) str.to_s.gsub(/([^a-zA-Z0-9_.-]+)/) do |m| '%' + m.unpack('H2' * m.bytesize).join('%').upcase end end |
#parse_cookie(str) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'waxx/http.rb', line 90 def (str) Waxx.debug "parse_cookie" re = {} return re if str.nil? or str == "" str.split(/[;,]\s?/).each do |pairs| name, values = pairs.split('=',2) next unless name and values name = unescape(name) vals = values.split('&').collect{|v| unescape(v) } if re.has_key?(name) Waxx.debug "re has key" if Array === re[name] re[name].push vals else re[name] = [re[name], vals] end else re[name] = vals end re[name].flatten! end re.freeze re end |
#parse_data(env, meth, io, head) ⇒ Object
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 |
# File 'waxx/http.rb', line 115 def parse_data(env, meth, io, head) Waxx.debug "parse_data" if %w(PUT POST PATCH).include? meth data = io.read(env['Content-Length'].to_i) Waxx.debug "data.size: #{data.size} #{env['Content-Type']}" if env['Content-Length'].to_i == 0 post = {}.freeze data = nil else case (env['Content-Type'] || env['content-type'] || env['Content-type']) when /x-www-form-urlencoded/ post = query_string_to_hash(data).freeze when /multipart/ post = parse_multipart(env, data).freeze when /json/ post = (JSON.parse(data)).freeze else post = data.freeze end end else post = {}.freeze data = nil end [post, data] end |
#parse_head(io) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'waxx/http.rb', line 33 def parse_head(io) Waxx.debug("parse_head: #{io.class}", 9) env = {} head = "" while(e = io.gets) break if e.strip == "" head << e n, v = e.split(":", 2) env[n] = v.strip end Waxx.debug "env.size: #{env.size}", 9 [env, head] end |
#parse_multipart(env, data) ⇒ Object
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 |
# File 'waxx/http.rb', line 62 def parse_multipart(env, data) boundary = env['Content-Type'].match(/boundary=(.*)$/)[1] parts = data.split("--"+boundary+"\r\n") post = {} parts.each{|part| next if part.strip == "" begin head, body = part.split("\r\n\r\n",2) headers = Hash[*(head.split("\r\n").map{|hp| hp.split(":",2).map{|i| i.strip}}.flatten)] cd = Hash[*("_=#{headers['Content-Disposition']}".split(";").map{|da| da.strip.gsub('"',"").split("=",2)}.flatten)] if cd['filename'] post[cd['name']] = { filename: cd['filename'], data: body.sub(/\r\n--#{boundary}--\r\n$/,"").sub(/\r\n$/,""), content_type: headers['Content-Type'], headers: headers } else post[cd['name']] = body.sub(/\r\n--#{boundary}--\r\n$/,"").sub(/\r\n$/,"") end rescue => e Waxx.debug "Error parse_multipart: #{e}" post["Error in parse_multipart (uid-#{rand})"] = e end } post end |
#query_string_to_hash(str, base = {}) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'waxx/http.rb', line 47 def query_string_to_hash(str, base={}) return base if str.nil? or str.strip == "" str.strip.split(/[;&]/).each{|nv| n, v = nv.split("=",2).map{|s| unescape(s)} if n =~ /\[\]$/ n = n.sub(/\[\]$/,"") base[n] ||= [] base[n] << v else base[n] = v end } base end |
#time(t = Time.new.utc) ⇒ Object
16 17 18 |
# File 'waxx/http.rb', line 16 def time(t=Time.new.utc) t.strftime('%a, %d %b %Y %H:%M:%S UTC') end |
#unescape(str) ⇒ Object
27 28 29 30 31 |
# File 'waxx/http.rb', line 27 def unescape(str) str.to_s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do |m| [m.delete('%')].pack('H*') end end |