right_cloud_api_base 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93876f7645c63a599b1cdde9e5752490efcb6b9e
4
- data.tar.gz: cf0a599994e10d1c17c2cf014e03ab303a18deed
3
+ metadata.gz: a15b1f9a44a3084eb718cb87639fb3c96c015157
4
+ data.tar.gz: 99545b9605f6d1b63c2ad1a138fd3ac614a9a811
5
5
  SHA512:
6
- metadata.gz: 76b486fbb4c8392dff74a77e953c051b7eabeb8a2e723f795d0efb1bf66c3cebbcb6c543bc36e4674e41adee214e8bac4955fda97cd69b8a79e11ad7a4752e9c
7
- data.tar.gz: ba3b90502877bbe162ceae9bfba958bb4682cc5ee2083fc1cd71c36b435c1ca8bb078cd522861683fb91fa30d3bf82855758936e803c2b04275e654a06e8b44a
6
+ metadata.gz: 710087ad760c2ec6b5e553e10848c4e54916f9568b957a28a579d1b1d7ca5613015a7604c58b3b07a43c3bbcd0bfbf5c89b7c08f9bf44761d38f576183a560fb
7
+ data.tar.gz: 24018fc8b936dc861528452f14e55adc4341297443cd1078c36f9bd03ea1ba359668135ae026e32325dd04633ad1c911ef595b3ce659ffa528f824cfa101f84e
data/HISTORY CHANGED
@@ -1,6 +1,13 @@
1
+ == 2015-03-11, v0.2.2
2
+ - Fixed "Cannot do block-based chunk gets on S3" issue
3
+ https://github.com/rightscale/right_aws_api/issues/24
4
+
5
+ == 2015-01-23, v0.2.1.1
6
+ - Removed RightHttpConnection gem related code
7
+
8
+ == 2014-11-03, v0.2.1
9
+ - Fix object._blank? issue for IO objects.
10
+
1
11
  == 2013-06-28
2
12
  - pre-release candidate created
3
13
 
4
- == 2014-11-03
5
- - Fix object._blank? issue for IO objects.
6
- - version bumped to 0.1.1
@@ -165,10 +165,7 @@ module RightScale
165
165
  #
166
166
  # @option options [String] :connection_proxy
167
167
  # Connection proxy class (when it need to be different from the default one).
168
- # Only RightScale::CloudApi::ConnectionProxy::NetHttpPersistentProxy (default) and
169
- # RightScale::CloudApi::ConnectionProxy::RightHttpConnectionProxy are supported.
170
- # The last one requires 'right_http_connection' gem to be manually installed, and it is
171
- # not recommended to use because it monkey patches Net::HTTP.
168
+ # Only RightScale::CloudApi::ConnectionProxy::NetHttpPersistentProxy is supported so far.
172
169
  #
173
170
  # @option options [Integer] :connection_read_timeout
174
171
  # Connection read timeout (in seconds).
@@ -83,7 +83,7 @@ module RightScale
83
83
  # Create a request
84
84
  @verb = verb.to_s.downcase
85
85
  @path = path
86
- @raws = raw
86
+ @raw = raw
87
87
  @headers = HTTPHeaders::new(headers)
88
88
  self.body = body
89
89
  end
@@ -122,7 +122,6 @@ module RightScale
122
122
  file.binmode if file.respond_to?(:binmode)
123
123
  # Fix 'content-length': it must not be bigger than a piece of a File left to be read or a String body size.
124
124
  # Otherwise the connection may behave like crazy causing 4xx or 5xx responses
125
- # KD: Make sure this code is used with the patched RightHttpConnection gem (see net_fix.rb)
126
125
  file_size = file.respond_to?(:lstat) ? file.lstat.size : file.size
127
126
  bytes_to_read = [ file_size - file.pos, self['content-length'].first ].compact.map{|v| v.to_i }.sort.first # remove nils then make values Integers
128
127
  if self['content-length'].first._blank? || self['content-length'].first.to_i > bytes_to_read
@@ -79,7 +79,7 @@ module RightScale
79
79
  #
80
80
  # query_api_pattern 'PutObject', :put, '{:Bucket}/{:Object}',
81
81
  # :body => Utils::MUST_BE_SET,
82
- # :headers => { 'content-type' => ['application/octet-stream'] }
82
+ # :headers => { 'content-type' => ['binary/octet-stream'] }
83
83
  # ..
84
84
  # end
85
85
  # end
@@ -99,7 +99,7 @@ module RightScale
99
99
  #
100
100
  # base.query_api_pattern 'PutObject', :put, '{:Bucket:}/{:Object:}',
101
101
  # :body => Utils::MUST_BE_SET,
102
- # :headers => { 'content-type' => ['application/octet-stream'] }
102
+ # :headers => { 'content-type' => ['binary/octet-stream'] }
103
103
  #
104
104
  # base.query_api_pattern 'UploadPartCopy', :put,'{:DestinationBucket}/{:DestinationObject}',
105
105
  # :params => { 'partNumber' => :PartNumber, 'uploadId' => :UploadId },
@@ -63,9 +63,9 @@ module RightScale
63
63
  begin
64
64
  make_request_with_retries(connection, @data[:connection][:uri], http_request)
65
65
  rescue => e
66
- fail(ConnectionError, e.message)
66
+ fail(ConnectionError, e.message)
67
67
  ensure
68
- connection.shutdown
68
+ connection.shutdown
69
69
  end
70
70
  end
71
71
 
@@ -180,9 +180,12 @@ module RightScale
180
180
  # then there is no low level retry is allowed. Otherwise we would need to reset the
181
181
  # IO pointer, etc.
182
182
  connection_retry_count = 0
183
- # Set IO response
184
- set_http_response(response)
185
- response.read_body(&block)
183
+ if response.is_a?(Net::HTTPSuccess)
184
+ set_http_response(response, :skip_body)
185
+ response.read_body(&block)
186
+ else
187
+ set_http_response(response)
188
+ end
186
189
  end
187
190
  else
188
191
  # Set text response
@@ -213,10 +216,10 @@ module RightScale
213
216
  #
214
217
  # @return [void]
215
218
  #
216
- def set_http_response(response)
219
+ def set_http_response(response, skip_body=false)
217
220
  @data[:response][:instance] = HTTPResponse.new(
218
221
  response.code,
219
- response.body.is_a?(IO) ? nil : response.body,
222
+ skip_body ? nil : response.body,
220
223
  response.to_hash,
221
224
  response
222
225
  )
@@ -38,12 +38,10 @@ module RightScale
38
38
  def process
39
39
  unless @connection_proxy
40
40
  # Try to use a user defined connection proxy. The options are:
41
- # - RightScale::CloudApi::ConnectionProxy::RightHttpConnectionProxy,
42
41
  # - RightScale::CloudApi::ConnectionProxy::NetHttpPersistentProxy
43
42
  connection_proxy_class = data[:options][:connection_proxy]
44
43
  unless connection_proxy_class
45
44
  # If it is not defined then load right_http_connection gem and use it.
46
- # connection_proxy_class = ConnectionProxy::RightHttpConnectionProxy
47
45
  connection_proxy_class = RightScale::CloudApi::ConnectionProxy::NetHttpPersistentProxy
48
46
  end
49
47
  @connection_proxy = connection_proxy_class.new
@@ -62,7 +62,6 @@ require "base/routines/retry_manager"
62
62
  require "base/routines/request_initializer"
63
63
  require "base/routines/request_generator"
64
64
  require "base/routines/connection_proxy"
65
- require "base/routines/connection_proxies/right_http_connection_proxy"
66
65
  require "base/routines/connection_proxies/net_http_persistent_proxy"
67
66
  require "base/routines/response_parser"
68
67
  require "base/routines/request_analyzer"
@@ -19,7 +19,7 @@
19
19
  # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
20
  # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
21
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
22
+ #++`
23
23
 
24
24
  # RightScale namespace
25
25
  #
@@ -31,7 +31,7 @@ module RightScale
31
31
  # CloudApi gem version namespace
32
32
  module VERSION
33
33
  # The gem version
34
- STRING = '0.2.1'
34
+ STRING = '0.2.2'
35
35
  end
36
36
  end
37
37
  end
@@ -57,7 +57,8 @@ describe "RightScale::CloudApi::ConnectionProxy::NetHTTPPersistentProxy" do
57
57
  before :each do
58
58
  @connection = double(
59
59
  :request => @response,
60
- :retry_change_requests= => true )
60
+ :retry_change_requests= => true,
61
+ :shutdown => true )
61
62
  expect(Net::HTTP::Persistent).to receive(:new).and_return(@connection)
62
63
  end
63
64
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_cloud_api_base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - RightScale, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-17 00:00:00.000000000 Z
11
+ date: 2015-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -144,7 +144,6 @@ files:
144
144
  - lib/base/parsers/sax.rb
145
145
  - lib/base/routines/cache_validator.rb
