right_http_connection 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,3 +28,15 @@ Initial public release
28
28
  * r1867, konstantin, 2007-10-05 06:19:45
29
29
  * # 220, (re)open connection to server if none exists or connection params
30
30
  have changed
31
+
32
+ == 1.2.1
33
+
34
+ * r2648, konstantin, 01-24-08 11:12:00
35
+ * net_fix.rb moved from right_aws gem to fix the problem with uploading the streamable
36
+ objects to S3
37
+
38
+ * r2764, konstantin, 02-08-08 00:05:00 +03:00
39
+ * "RightAws: incompatible Net::HTTP monkey-patch" exception is raised if our net_fix
40
+ patch was overriden (by attachment_fu for example, to avoid this load attachment_fu
41
+ before loading the right_http_connection gem).
42
+
@@ -2,5 +2,6 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
+ lib/net_fix.rb
5
6
  lib/right_http_connection.rb
6
7
  setup.rb
data/README.txt CHANGED
@@ -7,7 +7,7 @@ RightScale::HttpConnection
7
7
  Rightscale::HttpConnection is a robust HTTP/S library. It implements a retry
8
8
  algorithm for low-level network errors.
9
9
 
10
- == FEATURES/PROBLEMS:
10
+ == FEATURES:
11
11
 
12
12
  - provides put/get streaming
13
13
  - does configurable retries on connect and read timeouts, DNS failures, etc.
@@ -18,7 +18,13 @@ algorithm for low-level network errors.
18
18
 
19
19
  == REQUIREMENTS:
20
20
 
21
- None.
21
+ - 2/11/08: If you use RightScale::HttpConnection in conjunction with attachment_fu, the
22
+ HttpConnection gem must be included (using the require statement) AFTER
23
+ attachment_fu.
24
+ This is due to a conflict between the HttpConnection gem and another
25
+ gem required by attachment_fu.
26
+
27
+
22
28
 
23
29
  == INSTALL:
24
30
 
@@ -26,7 +32,7 @@ sudo gem install
26
32
 
27
33
  == LICENSE:
28
34
 
29
- Copyright (c) 2007 RightScale, Inc.
35
+ Copyright (c) 2007-2008 RightScale, Inc.
30
36
 
31
37
  Permission is hereby granted, free of charge, to any person obtaining
