right_http_connection 1.2.4 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ba2dac9f5194cfcb8a8e6dec24f973418d07f22
4
+ data.tar.gz: 59e6d3f82e45ca7679849320fc7fd89f6e776d20
5
+ SHA512:
6
+ metadata.gz: fd754b030589555f947f2a52bb64c4d3524c902f3e0d95c00fbecf5a340c06d7d6353360763b225b3e05464357610e2dae54d7e21df17b899a65c3bef5430c02
7
+ data.tar.gz: 2ee74c4fc7cf86908f8a06b96be6cd892aeb25e16a345ea959e0fbe7907712a126c73704c8a3da013dec9443cecd8cc6e1caace3ebd4737c7e0e4da4e5287488
data/History.txt CHANGED
@@ -57,3 +57,30 @@ Initial public release
57
57
  * fixed a bug: <NoMethodError: You have a nil object when you didn't expect it!
58
58
  The error occurred while evaluating nil.body_stream>
59
59
 
60
+ == 1.2.5
61
+
62
+ - ActiveSupport dependency removal
63
+
64
+
65
+ == 1.3.0
66
+ - Added:
67
+ - support for using through proxies
68
+ - functional tests
69
+
70
+ == 1.3.1
71
+ - Added:
72
+ - SSL certificate handshake support
73
+ - more specs
74
+ - ability to give client side key and certificate inline
75
+ - Fixed: some minor glitches
76
+
77
+ == 1.4.0
78
+ - Added
79
+ - license
80
+ - HTTP_PROXY env variable support
81
+ - Fixed
82
+ - context-length issue (thx kristianm)
83
+ - exception handling
84
+ - connection is now closed on any exception
85
+ - connection is reestablished when credentials change
86
+ - some other minor bugs
data/Manifest.txt CHANGED
@@ -4,4 +4,5 @@ README.txt
4
4
  Rakefile
5
5
  lib/net_fix.rb
6
6
  lib/right_http_connection.rb
7
+ lib/support.rb
7
8
  setup.rb
data/Rakefile CHANGED
@@ -1,72 +1,34 @@
1
1
  require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
2
4
  require 'rake'
3
5
  require 'rake/clean'
4
6
  require 'rake/testtask'
5
7
  require 'rake/packagetask'
6
- require 'rake/gempackagetask'
7
- require 'rake/rdoctask'
8
- require 'rake/contrib/rubyforgepublisher'
8
+ #require 'rake/gempackagetask'
9
+ #require 'rake/rdoctask'
10
+ #require 'rake/contrib/rubyforgepublisher'
11
+ require 'rspec/core/rake_task'
12
+ require 'cucumber/rake/task'
9
13
  require 'fileutils'
10
- require 'hoe'
11
14
  include FileUtils
12
15
  require File.join(File.dirname(__FILE__), 'lib', 'right_http_connection')
13
16
 
14
- AUTHOR = 'RightScale' # can also be an array of Authors
15
- EMAIL = "rubygems@rightscale.com"
16
- DESCRIPTION = "RightScale's robust HTTP/S connection module"
17
- GEM_NAME = 'right_http_connection' # what ppl will type to install your gem
18
- RUBYFORGE_PROJECT = 'rightscale' # The unix name for your project
19
- HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
- DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
21
-
22
- NAME = "right_http_connection"
23
- REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
- VERS = RightHttpConnection::VERSION::STRING + (REV ? ".#{REV}" : "")
25
- CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
26
- RDOC_OPTS = ['--quiet', '--title', 'right_http_connection documentation',
27
- "--opname", "index.html",
28
- "--line-numbers",
29
- "--main", "README",
30
- "--inline-source"]
31
-
32
- # Suppress Hoe's self-inclusion as a dependency for our Gem. This also keeps
33
- # Rake & rubyforge out of the dependency list. Users must manually install
34
- # these gems to run tests, etc.
35
- # TRB 2/19/09: also do this for the extra_dev_deps array present in newer hoes.
36
- # Older versions of RubyGems will try to install developer-dependencies as
37
- # required runtime dependencies....
38
- class Hoe
39
- def extra_deps
40
- @extra_deps.reject do |x|
41
- Array(x).first == 'hoe'
42
- end
43
- end
44
- def extra_dev_deps
45
- @extra_dev_deps.reject do |x|
46
- Array(x).first == 'hoe'
47
- end
48
- end
49
- end
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ =begin
50
20
 
