lib/net/dav.rb in net_dav-0.2.0 vs lib/net/dav.rb in net_dav-0.2.1
- old
+ new
@@ -9,10 +9,11 @@
end
module Net #:nodoc:
# Implement a WebDAV client
class DAV
+ MAX_REDIRECTS = 10
class NetHttpHandler
attr_writer :user, :pass
def initialize(uri)
@uri = uri
@@ -59,12 +60,11 @@
headers.each_pair { |key, value| req[key] = value } if headers
req.content_type = 'text/xml; charset="utf-8"'
if (@user)
req.basic_auth @user, @pass
end
- res = @http.request(req)
- res.value # raises error if not success
+ res = handle_request(req, headers)
res
end
def request_sending_body(verb, path, body, headers)
req =
@@ -78,12 +78,11 @@
headers.each_pair { |key, value| req[key] = value } if headers
req.content_type = 'text/xml; charset="utf-8"'
if (@user)
req.basic_auth @user, @pass
end
- res = @http.request(req)
- res.value # raises error if not success
+ res = handle_request(req, headers)
res
end
def request_returning_body(verb, path, headers, &block)
req =
@@ -95,16 +94,11 @@
end
headers.each_pair { |key, value| req[key] = value } if headers
if (@user)
req.basic_auth @user, @pass
end
- res = nil
- @http.request(req) {|response|
- response.read_body nil, &block
- res = response
- }
- res.value # raises error if not success
+ res = handle_request(req, headers, MAX_REDIRECTS, &block)
res.body
end
def request(verb, path, body, headers)
req =
@@ -120,24 +114,72 @@
headers.each_pair { |key, value| req[key] = value } if headers
req.content_type = 'text/xml; charset="utf-8"'
if (@user)
req.basic_auth @user, @pass
end
- res = @http.request(req)
- res.value # raises error if not success
+ res = handle_request(req, headers)
res
end
+
+ def handle_request(req, headers, limit = MAX_REDIRECTS, &block)
+ # You should choose better exception.
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
+
+ response = nil
+ if block
+ @http.request(req) {|res|
+ res.read_body nil, &block
+ response = res
+ }
+ else
+ response = @http.request(req)
+ end
+ case response
+ when Net::HTTPSuccess then response
+ when Net::HTTPRedirection then
+ location = URI.parse(response['location'])
+ if (@uri.scheme != location.scheme ||
+ @uri.host != location.host ||
+ @uri.port != location.port)
+ raise "cannot redirect to a different host #{@uri} => #{location}"
+ end
+ new_req = req.class.new(location.path)
+ new_req.body = req.body
+ new_req.body_stream = req.body_stream
+ headers.each_pair { |key, value| new_req[key] = value } if headers
+ if (@user)
+ new_req.basic_auth @user, @pass
+ end
+ handle_request(new_req, limit - 1, &block)
+ else
+ response.error!
+ end
+ end
end
+
class CurlHandler < NetHttpHandler
+ def make_curl
+ unless @curl
+ @curl = Curl::Easy.new
+ @curl.timeout = @http.read_timeout
+ @curl.follow_location = true
+ @curl.max_redirects = MAX_REDIRECTS
+ end
+ @curl
+ end
+
def request_returning_body(verb, path, headers)
raise "unkown returning_body verb #{verb}" unless verb == :get
url = @uri.merge(path)
- curl = Curl::Easy.new(url.to_s)
+ curl = make_curl
+ curl.url = url.to_s
headers.each_pair { |key, value| curl.headers[key] = value } if headers
if (@user)
- curl.headers["Authorization"] = "Basic #{Base64.encode64("#{@user}:#{@pass}")}"
+ curl.userpwd = "#{@user}:#{@pass}"
+ else
+ curl.userpwd = nil
end
res = nil
if block_given?
curl.on_body do |frag|
yield frag
@@ -281,11 +323,11 @@
# entity body in turn as a string as it is read from
# the socket. Note that in this case, the returned response
# object will *not* contain a (meaningful) body.
def get(path, &block)
- @handler.request_returning_body(:get, path, nil, &block)
- true
+ body = @handler.request_returning_body(:get, path, nil, &block)
+ body
end
# Stores the content of a stream to a URL
#
# Example: