Class: Handsoap::Http::Drivers::AbstractDriver
- Inherits:
-
Object
- Object
- Handsoap::Http::Drivers::AbstractDriver
- Defined in:
- lib/handsoap/http/drivers/abstract_driver.rb
Direct Known Subclasses
CurbDriver, EventMachineDriver, HttpClientDriver, MockDriver, NetHttpDriver
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize ⇒ AbstractDriver
constructor
A new instance of AbstractDriver.
-
#parse_headers(raw) ⇒ Object
lifted from webrick/httputils.rb.
-
#parse_http_part(headers, body, status = nil, content_type = nil) ⇒ Object
Parses a raw http response into a
Response
orPart
object. -
#parse_multipart(boundary, content_io, content_length = nil) ⇒ Object
Parses a multipart http-response body into parts.
-
#parse_multipart_boundary(content_type) ⇒ Object
Content-Type header string -> mime-boundary | nil.
Constructor Details
#initialize ⇒ AbstractDriver
Returns a new instance of AbstractDriver.
10 11 12 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 10 def initialize self.class.load! end |
Class Method Details
.load! ⇒ Object
7 8 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 7 def self.load! end |
Instance Method Details
#parse_headers(raw) ⇒ Object
lifted from webrick/httputils.rb
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 138 def parse_headers(raw) header = Hash.new([].freeze) field = nil tmp = raw.gsub(/^(\r\n)+|(\r\n)+$/, '') (tmp.respond_to?(:lines) ? tmp.lines : tmp).each {|line| case line when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om field, value = $1, $2 field.downcase! header[field] = [] unless header.has_key?(field) header[field] << value when /^\s+(.*?)\s*\z/om value = $1 unless field raise "bad header '#{line.inspect}'." end header[field][-1] << " " << value else raise "bad header '#{line.inspect}'." end } header.each {|key, values| values.each {|value| value.strip! value.gsub!(/\s+/, " ") } } header end |
#parse_http_part(headers, body, status = nil, content_type = nil) ⇒ Object
Parses a raw http response into a Response
or Part
object.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 15 def parse_http_part(headers, body, status = nil, content_type = nil) if headers.kind_of? String headers = parse_headers(headers) end headers = headers.inject({}) {|collect,item| collect[item[0].downcase] = item[1]; collect } if content_type.nil? && headers['content-type'] content_type = headers['content-type'].first end boundary = parse_multipart_boundary(content_type) parts = if boundary parse_multipart(boundary, body).map {|raw_part| parse_http_part(raw_part[:head], raw_part[:body]) } end if status.nil? Handsoap::Http::Part.new(headers, body, parts) else Handsoap::Http::Response.new(status, headers, body, parts) end end |
#parse_multipart(boundary, content_io, content_length = nil) ⇒ Object
Parses a multipart http-response body into parts. boundary
is a string of the boundary token. content_io
is either a string or an IO. If it’s an IO, then content_length must be specified. content_length
(optional) is an integer, specifying the length of content_io
This code is lifted from cgi.rb
48 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 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 48 def parse_multipart(boundary, content_io, content_length = nil) if content_io.kind_of? String content_length = content_io.length content_io = StringIO.new(content_io, 'r') elsif !(content_io.kind_of? IO) || content_length.nil? raise "Second argument must be String or IO with content_length" end boundary = "--" + boundary quoted_boundary = Regexp.quote(boundary, "n") buf = "" bufsize = 10 * 1024 boundary_end = "" # start multipart/form-data content_io.binmode if defined? content_io.binmode boundary_size = boundary.size + "\r\n".size content_length -= boundary_size status = content_io.read(boundary_size) if nil == status raise EOFError, "no content body" elsif boundary + "\r\n" != status raise EOFError, "bad content body" end parts = [] loop do head = nil if 10240 < content_length require "tempfile" body = Tempfile.new("Handsoap") else begin require "stringio" body = StringIO.new rescue LoadError require "tempfile" body = Tempfile.new("Handsoap") end end body.binmode if defined? body.binmode until head and /#{quoted_boundary}(?:\r\n|--)/n.match(buf) if (not head) and /\r\n\r\n/n.match(buf) buf = buf.sub(/\A((?:.|\n)*?\r\n)\r\n/n) do head = $1.dup "" end next end if head and ( ("\r\n" + boundary + "\r\n").size < buf.size ) body.print buf[0 ... (buf.size - ("\r\n" + boundary + "\r\n").size)] buf[0 ... (buf.size - ("\r\n" + boundary + "\r\n").size)] = "" end c = if bufsize < content_length content_io.read(bufsize) else content_io.read(content_length) end if c.nil? || c.empty? raise EOFError, "bad content body" end buf.concat(c) content_length -= c.size end buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do body.print $1 if "--" == $2 content_length = -1 end boundary_end = $2.dup "" end body.rewind parts << {:head => head, :body => body.read(body.size)} break if buf.size == 0 break if content_length == -1 end raise EOFError, "bad boundary end of body part" unless boundary_end =~ /--/ parts end |
#parse_multipart_boundary(content_type) ⇒ Object
Content-Type header string -> mime-boundary | nil
35 36 37 38 39 |
# File 'lib/handsoap/http/drivers/abstract_driver.rb', line 35 def parse_multipart_boundary(content_type) if %r|\Amultipart.*boundary=\"?([^\";,]+)\"?|n.match(content_type) $1.dup end end |