Module: Handsoap::Http
- Defined in:
- lib/handsoap/http.rb
Overview
The Handsoap::Http module provides a uniform interface to various http drivers.
Defined Under Namespace
Modules: Curb, Httpclient, NetHttp Classes: Part, Request, Response
Constant Summary collapse
- @@drivers =
{ :net_http => NetHttp, :curb => Curb, :httpclient => Httpclient }
Class Method Summary collapse
- .drivers ⇒ Object
- .normalize_header_key(key) ⇒ Object
-
.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
ResponseorPartobject. -
.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.
Class Method Details
.drivers ⇒ Object
402 403 404 |
# File 'lib/handsoap/http.rb', line 402 def self.drivers @@drivers end |
.normalize_header_key(key) ⇒ Object
392 393 394 |
# File 'lib/handsoap/http.rb', line 392 def self.normalize_header_key(key) key.split("-").map{|s| s.downcase.capitalize }.join("-") end |
.parse_headers(raw) ⇒ Object
lifted from webrick/httputils.rb
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/handsoap/http.rb', line 363 def self.parse_headers(raw) header = Hash.new([].freeze) field = nil raw.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.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/handsoap/http.rb', line 241 def self.parse_http_part(headers, body, status = nil, content_type = nil) if headers.kind_of? String headers = parse_headers(headers) end 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
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'lib/handsoap/http.rb', line 273 def self.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
260 261 262 263 264 |
# File 'lib/handsoap/http.rb', line 260 def self.parse_multipart_boundary(content_type) if %r|\Amultipart.*boundary=\"?([^\";,]+)\"?|n.match(content_type) $1.dup end end |