146
146
  - lib/base/routines/connection_proxies/net_http_persistent_proxy.rb
147
- - lib/base/routines/connection_proxies/right_http_connection_proxy.rb
148
147
  - lib/base/routines/connection_proxy.rb
149
148
  - lib/base/routines/request_analyzer.rb
150
149
  - lib/base/routines/request_generator.rb
@@ -1,227 +0,0 @@
1
- #--
2
- # Copyright (c) 2013 RightScale, Inc.
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # 'Software'), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- module RightScale
25
- module CloudApi
26
- class ConnectionProxy
27
-
28
- class RightHttpConnectionProxy
29
- @@storage = {}
30
-
31
- def self.storage
32
- @@storage
33
- end
34
-
35
- # Remove dead threads/fibers from the storage
36
- def self.clean_storage
37
- Utils::remove_dead_fibers_and_threads_from_storage(storage)
38
- end
39
-
40
- class Error < CloudApi::Error
41
- end
42
-
43
- # Performs an HTTP request.
44
- #
45
- # @param [Hash] data The API request +data+ storage.
46
- # See {RightScale::CloudApi::ApiManager.initialize_api_request_options} code for its explanation.
47
- #
48
- def request(data)
49
- require "right_http_connection"
50
-
51
- @data = data
52
- @data[:response] = {}
53
- # Create a connection
54
- @uri = @data[:connection][:uri].dup
55
-
56
- # Create/Get RightHttpConnection instance
57
- remote_endpoint = current_endpoint
58
- right_http_connection = current_connection
59
-
60
- # Register a callback to close current connection
61
- @data[:callbacks][:close_current_connection] = Proc::new{|reason| close_connection(remote_endpoint, reason); log "Current connection closed: #{reason}" }
62
-
63
- # Create a real HTTP request
64
- fake = @data[:request][:instance]
65
- http_request = "Net::HTTP::#{fake.verb._camelize}"._constantize::new(fake.path)
66
- if fake.is_io?
67
- http_request.body_stream = fake.body
68
- else
69
- http_request.body = fake.body
70
- end
71
- fake.headers.each{|header, value| http_request[header] = value }
72
- fake.raw = http_request
73
-
74
- # Set all the options are suported by RightHttpConnection (if they are)
75
- http_connection_data = {
76
- :server => @uri.host,
77
- :port => @uri.port,
78
- :protocol => @uri.scheme,
79
- :request => http_request,
80
- :exception => ConnectionError
81
- }
82
-
83
- # Set all required options
84
- http_connection_data[:logger] = @data[:options][:cloud_api_logger].logger
85
- http_connection_data[:user_agent] = @data[:options][:connection_user_agent] if @data[:options].has_key?(:connection_user_agent)
86
- http_connection_data[:ca_file] = @data[:options][:connection_ca_file] if @data[:options].has_key?(:connection_ca_file)
87
- http_connection_data[:http_connection_retry_count] = @data[:options][:connection_retry_count] if @data[:options].has_key?(:connection_retry_count)
88
- http_connection_data[:http_connection_read_timeout] = @data[:options][:connection_read_timeout] if @data[:options].has_key?(:connection_read_timeout)
89
- http_connection_data[:http_connection_open_timeout] = @data[:options][:connection_open_timeout] if @data[:options].has_key?(:connection_open_timeout)
90
- http_connection_data[:http_connection_retry_delay] = @data[:options][:connection_retry_delay] if @data[:options].has_key?(:connection_retry_delay)
91
- http_connection_data[:raise_on_timeout] = @data[:options][:abort_on_timeout] if @data[:options][:abort_on_timeout]
92
- http_connection_data[:cert] = @data[:credentials][:cert] if @data[:credentials].has_key?(:cert)
93
- http_connection_data[:key] = @data[:credentials][:key] if @data[:credentials].has_key?(:key)
94
- if @data[:options].has_key?(:connection_verify_mode)
95
- http_connection_data[:use_server_auth] = (@data[:options][:connection_verify_mode] != OpenSSL::SSL::VERIFY_NONE)
96
- end
97
-
98
- #log "HttpConnection request: #{http_connection_data.inspect}"
99
-
100
- # Make a request:
101
- block = @data[:vars][:system][:block]
102
- if block
103
- # If block is given - pass there all the chunks of a response and stop
104
- # (dont do any parsing, analysing etc)
105
- #
106
- # TRB 9/17/07 Careful - because we are passing in blocks, we get a situation where
107
- # an exception may get thrown in the block body (which is high-level
108
- # code either here or in the application) but gets caught in the
109
- # low-level code of HttpConnection. The solution is not to let any
110
- # exception escape the block that we pass to HttpConnection::request.
111
- # Exceptions can originate from code directly in the block, or from user
112
- # code called in the other block which is passed to response.read_body.
113
- #
114
- # TODO: the suggested fix for RightHttpConnection if to catch
115
- # Interrupt and SystemCallError instead of Exception in line 402
116
- response = nil
117
- begin
118
- block_exception = nil
119
- # Response.body will be a Net::ReadAdapter instance here - it cant be read as a string.
120
- # WEB: On its own, Net::HTTP causes response.body to be a Net::ReadAdapter when you make a request with a block
121
- # that calls read_body on the response.
122
- response = right_http_connection.request(http_connection_data) do |res|
123
- begin
124
- # Update temp response
125
- @data[:response][:instance] = HTTPResponse::new( res.code,
126
- nil,
127
- res.to_hash,
128
- res )
129
- res.read_body(&block) if res.is_a?(Net::HTTPSuccess)
130
- rescue Exception => e
131
- block_exception = e
132
- break
133
- end
134
- end
135
- raise block_exception if block_exception
136
- rescue Exception => e
137
- right_http_connection.finish(e.message)
138
- raise e
139
- end
140
- else
141
- # Things are simple if there is no any block
142
- response = right_http_connection.request(http_connection_data)
143
- end
144
-
145
- @data[:response][:instance] = HTTPResponse::new( response.code,
146
- response.body,
147
- response.to_hash,
148
- response )
149
-
150
- # # HACK: KD
151
- # #
152
- # # When one uploads a file with pos > 0 and 'content-length' != File.size - pos
153
- # # then the next request through this connection fails with 400 or 505...
154
- # # It seems that it expects the file to be read until EOF.
155
- # #
156
- # # KIlling the current connection seems to help but it is not good...
157
- # #
158
- # if @data[:request][:instance].body_stream #&& !@data[:request][:instance].body_stream.eof
159
- # pp @data[:request][:instance].body_stream.pos
160
- # log "closing current connection because of an issue when an IO object is not read until EOF"
161
- # @connection.finish
162
- # end
163
- end
164
-
165
- def log(message)
166
- @data[:options][:cloud_api_logger].log(message, :connection_proxy)
167
- end
168
-
169
- #----------------------------
170
- # HTTP Connections handling
171
- #----------------------------
172
-
173
- def storage # :nodoc:
174
- @@storage[Utils::current_thread_and_fiber] ||= {}
175
- end
176
-
177
- def current_endpoint # :nodoc:
178
- "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
179
- end
180
-
181
- def close_connection(endpoint, reason='') # :nodoc:
182
- return nil unless storage[endpoint]
183
-
184
- log "Destroying RightHttpConnection to #{endpoint}, reason: #{reason}"
185
- storage[endpoint][:connection].finish(reason)
186
- rescue => e
187
- log "Exception in close_connection: #{e.class.name}: #{e.message}"
188
- ensure
189
- storage.delete(endpoint) if endpoint
190
- end
191
-
192
- INACTIVE_LIFETIME_LIMIT = 900 # seconds
193
-
194
- # Delete out-of-dated connections for current Thread/Fiber
195
- def clean_outdated_connections
196
- life_time_scratch = Time::now - INACTIVE_LIFETIME_LIMIT
197
- storage.each do |endpoint, connection|
198
- if connection[:last_used_at] < life_time_scratch
199
- close_connection(endpoint, 'out-of-date')
200
- end
201
- end
202
- end
203
-
204
- # Expire the connection if it has expired.
205
- def current_connection # :nodoc:
206
- # Remove dead threads/fibers from the storage
207
- self.class::clean_storage
208
- # Delete out-of-dated connections
209
- clean_outdated_connections
210
- # Get current_connection
211
- endpoint = current_endpoint
212
- unless storage[endpoint]
213
- storage[endpoint] = {}
214
- storage[endpoint][:connection] = Rightscale::HttpConnection.new( :exception => CloudError,
215
- :logger => @data[:options][:cloud_api_logger].logger )
216
- log "Creating RightHttpConection to #{endpoint.inspect}"
217
- else
218
- log "Reusing RightHttpConection to #{endpoint.inspect}"
219
- end
220
- storage[endpoint][:last_used_at] = Time::now
221
- storage[endpoint][:connection]
222
- end
223
- end
224
-
225
- end
226
- end
227
- end