51
- # Generate all the Rake tasks
52
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
53
- hoe = Hoe.new(GEM_NAME, VERS) do |p|
54
- p.author = AUTHOR
55
- p.description = DESCRIPTION
56
- p.email = EMAIL
57
- p.summary = DESCRIPTION
58
- p.url = HOMEPATH
59
- p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
60
- p.test_globs = ["test/**/test_*.rb"]
61
- p.clean_globs = CLEAN #An array of file patterns to delete on clean.
62
- p.remote_rdoc_dir = "right_http_gem_doc"
63
-
64
- # == Optional
65
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
66
- #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
67
- #p.spec_extras = {} # A hash of extra values to set in the gemspec.
21
+ # == Gem == #
22
+
23
+ gemtask = Rake::GemPackageTask.new(Gem::Specification.load("right_http_connection.gemspec")) do |package|
24
+ package.package_dir = ENV['PACKAGE_DIR'] || 'pkg'
25
+ package.need_zip = true
26
+ package.need_tar = true
68
27
  end
69
28
 
29
+ directory gemtask.package_dir
30
+
31
+ CLEAN.include(gemtask.package_dir)
70
32
 
71
33
  desc 'Generate website files'
72
34
  task :website_generate do
@@ -101,3 +63,30 @@ task :check_version do
101
63
  exit
102
64
  end
103
65
  end
66
+ =end
67
+
68
+ task :default => 'spec'
69
+
70
+ # == Unit Tests == #
71
+
72
+ desc "Run unit tests"
73
+ RSpec::Core::RakeTask.new
74
+
75
+ namespace :spec do
76
+ desc "Run unit tests with RCov"
77
+ RSpec::Core::RakeTask.new(:rcov) do |t|
78
+ t.rcov = true
79
+ t.rcov_opts = %q[--exclude "spec"]
80
+ end
81
+
82
+ desc "Print Specdoc for unit tests"
83
+ RSpec::Core::RakeTask.new(:doc) do |t|
84
+ t.rspec_opts = ["--format", "documentation"]
85
+ end
86
+ end
87
+
88
+ # == Functional tests == #
89
+ desc "Run functional tests"
90
+ Cucumber::Rake::Task.new do |t|
91
+ t.cucumber_opts = %w{--color --format pretty}
92
+ end
@@ -25,6 +25,7 @@
25
25
  # Net::HTTP and Net::HTTPGenericRequest fixes to support 100-continue on
26
26
  # POST and PUT. The request must have 'expect' field set to '100-continue'.
27
27
 
28
+ require 'timeout'
28
29
 
29
30
  module Net
30
31
 
@@ -48,7 +49,7 @@ module Net
48
49
  end
49
50
 
50
51
  def rbuf_fill