32
38
  a copy of this software and associated documentation files (the
@@ -0,0 +1,160 @@
1
+ #
2
+ # Copyright (c) 2008 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
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+ #
24
+
25
+ # Net::HTTP and Net::HTTPGenericRequest fixes to support 100-continue on
26
+ # POST and PUT. The request must have 'expect' field set to '100-continue'.
27
+
28
+
29
+ module Net
30
+
31
+ class BufferedIO #:nodoc:
32
+ # Monkey-patch Net::BufferedIO to read > 1024 bytes from the socket at a time
33
+
34
+ # Default size (in bytes) of the max read from a socket into the user space read buffers for socket IO
35
+ DEFAULT_SOCKET_READ_SIZE = 16*1024
36
+
37
+ @@socket_read_size = DEFAULT_SOCKET_READ_SIZE
38
+
39
+ def self.socket_read_size=(readsize)
40
+ if(readsize <= 0)
41
+ return
42
+ end
43
+ @@socket_read_size = readsize
44
+ end
45
+
46
+ def self.socket_read_size?()
47
+ @@socket_read_size
48
+ end
49
+
50
+ def rbuf_fill
51
+ timeout(@read_timeout) {
52
+ @rbuf << @io.sysread(@@socket_read_size)
53
+ }
54
+ end
55
+ end
56
+
57
+
58
+ #-- Net::HTTPGenericRequest --
59
+
60
+ class HTTPGenericRequest
61
+ # Monkey-patch Net::HTTPGenericRequest to read > 1024 bytes from the local data
62
+ # source at a time (used in streaming PUTs)
63
+
64
+ # Default size (in bytes) of the max read from a local source (File, String,
65
+ # etc.) to the user space write buffers for socket IO.
66
+ DEFAULT_LOCAL_READ_SIZE = 16*1024
67
+
68
+ @@local_read_size = DEFAULT_LOCAL_READ_SIZE
69
+
70
+ def self.local_read_size=(readsize)
71
+ if(readsize <= 0)
72
+ return
73
+ end
74
+ @@local_read_size = readsize
75
+ end
76
+
77
+ def self.local_read_size?()
78
+ @@local_read_size
79
+ end
80
+
81
+ def exec(sock, ver, path, send_only=nil) #:nodoc: internal use only
82
+ if @body
83
+ send_request_with_body sock, ver, path, @body, send_only
84
+ elsif @body_stream
85
+ send_request_with_body_stream sock, ver, path, @body_stream, send_only
86
+ else
87
+ write_header(sock, ver, path)
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def send_request_with_body(sock, ver, path, body, send_only=nil)
94
+ self.content_length = body.length
95
+ delete 'Transfer-Encoding'
96
+ supply_default_content_type
97
+ write_header(sock, ver, path) unless send_only == :body
98
+ sock.write(body) unless send_only == :header
99
+ end
100
+
101
+ def send_request_with_body_stream(sock, ver, path, f, send_only=nil)
102
+ unless content_length() or chunked?
103
+ raise ArgumentError,
104
+ "Content-Length not given and Transfer-Encoding is not `chunked'"
105
+ end
106
+ supply_default_content_type
107
+ write_header(sock, ver, path) unless send_only == :body
108
+ unless send_only == :header
109
+ if chunked?
110
+ while s = f.read(@@local_read_size)
111
+ sock.write(sprintf("%x\r\n", s.length) << s << "\r\n")
112
+ end
113
+ sock.write "0\r\n\r\n"
114
+ else
115
+ while s = f.read(@@local_read_size)
116
+ sock.write s
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+
124
+ #-- Net::HTTP --
125
+
126
+ class HTTP
127
+ def request(req, body = nil, &block) # :yield: +response+
128
+ unless started?
129
+ start {
130
+ req['connection'] ||= 'close'
131
+ return request(req, body, &block)
132
+ }
133
+ end
134
+ if proxy_user()
135
+ unless use_ssl?
136
+ req.proxy_basic_auth proxy_user(), proxy_pass()
137
+ end
138
+ end
139
+ # set body
140
+ req.set_body_internal body
141
+ begin_transport req
142
+ # if we expect 100-continue then send a header first
143
+ send_only = ((req.is_a?(Post)||req.is_a?(Put)) && (req['expect']=='100-continue')) ? :header : nil
144
+ req.exec @socket, @curr_http_version, edit_path(req.path), send_only
145
+ begin
146
+ res = HTTPResponse.read_new(@socket)
147
+ # if we expected 100-continue then send a body
148
+ if res.is_a?(HTTPContinue) && send_only && req['content-length'].to_i > 0
149
+ req.exec @socket, @curr_http_version, edit_path(req.path), :body
150
+ end
151
+ end while res.kind_of?(HTTPContinue)
152
+ res.reading_body(@socket, req.response_body_permitted?) {
153
+ yield res if block_given?
154
+ }
155
+ end_transport req, res
156
+ res
157
+ end
158
+ end
159
+
160
+ end
@@ -1,5 +1,24 @@
1
1
  #
2
- # Copyright (c) 2007 RightScale Inc, all rights reserved
2
+ # Copyright (c) 2007-2008 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
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3
22
  #
4
23
 
5
24
  require "net/https"
@@ -7,12 +26,15 @@ require "uri"
7
26
  require "time"
8
27
  require "logger"
9
28
 
29
+ $:.unshift(File.dirname(__FILE__))
30
+ require "net_fix"
31
+
10
32
 
11
33
  module RightHttpConnection #:nodoc:
12
34
  module VERSION #:nodoc:
13
35
  MAJOR = 1
14
36
  MINOR = 2
15
- TINY = 0
37
+ TINY = 1
16
38
 
17
39
  STRING = [MAJOR, MINOR, TINY].join('.')
18
40
  end
@@ -114,6 +136,34 @@ them.
114
136
  @params[name] || @@params[name]
115
137
  end
116
138
 
139
+ # Query for the maximum size (in bytes) of a single read from the underlying
140
+ # socket. For bulk transfer, especially over fast links, this is value is
141
+ # critical to performance.
142
+ def socket_read_size?
143
+ Net::BufferedIO.socket_read_size?
144
+ end
145
+
146
+ # Set the maximum size (in bytes) of a single read from the underlying
147
+ # socket. For bulk transfer, especially over fast links, this is value is
148
+ # critical to performance.
149
+ def socket_read_size=(newsize)
150
+ Net::BufferedIO.socket_read_size=(newsize)
151
+ end
152
+
153
+ # Query for the maximum size (in bytes) of a single read from local data
154
+ # sources like files. This is important, for example, in a streaming PUT of a
155
+ # large buffer.
156
+ def local_read_size?
157
+ Net::HTTPGenericRequest.local_read_size?
158
+ end
159
+
160
+ # Set the maximum size (in bytes) of a single read from local data
161
+ # sources like files. This can be used to tune the performance of, for example, a streaming PUT of a
162
+ # large buffer.
163
+ def local_read_size=(newsize)
164
+ Net::HTTPGenericRequest.local_read_size=(newsize)
165
+ end
166
+
117
167
  private
118
168
  #--------------
119
169
  # Retry state - Keep track of errors on a per-server basis
@@ -292,18 +342,20 @@ them.
292
342
  # ... else just sleep a bit before new retry
293
343
  sleep(add_eof)
294
344
  end
295
-
296
345
  rescue Exception => e # See comment at bottom for the list of errors seen...
346
+ @http = nil
297
347
  # if ctrl+c is pressed - we have to reraise exception to terminate proggy
298
348
  if e.is_a?(Interrupt) && !( e.is_a?(Errno::ETIMEDOUT) || e.is_a?(Timeout::Error))
299
349
  @logger.debug( "#{err_header} request to server #{@server} interrupted by ctrl-c")
300
- @http = nil
301
350
  raise
351
+ elsif e.is_a?(ArgumentError) && e.message.include?('wrong number of arguments (5 for 4)')
352
+ # seems our net_fix patch was overriden...
353
+ exception = get_param(:exception) || RuntimeError
354
+ raise exception.new('incompatible Net::HTTP monkey-patch')
302
355
  end
303
356
  # oops - we got a banana: log it
304
357
  error_add(e.message)
305
358
  @logger.warn("#{err_header} request failure count: #{error_count}, exception: #{e.inspect}")
306
- @http = nil
307
359
  end
308
360
  end
309
361
  end
@@ -328,3 +380,4 @@ them.
328
380
  end
329
381
 
330
382
  end
383
+
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: right_http_connection
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.0
7
- date: 2007-10-17 00:00:00 +04:00
6
+ version: 1.2.1
7
+ date: 2008-02-11 00:00:00 -08:00
8
8
  summary: RightScale's robust HTTP/S connection module
9
9
  require_paths:
10
10
  - lib
@@ -33,6 +33,7 @@ files:
33
33
  - Manifest.txt
34
34
  - README.txt
35
35
  - Rakefile
36
+ - lib/net_fix.rb
36
37
  - lib/right_http_connection.rb
37
38
  - setup.rb
38
39
  test_files: []