rets 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -1
- data/lib/rets.rb +1 -1
- data/lib/rets/client.rb +37 -31
- data/test/test_client.rb +16 -16
- metadata +16 -16
data/CHANGELOG.md
CHANGED
data/lib/rets.rb
CHANGED
data/lib/rets/client.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Rets
|
|
2
|
-
Session = Struct.new(:
|
|
2
|
+
Session = Struct.new(:auth_digest, :capabilities, :cookies)
|
|
3
3
|
|
|
4
4
|
class Client
|
|
5
5
|
DEFAULT_OPTIONS = { :persistent => true }
|
|
6
6
|
|
|
7
7
|
include Authentication
|
|
8
8
|
|
|
9
|
-
attr_accessor :
|
|
9
|
+
attr_accessor :login_uri, :options, :logger, :auth_digest
|
|
10
10
|
attr_writer :capabilities, :metadata
|
|
11
11
|
|
|
12
12
|
def initialize(options)
|
|
@@ -16,26 +16,26 @@ module Rets
|
|
|
16
16
|
|
|
17
17
|
def clean_setup
|
|
18
18
|
|
|
19
|
+
@auth_digest = nil
|
|
20
|
+
@cached_metadata = nil
|
|
19
21
|
@capabilities = nil
|
|
22
|
+
@connection = nil
|
|
20
23
|
@cookies = nil
|
|
21
24
|
@metadata = nil
|
|
22
|
-
@cached_metadata = nil
|
|
23
25
|
@tries = nil
|
|
24
|
-
@connection = nil
|
|
25
|
-
self.authorization = nil
|
|
26
26
|
self.capabilities = nil
|
|
27
27
|
|
|
28
|
-
uri
|
|
28
|
+
uri = URI.parse(@options[:login_url])
|
|
29
29
|
|
|
30
|
-
uri.user
|
|
31
|
-
uri.password
|
|
30
|
+
uri.user = @options.key?(:username) ? CGI.escape(@options[:username]) : nil
|
|
31
|
+
uri.password = @options.key?(:password) ? CGI.escape(@options[:password]) : nil
|
|
32
32
|
|
|
33
|
-
self.options
|
|
34
|
-
self.
|
|
33
|
+
self.options = DEFAULT_OPTIONS.merge(@options)
|
|
34
|
+
self.login_uri = uri
|
|
35
35
|
|
|
36
|
-
self.logger
|
|
36
|
+
self.logger = @options[:logger] || FakeLogger.new
|
|
37
37
|
|
|
38
|
-
self.session
|
|
38
|
+
self.session = @options.delete(:session) if @options[:session]
|
|
39
39
|
@cached_metadata = @options[:metadata] || nil
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ module Rets
|
|
|
44
44
|
# provided in initialize. Returns the capabilities that the
|
|
45
45
|
# RETS server provides, per http://retsdoc.onconfluence.com/display/rets172/4.10+Capability+URL+List.
|
|
46
46
|
def login
|
|
47
|
-
response = request(
|
|
47
|
+
response = request(login_uri.path)
|
|
48
48
|
self.capabilities = extract_capabilities(Nokogiri.parse(response.body))
|
|
49
49
|
raise UnknownResponse, "Cannot read rets server capabilities." unless @capabilities
|
|
50
50
|
@capabilities
|
|
@@ -267,7 +267,7 @@ module Rets
|
|
|
267
267
|
end
|
|
268
268
|
|
|
269
269
|
def raw_request(path, body = nil, extra_headers = {}, &reader)
|
|
270
|
-
headers = build_headers.merge(extra_headers)
|
|
270
|
+
headers = build_headers(path).merge(extra_headers)
|
|
271
271
|
|
|
272
272
|
post = Net::HTTP::Post.new(path, headers)
|
|
273
273
|
post.body = body.to_s
|
|
@@ -280,7 +280,7 @@ POST #{path}
|
|
|
280
280
|
#{binary?(body.to_s) ? '<<< BINARY BODY >>>' : body.to_s}
|
|
281
281
|
EOF
|
|
282
282
|
|
|
283
|
-
connection_args = [Net::HTTP::Persistent === connection ?
|
|
283
|
+
connection_args = [Net::HTTP::Persistent === connection ? login_uri : nil, post].compact
|
|
284
284
|
|
|
285
285
|
response = connection.request(*connection_args) do |res|
|
|
286
286
|
res.read_body(&reader)
|
|
@@ -301,13 +301,8 @@ EOF
|
|
|
301
301
|
def digest_auth_request(path, body = nil, extra_headers = {}, &reader)
|
|
302
302
|
response = raw_request(path, body, extra_headers, &reader)
|
|
303
303
|
if Net::HTTPUnauthorized === response
|
|
304
|
-
|
|
305
|
-
if
|
|
306
|
-
uri2 = URI.parse(uri.to_s)
|
|
307
|
-
uri2.user = uri.user
|
|
308
|
-
uri2.password = uri.password
|
|
309
|
-
uri2.path = path
|
|
310
|
-
self.authorization = build_auth(challenge, uri2, tries)
|
|
304
|
+
@auth_digest = extract_digest_header(response)
|
|
305
|
+
if @auth_digest
|
|
311
306
|
response = raw_request(path, body, extra_headers, &reader)
|
|
312
307
|
if Net::HTTPUnauthorized === response
|
|
313
308
|
raise AuthorizationFailure, "Authorization failed, check credentials?"
|
|
@@ -317,6 +312,16 @@ EOF
|
|
|
317
312
|
response
|
|
318
313
|
end
|
|
319
314
|
|
|
315
|
+
def authorization(path)
|
|
316
|
+
return nil unless @auth_digest
|
|
317
|
+
uri2 = URI.parse(login_uri.to_s)
|
|
318
|
+
uri2.user = login_uri.user
|
|
319
|
+
uri2.password = login_uri.password
|
|
320
|
+
uri2.path = path
|
|
321
|
+
build_auth(@auth_digest, uri2, tries)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
|
|
320
325
|
def request(*args, &block)
|
|
321
326
|
handle_response(digest_auth_request(*args, &block))
|
|
322
327
|
end
|
|
@@ -383,13 +388,13 @@ EOF
|
|
|
383
388
|
end
|
|
384
389
|
|
|
385
390
|
def session=(session)
|
|
386
|
-
self.
|
|
387
|
-
self.capabilities
|
|
388
|
-
self.cookies
|
|
391
|
+
self.auth_digest = session.auth_digest
|
|
392
|
+
self.capabilities = session.capabilities
|
|
393
|
+
self.cookies = session.cookies
|
|
389
394
|
end
|
|
390
395
|
|
|
391
396
|
def session
|
|
392
|
-
Session.new(
|
|
397
|
+
Session.new(auth_digest, capabilities, cookies)
|
|
393
398
|
end
|
|
394
399
|
|
|
395
400
|
|
|
@@ -435,7 +440,7 @@ EOF
|
|
|
435
440
|
def connection
|
|
436
441
|
@connection ||= options[:persistent] ?
|
|
437
442
|
persistent_connection :
|
|
438
|
-
Net::HTTP.new(
|
|
443
|
+
Net::HTTP.new(login_uri.host, login_uri.port)
|
|
439
444
|
end
|
|
440
445
|
|
|
441
446
|
def persistent_connection
|
|
@@ -457,15 +462,16 @@ EOF
|
|
|
457
462
|
options[:version] || "RETS/1.7.2"
|
|
458
463
|
end
|
|
459
464
|
|
|
460
|
-
def build_headers
|
|
465
|
+
def build_headers(path)
|
|
461
466
|
headers = {
|
|
462
467
|
"User-Agent" => user_agent,
|
|
463
|
-
"Host" => "#{
|
|
468
|
+
"Host" => "#{login_uri.host}:#{login_uri.port}",
|
|
464
469
|
"RETS-Version" => rets_version
|
|
465
470
|
}
|
|
466
471
|
|
|
467
|
-
|
|
468
|
-
headers.merge!("
|
|
472
|
+
auth = authorization(path)
|
|
473
|
+
headers.merge!("Authorization" => auth) if auth
|
|
474
|
+
headers.merge!("Cookie" => cookies) if cookies
|
|
469
475
|
|
|
470
476
|
if options[:ua_password]
|
|
471
477
|
headers.merge!(
|
data/test/test_client.rb
CHANGED
|
@@ -11,8 +11,8 @@ class TestClient < Test::Unit::TestCase
|
|
|
11
11
|
:login_url => "http://example.com",
|
|
12
12
|
:username => "bob@example.com")
|
|
13
13
|
|
|
14
|
-
assert_equal CGI.escape("bob@example.com"), client.
|
|
15
|
-
assert_nil client.
|
|
14
|
+
assert_equal CGI.escape("bob@example.com"), client.login_uri.user
|
|
15
|
+
assert_nil client.login_uri.password
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def test_initialize_adds_escaped_password_to_uri
|
|
@@ -21,7 +21,7 @@ class TestClient < Test::Unit::TestCase
|
|
|
21
21
|
:username => "bob",
|
|
22
22
|
:password => "secret@2!")
|
|
23
23
|
|
|
24
|
-
assert_equal CGI.escape("secret@2!"), client.
|
|
24
|
+
assert_equal CGI.escape("secret@2!"), client.login_uri.password
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def test_initialize_merges_default_options
|
|
@@ -58,11 +58,11 @@ class TestClient < Test::Unit::TestCase
|
|
|
58
58
|
post = mock()
|
|
59
59
|
post.expects(:body=).with("fake body")
|
|
60
60
|
|
|
61
|
-
headers = @client.build_headers
|
|
61
|
+
headers = @client.build_headers('path')
|
|
62
62
|
|
|
63
63
|
Net::HTTP::Post.expects(:new).with("/foo", headers).returns(post)
|
|
64
64
|
|
|
65
|
-
@client.connection.expects(:request).with(@client.
|
|
65
|
+
@client.connection.expects(:request).with(@client.login_uri, post).returns(stub_everything)
|
|
66
66
|
|
|
67
67
|
@client.expects(:handle_cookies)
|
|
68
68
|
@client.expects(:handle_response)
|
|
@@ -77,7 +77,7 @@ class TestClient < Test::Unit::TestCase
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def test_request_passes_correct_arguments_to_persistent_connection
|
|
80
|
-
@client.connection.expects(:request).with(@client.
|
|
80
|
+
@client.connection.expects(:request).with(@client.login_uri, instance_of(Net::HTTP::Post)).returns(stub_everything)
|
|
81
81
|
|
|
82
82
|
@client.stubs(:handle_cookies)
|
|
83
83
|
@client.stubs(:handle_response)
|
|
@@ -213,18 +213,18 @@ class TestClient < Test::Unit::TestCase
|
|
|
213
213
|
"User-Agent" => "Client/1.0",
|
|
214
214
|
"Host" => "example.com:80",
|
|
215
215
|
"RETS-Version" => "RETS/1.7.2"},
|
|
216
|
-
@client.build_headers)
|
|
216
|
+
@client.build_headers('path'))
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
def test_build_headers_provides_authorization
|
|
220
|
-
@client.authorization
|
|
220
|
+
@client.expects(:authorization).returns("Just trust me")
|
|
221
221
|
|
|
222
222
|
assert_equal({
|
|
223
223
|
"Authorization" => "Just trust me",
|
|
224
224
|
"User-Agent" => "Client/1.0",
|
|
225
225
|
"Host" => "example.com:80",
|
|
226
226
|
"RETS-Version" => "RETS/1.7.2"},
|
|
227
|
-
@client.build_headers)
|
|
227
|
+
@client.build_headers('path'))
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
def test_build_headers_provides_cookies
|
|
@@ -235,7 +235,7 @@ class TestClient < Test::Unit::TestCase
|
|
|
235
235
|
"User-Agent" => "Client/1.0",
|
|
236
236
|
"Host" => "example.com:80",
|
|
237
237
|
"RETS-Version" => "RETS/1.7.2"},
|
|
238
|
-
@client.build_headers)
|
|
238
|
+
@client.build_headers('path'))
|
|
239
239
|
end
|
|
240
240
|
|
|
241
241
|
|
|
@@ -289,33 +289,33 @@ DIGEST
|
|
|
289
289
|
|
|
290
290
|
|
|
291
291
|
def test_session_restores_state
|
|
292
|
-
session = Rets::Session.new(
|
|
292
|
+
session = Rets::Session.new({:digest => 'true'}, {"Foo" => "/foo"}, "sessionid=123")
|
|
293
293
|
|
|
294
294
|
@client.session = session
|
|
295
295
|
|
|
296
|
-
assert_equal(
|
|
296
|
+
assert_equal({:digest => 'true'}, @client.auth_digest)
|
|
297
297
|
assert_equal({"Foo" => "/foo"}, @client.capabilities)
|
|
298
298
|
assert_equal("sessionid=123", @client.cookies)
|
|
299
299
|
end
|
|
300
300
|
|
|
301
301
|
def test_session_dumps_state
|
|
302
|
-
@client.
|
|
302
|
+
@client.auth_digest = {:digest => 'true'}
|
|
303
303
|
@client.capabilities = {"Foo" => "/foo"}
|
|
304
304
|
@client.cookies = "session-id=123"
|
|
305
305
|
|
|
306
306
|
session = @client.session
|
|
307
307
|
|
|
308
|
-
assert_equal(
|
|
308
|
+
assert_equal({:digest => 'true'}, session.auth_digest)
|
|
309
309
|
assert_equal({"Foo" => "/foo"}, session.capabilities)
|
|
310
310
|
assert_equal("session-id=123", session.cookies)
|
|
311
311
|
end
|
|
312
312
|
|
|
313
313
|
def test_initialize_with_session_restores_state
|
|
314
|
-
session = Rets::Session.new(
|
|
314
|
+
session = Rets::Session.new({:digest => true}, {"Foo" => "/foo"}, "sessionid=123")
|
|
315
315
|
|
|
316
316
|
client = Rets::Client.new(:login_url => "http://example.com", :session => session)
|
|
317
317
|
|
|
318
|
-
assert_equal(
|
|
318
|
+
assert_equal({:digest => true}, client.auth_digest)
|
|
319
319
|
assert_equal({"Foo" => "/foo"}, client.capabilities)
|
|
320
320
|
assert_equal("sessionid=123", client.cookies)
|
|
321
321
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rets
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-08-
|
|
12
|
+
date: 2012-08-29 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: net-http-persistent
|
|
@@ -44,13 +44,13 @@ dependencies:
|
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
45
|
version: 1.5.2
|
|
46
46
|
- !ruby/object:Gem::Dependency
|
|
47
|
-
name:
|
|
47
|
+
name: rdoc
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
49
49
|
none: false
|
|
50
50
|
requirements:
|
|
51
51
|
- - ~>
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: '3.10'
|
|
54
54
|
type: :development
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -58,15 +58,15 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - ~>
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
61
|
+
version: '3.10'
|
|
62
62
|
- !ruby/object:Gem::Dependency
|
|
63
|
-
name:
|
|
63
|
+
name: mocha
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
|
65
65
|
none: false
|
|
66
66
|
requirements:
|
|
67
67
|
- - ~>
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version:
|
|
69
|
+
version: 0.11.0
|
|
70
70
|
type: :development
|
|
71
71
|
prerelease: false
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -74,15 +74,15 @@ dependencies:
|
|
|
74
74
|
requirements:
|
|
75
75
|
- - ~>
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
|
-
version:
|
|
77
|
+
version: 0.11.0
|
|
78
78
|
- !ruby/object:Gem::Dependency
|
|
79
|
-
name:
|
|
79
|
+
name: vcr
|
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
|
81
81
|
none: false
|
|
82
82
|
requirements:
|
|
83
83
|
- - ~>
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
|
-
version:
|
|
85
|
+
version: 2.2.2
|
|
86
86
|
type: :development
|
|
87
87
|
prerelease: false
|
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -90,15 +90,15 @@ dependencies:
|
|
|
90
90
|
requirements:
|
|
91
91
|
- - ~>
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
|
-
version:
|
|
93
|
+
version: 2.2.2
|
|
94
94
|
- !ruby/object:Gem::Dependency
|
|
95
|
-
name:
|
|
95
|
+
name: webmock
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
|
97
97
|
none: false
|
|
98
98
|
requirements:
|
|
99
99
|
- - ~>
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
|
-
version:
|
|
101
|
+
version: 1.8.0
|
|
102
102
|
type: :development
|
|
103
103
|
prerelease: false
|
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -106,7 +106,7 @@ dependencies:
|
|
|
106
106
|
requirements:
|
|
107
107
|
- - ~>
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
|
-
version:
|
|
109
|
+
version: 1.8.0
|
|
110
110
|
- !ruby/object:Gem::Dependency
|
|
111
111
|
name: hoe
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,7 +114,7 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - ~>
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
117
|
+
version: '3.0'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -122,7 +122,7 @@ dependencies:
|
|
|
122
122
|
requirements:
|
|
123
123
|
- - ~>
|
|
124
124
|
- !ruby/object:Gem::Version
|
|
125
|
-
version: '
|
|
125
|
+
version: '3.0'
|
|
126
126
|
description: ! '[](http://travis-ci.org/estately/rets)
|
|
127
127
|
|
|
128
128
|
A pure-ruby library for fetching data from [RETS] servers.
|