rets 0.2.2 → 0.3.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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