net_dav 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -1
- data/VERSION +1 -1
- data/bin/dav +4 -2
- data/lib/net/dav.rb +82 -21
- data/net_dav.gemspec +2 -2
- metadata +2 -2
data/Rakefile
CHANGED
@@ -36,7 +36,11 @@ task :spec => :check_dependencies
|
|
36
36
|
|
37
37
|
task :default => :spec
|
38
38
|
|
39
|
-
task
|
39
|
+
task "dist" => [:clean, :release]
|
40
|
+
|
41
|
+
task "dist:patch" => [:clean, "version:bump:patch", :release]
|
42
|
+
|
43
|
+
task "dist:minor" => [:clean, "version:bump:minor", :release]
|
40
44
|
|
41
45
|
task :clean do
|
42
46
|
Dir.glob("**/*~").each do |file|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/dav
CHANGED
@@ -6,6 +6,9 @@ require 'net/dav'
|
|
6
6
|
|
7
7
|
dav_user = ENV['DAVUSER']
|
8
8
|
dav_pass = ENV['DAVPASS']
|
9
|
+
disable_basic_auth = (ENV['DISABLE_BASIC_AUTH'] && ENV['DISABLE_BASIC_AUTH'] != "0")
|
10
|
+
enable_curl = !(ENV['DISABLE_CURL'] && ENV['DISABLE_CURL'] != "0")
|
11
|
+
|
9
12
|
cmd = $*[0]
|
10
13
|
|
11
14
|
def print_usage
|
@@ -36,9 +39,8 @@ else
|
|
36
39
|
url = URI.parse $*[1]
|
37
40
|
end
|
38
41
|
|
39
|
-
enable_curl = !(ENV['DISABLE_CURL'] && ENV['DISABLE_CURL'] != "0")
|
40
|
-
|
41
42
|
dav = Net::DAV.new(url, :curl => enable_curl)
|
43
|
+
dav.disable_basic_auth = disable_basic_auth
|
42
44
|
|
43
45
|
if (url.scheme == 'https')
|
44
46
|
dav.verify_callback = lambda do |preverify_ok, x509_store|
|
data/lib/net/dav.rb
CHANGED
@@ -3,6 +3,7 @@ require 'uri'
|
|
3
3
|
require 'nokogiri'
|
4
4
|
require 'net/dav/item'
|
5
5
|
require 'base64'
|
6
|
+
require 'digest/md5'
|
6
7
|
begin
|
7
8
|
require 'curb'
|
8
9
|
rescue LoadError
|
@@ -15,6 +16,8 @@ module Net #:nodoc:
|
|
15
16
|
class NetHttpHandler
|
16
17
|
attr_writer :user, :pass
|
17
18
|
|
19
|
+
attr_accessor :disable_basic_auth
|
20
|
+
|
18
21
|
def verify_callback=(callback)
|
19
22
|
@http.verify_callback = callback
|
20
23
|
end
|
@@ -24,6 +27,7 @@ module Net #:nodoc:
|
|
24
27
|
end
|
25
28
|
|
26
29
|
def initialize(uri)
|
30
|
+
@disable_basic_auth = false
|
27
31
|
@uri = uri
|
28
32
|
case @uri.scheme
|
29
33
|
when "http"
|
@@ -69,9 +73,6 @@ module Net #:nodoc:
|
|
69
73
|
req.content_length = length
|
70
74
|
headers.each_pair { |key, value| req[key] = value } if headers
|
71
75
|
req.content_type = 'text/xml; charset="utf-8"'
|
72
|
-
if (@user)
|
73
|
-
req.basic_auth @user, @pass
|
74
|
-
end
|
75
76
|
res = handle_request(req, headers)
|
76
77
|
res
|
77
78
|
end
|
@@ -87,9 +88,6 @@ module Net #:nodoc:
|
|
87
88
|
req.body = body
|
88
89
|
headers.each_pair { |key, value| req[key] = value } if headers
|
89
90
|
req.content_type = 'text/xml; charset="utf-8"'
|
90
|
-
if (@user)
|
91
|
-
req.basic_auth @user, @pass
|
92
|
-
end
|
93
91
|
res = handle_request(req, headers)
|
94
92
|
res
|
95
93
|
end
|
@@ -103,9 +101,6 @@ module Net #:nodoc:
|
|
103
101
|
raise "unkown returning_body verb #{verb}"
|
104
102
|
end
|
105
103
|
headers.each_pair { |key, value| req[key] = value } if headers
|
106
|
-
if (@user)
|
107
|
-
req.basic_auth @user, @pass
|
108
|
-
end
|
109
104
|
res = handle_request(req, headers, MAX_REDIRECTS, &block)
|
110
105
|
res.body
|
111
106
|
end
|
@@ -123,9 +118,6 @@ module Net #:nodoc:
|
|
123
118
|
req.body = body
|
124
119
|
headers.each_pair { |key, value| req[key] = value } if headers
|
125
120
|
req.content_type = 'text/xml; charset="utf-8"'
|
126
|
-
if (@user)
|
127
|
-
req.basic_auth @user, @pass
|
128
|
-
end
|
129
121
|
res = handle_request(req, headers)
|
130
122
|
res
|
131
123
|
end
|
@@ -144,7 +136,21 @@ module Net #:nodoc:
|
|
144
136
|
response = @http.request(req)
|
145
137
|
end
|
146
138
|
case response
|
147
|
-
when Net::HTTPSuccess then
|
139
|
+
when Net::HTTPSuccess then
|
140
|
+
return response
|
141
|
+
when Net::HTTPUnauthorized then
|
142
|
+
response.error! unless @user
|
143
|
+
response.error! if req['authorization']
|
144
|
+
new_req = clone_req(req.path, req, headers)
|
145
|
+
if response['www-authenticate'] =~ /^Basic/
|
146
|
+
if disable_basic_auth
|
147
|
+
raise "server requested basic auth, but that is disabled"
|
148
|
+
end
|
149
|
+
new_req.basic_auth @user, @pass
|
150
|
+
else
|
151
|
+
digest_auth(new_req, @user, @pass, response)
|
152
|
+
end
|
153
|
+
return handle_request(new_req, headers, limit - 1, &block)
|
148
154
|
when Net::HTTPRedirection then
|
149
155
|
location = URI.parse(response['location'])
|
150
156
|
if (@uri.scheme != location.scheme ||
|
@@ -152,18 +158,56 @@ module Net #:nodoc:
|
|
152
158
|
@uri.port != location.port)
|
153
159
|
raise "cannot redirect to a different host #{@uri} => #{location}"
|
154
160
|
end
|
155
|
-
new_req =
|
156
|
-
new_req
|
157
|
-
new_req.body_stream = req.body_stream
|
158
|
-
headers.each_pair { |key, value| new_req[key] = value } if headers
|
159
|
-
if (@user)
|
160
|
-
new_req.basic_auth @user, @pass
|
161
|
-
end
|
162
|
-
handle_request(new_req, limit - 1, &block)
|
161
|
+
new_req = clone_req(location.path, req, headers)
|
162
|
+
return handle_request(new_req, headers, limit - 1, &block)
|
163
163
|
else
|
164
164
|
response.error!
|
165
165
|
end
|
166
166
|
end
|
167
|
+
def clone_req(path, req, headers)
|
168
|
+
new_req = req.class.new(path)
|
169
|
+
new_req.body = req.body
|
170
|
+
new_req.body_stream = req.body_stream
|
171
|
+
headers.each_pair { |key, value| new_req[key] = value } if headers
|
172
|
+
return new_req
|
173
|
+
end
|
174
|
+
|
175
|
+
CNONCE = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))).slice(0, 8)
|
176
|
+
|
177
|
+
def digest_auth(request, user, password, response)
|
178
|
+
# based on http://segment7.net/projects/ruby/snippets/digest_auth.rb
|
179
|
+
@nonce_count = 0 if @nonce_count.nil?
|
180
|
+
@nonce_count += 1
|
181
|
+
|
182
|
+
raise "bad www-authenticate header" unless (response['www-authenticate'] =~ /^(\w+) (.*)/)
|
183
|
+
|
184
|
+
params = {}
|
185
|
+
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
186
|
+
|
187
|
+
a_1 = "#{user}:#{params['realm']}:#{password}"
|
188
|
+
a_2 = "#{request.method}:#{request.path}"
|
189
|
+
request_digest = ''
|
190
|
+
request_digest << Digest::MD5.hexdigest(a_1)
|
191
|
+
request_digest << ':' << params['nonce']
|
192
|
+
request_digest << ':' << ('%08x' % @nonce_count)
|
193
|
+
request_digest << ':' << CNONCE
|
194
|
+
request_digest << ':' << params['qop']
|
195
|
+
request_digest << ':' << Digest::MD5.hexdigest(a_2)
|
196
|
+
|
197
|
+
header = []
|
198
|
+
header << "Digest username=\"#{user}\""
|
199
|
+
header << "realm=\"#{params['realm']}\""
|
200
|
+
header << "nonce=\"#{params['nonce']}\""
|
201
|
+
header << "uri=\"#{request.path}\""
|
202
|
+
header << "cnonce=\"#{CNONCE}\""
|
203
|
+
header << "nc=#{'%08x' % @nonce_count}"
|
204
|
+
header << "qop=#{params['qop']}"
|
205
|
+
header << "response=\"#{Digest::MD5.hexdigest(request_digest)}\""
|
206
|
+
header << "algorithm=\"MD5\""
|
207
|
+
|
208
|
+
header = header.join(', ')
|
209
|
+
request['Authorization'] = header
|
210
|
+
end
|
167
211
|
end
|
168
212
|
|
169
213
|
|
@@ -187,6 +231,9 @@ module Net #:nodoc:
|
|
187
231
|
@curl.timeout = @http.read_timeout
|
188
232
|
@curl.follow_location = true
|
189
233
|
@curl.max_redirects = MAX_REDIRECTS
|
234
|
+
if disable_basic_auth
|
235
|
+
@curl.http_auth_types = Curl::CURLAUTH_DIGEST
|
236
|
+
end
|
190
237
|
end
|
191
238
|
@curl
|
192
239
|
end
|
@@ -210,11 +257,25 @@ module Net #:nodoc:
|
|
210
257
|
end
|
211
258
|
end
|
212
259
|
curl.perform
|
260
|
+
unless curl.response_code >= 200 && curl.response_code < 300
|
261
|
+
headers = curl.header_str.split(/\r?\n/)
|
262
|
+
raise Exception.new("Curl response #{headers[0]}")
|
263
|
+
end
|
213
264
|
curl.body_str
|
214
265
|
end
|
215
266
|
|
216
267
|
end
|
217
268
|
|
269
|
+
# Disable basic auth - to protect passwords from going in the clear
|
270
|
+
# through a man-in-the-middle attack.
|
271
|
+
def disable_basic_auth?
|
272
|
+
@handler.disable_basic_auth
|
273
|
+
end
|
274
|
+
|
275
|
+
def disable_basic_auth=(value)
|
276
|
+
@handler.disable_basic_auth = value
|
277
|
+
end
|
278
|
+
|
218
279
|
# Seconds to wait until reading one block (by one system call).
|
219
280
|
# If the DAV object cannot read a block in this many seconds,
|
220
281
|
# it raises a TimeoutError exception.
|
data/net_dav.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{net_dav}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Miron Cuperman"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-02}
|
13
13
|
s.default_executable = %q{dav}
|
14
14
|
s.description = %q{WebDAV client library in the style of Net::HTTP}
|
15
15
|
s.email = %q{c1.github@niftybox.net}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net_dav
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miron Cuperman
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-02 00:00:00 -08:00
|
13
13
|
default_executable: dav
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|