rets 0.2.2 → 0.3.0.rc.1

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 CHANGED
@@ -1,3 +1,7 @@
1
+ ### 0.3.0.rc.0 / 2012-07-26
2
+
3
+ * feature: significantly better handling of authorization failures
4
+
1
5
  ### 0.2.1 / 2012-04-20
2
6
 
3
7
  * fix: better handling of malformed RETS responses
data/lib/rets.rb CHANGED
@@ -8,7 +8,7 @@ require 'net/http/persistent'
8
8
  require 'nokogiri'
9
9
 
10
10
  module Rets
11
- VERSION = '0.2.2'
11
+ VERSION = '0.3.0'
12
12
 
13
13
  AuthorizationFailure = Class.new(ArgumentError)
14
14
  InvalidRequest = Class.new(ArgumentError)
data/lib/rets/client.rb CHANGED
@@ -35,7 +35,7 @@ module Rets
35
35
 
36
36
  self.logger = @options[:logger] || FakeLogger.new
37
37
 
38
- self.session = @options[:session] if @options[:session]
38
+ self.session = @options.delete(:session) if @options[:session]
39
39
  @cached_metadata = @options[:metadata] || nil
40
40
  end
41
41
 
@@ -108,12 +108,12 @@ module Rets
108
108
 
109
109
  body = build_key_values(query)
110
110
 
111
- headers = build_headers.merge(
111
+ extra_headers = {
112
112
  "Content-Type" => "application/x-www-form-urlencoded",
113
113
  "Content-Length" => body.size.to_s
114
- )
114
+ }
115
115
 
116
- results = request_with_compact_response(search_uri.path, body, headers)
116
+ results = request_with_compact_response(search_uri.path, body, extra_headers)
117
117
 
118
118
  if resolve
119
119
  rets_class = find_rets_class(opts[:search_type], opts[:class])
@@ -210,13 +210,13 @@ module Rets
210
210
  "Location" => opts[:location] || 0
211
211
  )
212
212
 
213
- headers = build_headers.merge(
213
+ extra_headers = {
214
214
  "Accept" => "image/jpeg, image/png;q=0.5, image/gif;q=0.1",
215
215
  "Content-Type" => "application/x-www-form-urlencoded",
216
216
  "Content-Length" => body.size.to_s
217
- )
217
+ }
218
218
 
219
- request(object_uri.path, body, headers)
219
+ request(object_uri.path, body, extra_headers)
220
220
  end
221
221
 
222
222
  # Changes keys to be camel cased, per the RETS standard for queries.
@@ -252,18 +252,19 @@ module Rets
252
252
  "ID" => "0"
253
253
  )
254
254
 
255
- headers = build_headers.merge(
255
+ extra_headers = {
256
256
  "Content-Type" => "application/x-www-form-urlencoded",
257
257
  "Content-Length" => body.size.to_s
258
- )
258
+ }
259
259
 
260
- response = request(metadata_uri.path, body, headers)
260
+ response = request(metadata_uri.path, body, extra_headers)
261
261
 
262
262
  response.body
263
263
  end
264
264
 
265
- def raw_request(path, body = nil, headers = build_headers, &reader)
265
+ def raw_request(path, body = nil, extra_headers = {}, &reader)
266
266
  logger.info "posting to #{path}"
267
+ headers = build_headers.merge(extra_headers)
267
268
 
268
269
  post = Net::HTTP::Post.new(path, headers)
269
270
  post.body = body.to_s
@@ -291,7 +292,14 @@ module Rets
291
292
  end
292
293
 
293
294
  def request(*args, &block)
294
- handle_response(raw_request(*args, &block))
295
+ response = handle_response(raw_request(*args, &block))
296
+ if Net::HTTPUnauthorized === response
297
+ retry_response = handle_response(raw_request(*args, &block))
298
+ raise AuthorizationFailure if retry_response === Net::HTTPUnauthorized
299
+ retry_response
300
+ else
301
+ response
302
+ end
295
303
  end
296
304
 
297
305
  def request_with_compact_response(path, body, headers)
@@ -306,15 +314,19 @@ module Rets
306
314
  end
307
315
 
308
316
  def handle_unauthorized_response(response)
309
- self.authorization = build_auth(extract_digest_header(response), uri, tries)
317
+ if self.authorization.nil?
318
+ self.authorization = build_auth(extract_digest_header(response), uri, tries)
319
+ response = raw_request(uri.path)
310
320
 
