rets 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: ! '[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
|
127
127
|
|
128
128
|
A pure-ruby library for fetching data from [RETS] servers.
|