Below is a patch file that adds two features:
1. Allows redirects from inital "POST" requests.
2. Allows submitting multipart forms.
Please feel free to incorporate into future versions of http-access2. Thanks.
diff -cNr http-access-2_0_5/lib/http-access2/http.rb http-access-2_0_5.patched/lib/http-access2/http.rb
*** http-access-2_0_5/lib/http-access2/http.rb Thu Dec 9 17:17:41 2004
--- http-access-2_0_5.patched/lib/http-access2/http.rb Mon Apr 4 07:58:41 2005
***************
*** 5,11 ****
# You can redistribute it and/or modify it under the same term as Ruby.
require 'uri'
!
module HTTP
--- 5,11 ----
# You can redistribute it and/or modify it under the same term as Ruby.
require 'uri'
! require 'time'
module HTTP
***************
*** 288,296 ****
class Body
attr_accessor :type, :charset, :date, :chunk_size
! def initialize(body = nil, date = nil, type = nil, charset = nil)
@body = nil
! set_content(body || '')
@type = type
@charset = charset
@date = date
--- 288,297 ----
class Body
attr_accessor :type, :charset, :date, :chunk_size
! def initialize(body = nil, date = nil, type = nil, charset = nil, boundary = nil)
@body = nil
! @boundary = boundary
! set_content(body || '', boundary)
@type = type
@charset = charset
@date = date
***************
*** 326,334 ****
@body
end
! def set_content(body)
if body.respond_to?(:read)
@body = body
else
@body = Message.create_query_part_str(body)
end
--- 327,337 ----
@body
end
! def set_content(body, boundary = nil)
if body.respond_to?(:read)
@body = body
+ elsif boundary
+ @body = Message.create_query_multipart_str(body, boundary)
else
@body = Message.create_query_part_str(body)
end
***************
*** 358,368 ****
undef new
end
! def self.new_request(method, uri, query = nil, body = nil, proxy = nil)
m = self.__new
m.header = Headers.new
m.header.init_request(method, uri, query, proxy)
! m.body = Body.new(body)
m
end
--- 361,371 ----
undef new
end
! def self.new_request(method, uri, query = nil, body = nil, proxy = nil, boundary = nil)
m = self.__new
m.header = Headers.new
m.header.init_request(method, uri, query, proxy)
! m.body = Body.new(body, nil, nil, nil, boundary)
m
end
***************
*** 452,457 ****
--- 455,493 ----
end
end
+ def mime_type(path)
+ case path
+ when /.(htm|html)$/
+ 'text/html'
+ when /.doc$/
+ 'application/msword'
+ else
+ 'text/plain'
+ end
+ end
+
+ def create_query_multipart_str(query, boundary)
+ query.collect { |attr, value|
+ value ||= ''
+ if value.is_a? File
+ params = {
+ 'filename' => value.path,
+ # 'creation-date' => value.ctime.rfc822, # Creation time is not available from File::Stat
+ 'modification-date' => value.mtime.rfc822,
+ 'read-date' => value.atime.rfc822,
+ }
+ param_str = params.to_a.collect {|k, v| "#{k}=\"#{v}\""}.join("; ")
+ "--#{boundary}\n" +
+ %{Content-Disposition: form-data; name="#{attr.to_s}"; #{param_str}\n} +
+ "Content-Type: #{mime_type(value.path)}\n\n#{value.read}\n"
+ else
+ "--#{boundary}\n" +
+ %{Content-Disposition: form-data; name="#{attr.to_s}"\n} +
+ "\n#{value.to_s}\n"
+ end
+ }.join('') + "--#{boundary}--\n"
+ end
+
def escape_query(query)
query.collect { |attr, value|
escape(attr.to_s) << '=' << escape(value.to_s)
diff -cNr http-access-2_0_5/lib/http-access2.rb http-access-2_0_5.patched/lib/http-access2.rb
*** http-access-2_0_5/lib/http-access2.rb Thu Dec 16 07:40:24 2004
--- http-access-2_0_5.patched/lib/http-access2.rb Mon Apr 4 08:07:44 2005
***************
*** 218,224 ****
end
# SYNOPSIS
! # Client#get_content(uri, query = nil, extheader = {}, &block = nil)
#
# ARGS
# uri an_URI or a_string of uri to connect.
--- 218,224 ----
end
# SYNOPSIS
! # Client#get_content(uri, query = nil, extheader = {}, method = 'get', &block = nil)
#
# ARGS
# uri an_URI or a_string of uri to connect.
***************
*** 227,243 ****
# [["a" => "b"], ["a" => "c"]].
# extheader
# a_hash of extra headers like { "SOAPAction" => "urn:foo" }.
# &block Give a block to get chunked message-body of response like
# get_content(uri) { |chunked_body| ... }
# Size of each chunk may not be the same.
#
# DESCRIPTION
! # Get a_sring of message-body of response.
#
! def get_content(uri, query = nil, extheader = {}, &block)
retry_number = 0
while retry_number < 10
! res = get(uri, query, extheader, &block)
if res.status == HTTP::Status::OK
return res.content
elsif HTTP::Status.redirect?(res.status)
--- 227,248 ----
# [["a" => "b"], ["a" => "c"]].
# extheader
# a_hash of extra headers like { "SOAPAction" => "urn:foo" }.
+ # method
+ # a_string of the HTTP method to use. e.g. "post".
# &block Give a block to get chunked message-body of response like
# get_content(uri) { |chunked_body| ... }
# Size of each chunk may not be the same.
#
# DESCRIPTION
! # Get a_sring of message-body of response. This handles up to 10
! # redirects. Redirects always use the 'get' HTTP method.
#
! def get_content(uri, query = nil, extheader = {}, method = 'get', &block)
retry_number = 0
+ method = method.downcase.intern
while retry_number < 10
! res = send(method, uri, query, extheader, &block)
! method = :get
if res.status == HTTP::Status::OK
return res.content
elsif HTTP::Status.redirect?(res.status)
***************
*** 375,381 ****
extheader << ['Cookie', cookies]
end
end
! req = HTTP::Message.new_request(method, uri, query, body, proxy)
extheader.each do |key, value|
req.header.set(key, value)
end
--- 380,391 ----
extheader << ['Cookie', cookies]
end
end
! boundary = nil
! contentType = extheader.detect {|key, value| key == 'Content-Type'}
! if contentType && contentType[1] =~ /boundary=(.+)$/
! boundary = $1
! end
! req = HTTP::Message.new_request(method, uri, query, body, proxy, boundary)
extheader.each do |key, value|
req.header.set(key, value)
end
***************
*** 1335,1341 ****
end
# Read status block.
! StatusParseRegexp = %r(\AHTTP/(\d+\.\d+)\s+(\d+)(?:\s+(.*))?#{ RS }\z)
def read_header
if @state == :DATA
get_data {}
--- 1345,1351 ----
end
# Read status block.
! StatusParseRegexp = %r(\A\000?HTTP/(\d+\.\d+)\s+(\d+)(?:\s+(.*))?#{ RS }\z)
def read_header
if @state == :DATA
get_data {}
{{{
}}}