311
- response = raw_request(uri.path)
312
-
313
- if Net::HTTPUnauthorized === response
314
- raise AuthorizationFailure, "Authorization failed, check credentials?"
321
+ if Net::HTTPUnauthorized === response
322
+ raise AuthorizationFailure, "Authorization failed, check credentials?"
323
+ else
324
+ ErrorChecker.check(response)
325
+ self.capabilities = extract_capabilities(Nokogiri.parse(response.body))
326
+ end
315
327
  else
316
- ErrorChecker.check(response)
317
- self.capabilities = extract_capabilities(Nokogiri.parse(response.body))
328
+ clean_setup
329
+ login
318
330
  end
319
331
  end
320
332
 
data/test/test_client.rb CHANGED
@@ -521,15 +521,41 @@ DIGEST
521
521
  @client.objects([1,2], :foo => :bar)
522
522
  end
523
523
 
524
- def test_object_handles_empty_bodies
525
- @client = Rets::Client.new(:password=>"fake", :agent=>"agent", :login_url=>"http://www.example.com:6103/", :username=>"fake_user")
526
- assert_raise Rets::MalformedResponse do
527
- VCR.use_cassette('empty_body') do
528
- @client.objects([1], :resource => 'Property', :object_type => 'Photo', :resource_id => '480346')
529
- end
524
+ def test_unauthorized_session
525
+ session = Rets::Session.new(
526
+ "Digest username=\"login\", realm=\"fake_realm\", qop=\"auth\", uri=\"/Login.asmx/Login\", nonce=\"a8f4bc805062602c8ba7a87b2109f808\", nc=00000001, cnonce=\"6e2dd038eea6cbacf0b956fd11f914b6\", response=\"fake_digest\", opaque=\"96eda461-41d0-4624-b7fe-b59e966035f3\"",
527
+ {
528
+ "GetObject"=>"/GetObject.asmx/GetObject",
529
+ "GetMetadata"=>"/GetMetadata.asmx/GetMetadata",
530
+ "Login"=>"/Login.asmx/Login",
531
+ "metadatatimestamp"=>"2012-07-17T16:34:22Z",
532
+ "user"=>"23756,60,RH,login",
533
+ "Search"=>"/Search.asmx/Search",
534
+ "timeoutseconds"=>"7200"
535
+ },
536
+ "ASP.NET_SessionId=mapij045k3bphj3gqqgpmmrx; RETS-Session-ID=mapij045k3bphj3gqqgpmmrx"
537
+ )
538
+ opts = {
539
+ :username => 'login',
540
+ :password => 'Bn1X@y4L',
541
+ :login_url => 'http://rets.example.com/Login.asmx/Login',
542
+ :agent => 'Estately/1.0',
543
+ :persistent => false,
544
+ :session => session
545
+ }
546
+ client = Rets::Client.new(opts)
547
+ response = nil
548
+ VCR.use_cassette('unauthorized_response') do
549
+ response = client.objects("1",
550
+ :resource => 'Property',
551
+ :object_type => 'Photo',
552
+ :resource_id => '2661580'
553
+ )
530
554
  end
555
+ assert_equal 'image/jpeg', response.first.headers['content-type']
531
556
  end
532
557
 
558
+
533
559
  def test_objects_raises_on_other_arguments
534
560
  assert_raise ArgumentError do
535
561
  @client.objects(Object.new, :foo => :bar)
metadata CHANGED
@@ -1,130 +1,107 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rets
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0.rc.1
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Estately, Inc. Open Source
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-07-01 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: net-http-persistent
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70186895334000 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 1
29
- segments:
30
- - 1
31
- - 7
32
- version: "1.7"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.7'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: nokogiri
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70186895334000
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70186895333580 !ruby/object:Gem::Requirement
39
28
  none: false
40
- requirements:
29
+ requirements:
41
30
  - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 7
44
- segments:
45
- - 1
46
- - 5
47
- - 2
31
+ - !ruby/object:Gem::Version
48
32
  version: 1.5.2
49
33
  type: :runtime
50
- version_requirements: *id002
51
- - !ruby/object:Gem::Dependency
52
- name: mocha
53
34
  prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70186895333580
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &70186895333160 !ruby/object:Gem::Requirement
55
39
  none: false
56
- requirements:
40
+ requirements:
57
41
  - - ~>