51
- timeout(@read_timeout) {
52
+ Timeout.timeout(@read_timeout) {
52
53
  @rbuf << @io.sysread(@@socket_read_size)
53
54
  }
54
55
  end
@@ -91,18 +92,30 @@ module Net
91
92
  private
92
93
 
93
94
  def send_request_with_body(sock, ver, path, body, send_only=nil)
94
- self.content_length = body.length
95
+ self.content_length = body.respond_to?(:bytesize) ? body.bytesize : body.length
95
96
  delete 'Transfer-Encoding'
96
97
  supply_default_content_type
97
98
  write_header(sock, ver, path) unless send_only == :body
98
- sock.write(body) unless send_only == :header
99
+ sock.write(body && body.to_s) unless send_only == :header
99
100
  end
100
101
 
101
102
  def send_request_with_body_stream(sock, ver, path, f, send_only=nil)
103
+ # KD: Fix 'content-length': it must not be greater than a piece of file left to be read.
104
+ # Otherwise the connection may behave like crazy causing 4xx or 5xx responses
105
+ #
106
+ # Only do this helpful thing if the stream responds to :pos (it may be something
107
+ # that responds to :read and :size but not :pos).
108
+ if f.respond_to?(:pos)
109
+ file_size = f.respond_to?(:lstat) ? f.lstat.size : f.size
110
+ bytes_to_read = [ file_size - f.pos, self.content_length.to_i ].sort.first
111
+ self.content_length = bytes_to_read
112
+ end
113
+
102
114
  unless content_length() or chunked?
103
115
  raise ArgumentError,
104
116
  "Content-Length not given and Transfer-Encoding is not `chunked'"
105
117
  end
118
+ bytes_to_read ||= content_length()
106
119
  supply_default_content_type
107
120
  write_header(sock, ver, path) unless send_only == :body
108
121
  unless send_only == :header
@@ -112,8 +125,14 @@ module Net
112
125
  end
113
126
  sock.write "0\r\n\r\n"
114
127
  else
115
- while s = f.read(@@local_read_size)
128
+ # KD: When we read/write over file EOF it sometimes make the connection unstable
129
+ read_size = [ @@local_read_size, bytes_to_read ].sort.first
130
+ while s = f.read(read_size)
116
131
  sock.write s
132
+ # Make sure we do not read over EOF or more than expected content-length
133
+ bytes_to_read -= read_size
134
+ break if bytes_to_read <= 0
135
+ read_size = bytes_to_read if bytes_to_read < read_size
117
136
  end
118
137
  end
119
138
  end
@@ -144,6 +163,7 @@ module Net
144
163
  req.exec @socket, @curr_http_version, edit_path(req.path), send_only
145
164
  begin
146
165
  res = HTTPResponse.read_new(@socket)
166
+ res.decode_content = req.decode_content if RUBY_VERSION > '2.0'
147
167
  # if we expected 100-continue then send a body
148
168
  if res.is_a?(HTTPContinue) && send_only && req['content-length'].to_i > 0
149
169
  req.exec @socket, @curr_http_version, edit_path(req.path), :body
@@ -0,0 +1,109 @@
1
+ # These are ActiveSupport-;like extensions to do a few handy things in the gems
2
+ # Derived from ActiveSupport, so the AS copyright notice applies:
3
+ #
4
+ #
5
+ #
6
+ # Copyright (c) 2005 David Heinemeier Hansson
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining
9
+ # a copy of this software and associated documentation files (the
10
+ # "Software"), to deal in the Software without restriction, including
11
+ # without limitation the rights to use, copy, modify, merge, publish,
12
+ # distribute, sublicense, and/or sell copies of the Software, and to
13
+ # permit persons to whom the Software is furnished to do so, subject to
14
+ # the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be
17
+ # included in all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ #++
27
+ #
28
+ #
29
+ class String #:nodoc:
30
+
31
+ # Constantize tries to find a declared constant with the name specified
32
+ # in the string. It raises a NameError when the name is not in CamelCase
33
+ # or is not initialized.
34
+ #
35
+ # Examples
36
+ # "Module".constantize #=> Module
37
+ # "Class".constantize #=> Class
38
+ def right_constantize()
39
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
40
+ raise NameError, "#{self.inspect} is not a valid constant name!"
41
+ end
42
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
43
+ end
44
+
45
+ def right_camelize()
46
+ self.dup.split(/_/).map{ |word| word.capitalize }.join('')
47
+ end
48
+
49
+ end
50
+
51
+
52
+ class Object #:nodoc:
53
+ # "", " ", nil, [], and {} are blank
54
+ def right_blank?
55
+ if respond_to?(:empty?) && respond_to?(:strip)
56
+ empty? or strip.empty?
57
+ elsif respond_to?(:empty?)
58
+ empty?
59
+ else
60
+ !self
61
+ end
62
+ end
63
+ end
64
+
65
+ class NilClass #:nodoc:
66
+ def right_blank?
67
+ true
68
+ end
69
+ end
70
+
71
+ class FalseClass #:nodoc:
72
+ def right_blank?
73
+ true
74
+ end
75
+ end
76
+
77
+ class TrueClass #:nodoc:
78
+ def right_blank?
79
+ false
80
+ end
81
+ end
82
+
83
+ class Array #:nodoc:
84
+ alias_method :right_blank?, :empty?
85
+ end
86
+
87
+ class Hash #:nodoc:
88
+ alias_method :right_blank?, :empty?
89
+
90
+ # Return a new hash with all keys converted to symbols.
91
+ def right_symbolize_keys
92
+ inject({}) do |options, (key, value)|
93
+ options[key.to_sym] = value
94
+ options
95
+ end
96
+ end
97
+ end
98
+
99
+ class String #:nodoc:
100
+ def right_blank?
101
+ empty? || strip.empty?
102
+ end
103
+ end
104
+
105
+ class Numeric #:nodoc:
106
+ def right_blank?
107
+ false
108
+ end
109
+ end
@@ -0,0 +1,32 @@
1
+ #-- -*- mode: ruby; encoding: utf-8 -*-
2
+ # Copyright: Copyright (c) 2010 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 RightHttpConnection #:nodoc:
25
+ module VERSION #:nodoc:
26
+ MAJOR = 1 unless defined?(MAJOR)
27
+ MINOR = 5 unless defined?(MINOR)
28
+ TINY = 1 unless defined?(TINY)
29
+
30
+ STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
31
+ end
32
+ end