58
- - !ruby/object:Gem::Version
59
- hash: 51
60
- segments:
61
- - 0
62
- - 11
63
- - 0
42
+ - !ruby/object:Gem::Version
64
43
  version: 0.11.0
65
44
  type: :development
66
- version_requirements: *id003
67
- - !ruby/object:Gem::Dependency
68
- name: vcr
69
45
  prerelease: false
70
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70186895333160
47
+ - !ruby/object:Gem::Dependency
48
+ name: vcr
49
+ requirement: &70186895332740 !ruby/object:Gem::Requirement
71
50
  none: false
72
- requirements:
51
+ requirements:
73
52
  - - ~>
74
- - !ruby/object:Gem::Version
75
- hash: 3
76
- segments:
77
- - 2
78
- - 2
79
- - 2
53
+ - !ruby/object:Gem::Version
80
54
  version: 2.2.2
81
55
  type: :development
82
- version_requirements: *id004
83
- - !ruby/object:Gem::Dependency
84
- name: webmock
85
56
  prerelease: false
86
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70186895332740
58
+ - !ruby/object:Gem::Dependency
59
+ name: webmock
60
+ requirement: &70186895332320 !ruby/object:Gem::Requirement
87
61
  none: false
88
- requirements:
62
+ requirements:
89
63
  - - ~>
90
- - !ruby/object:Gem::Version
91
- hash: 55
92
- segments:
93
- - 1
94
- - 8
95
- - 0
64
+ - !ruby/object:Gem::Version
96
65
  version: 1.8.0
97
66
  type: :development
98
- version_requirements: *id005
99
- - !ruby/object:Gem::Dependency
100
- name: hoe
101
67
  prerelease: false
102
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *70186895332320
69
+ - !ruby/object:Gem::Dependency
70
+ name: rdoc
71
+ requirement: &70186895331900 !ruby/object:Gem::Requirement
103
72
  none: false
104
- requirements:
73
+ requirements:
105
74
  - - ~>
106
- - !ruby/object:Gem::Version
107
- hash: 27
108
- segments:
109
- - 2
110
- - 12
111
- version: "2.12"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.10'
112
77
  type: :development
113
- version_requirements: *id006
114
- description: |-
115
- [![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
78
+ prerelease: false
79
+ version_requirements: *70186895331900
80
+ - !ruby/object:Gem::Dependency
81
+ name: hoe
82
+ requirement: &70186895331480 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '2.13'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70186895331480
91
+ description: ! '[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
92
+
116
93
  A pure-ruby library for fetching data from [RETS] servers.
117
-
118
- [RETS]: http://www.rets.org
119
- email:
94
+
95
+
96
+ [RETS]: http://www.rets.org'
97
+ email:
120
98
  - opensource@estately.com
121
- executables:
99
+ executables:
122
100
  - rets
123
101
  extensions: []
124
-
125
- extra_rdoc_files:
102
+ extra_rdoc_files:
126
103
  - Manifest.txt
127
- files:
104
+ files:
128
105
  - CHANGELOG.md
129
106
  - Manifest.txt
130
107
  - README.md
@@ -151,39 +128,32 @@ files:
151
128
  - .gemtest
152
129
  homepage: http://github.com/estately/rets
153
130
  licenses: []
154
-
155
131
  post_install_message:
156
- rdoc_options:
132
+ rdoc_options:
157
133
  - --main
158
134
  - README.md
159
- require_paths:
135
+ require_paths:
160
136
  - lib
161
- required_ruby_version: !ruby/object:Gem::Requirement
137
+ required_ruby_version: !ruby/object:Gem::Requirement
162
138
  none: false
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- hash: 3
167
- segments:
168
- - 0
169
- version: "0"
170
- required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
144
  none: false
172
- requirements:
173
- - - ">="
174
- - !ruby/object:Gem::Version
175
- hash: 3
176
- segments:
177
- - 0
178
- version: "0"
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
179
149
  requirements: []
180
-
181
150
  rubyforge_project: rets
182
- rubygems_version: 1.8.10
151
+ rubygems_version: 1.8.15
183
152
  signing_key:
184
153
  specification_version: 3
185
- summary: "[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets) A pure-ruby library for fetching data from [RETS] servers"
186
- test_files:
154
+ summary: ! '[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
155
+ A pure-ruby library for fetching data from [RETS] servers'
156
+ test_files:
187
157
  - test/test_client.rb
188
158
  - test/test_metadata.rb
189
159
  - test/test_parser_compact.rb