faraday 0.8.7 → 0.8.8

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/Gemfile CHANGED
@@ -1,26 +1,20 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :development do
4
- gem 'sinatra', '~> 1.3'
5
- end
3
+ gem 'ffi-ncurses', '~> 0.3', :platforms => :jruby
4
+ gem 'jruby-openssl', '~> 0.8.8', :platforms => :jruby
5
+ gem 'rake'
6
6
 
7
7
  group :test do
8
- gem 'em-http-request', '~> 1.0', :require => 'em-http'
9
- gem 'em-synchrony', '~> 1.0', :require => ['em-synchrony', 'em-synchrony/em-http']
10
- gem 'excon', '>= 0.16.1'
11
- gem 'net-http-persistent', '~> 2.5', :require => false
12
- gem 'leftright', '~> 0.9', :require => false
13
- gem 'rack-test', '~> 0.6', :require => 'rack/test'
14
- end
15
-
16
- platforms :ruby do
17
- gem 'patron', '~> 0.4', '> 0.4.1'
18
- gem 'typhoeus', '~> 0.3.3'
19
- end
20
-
21
- platforms :jruby do
22
- gem 'jruby-openssl', '~> 0.7'
23
- gem 'ffi-ncurses', '~> 0.3'
8
+ gem 'em-http-request', '>= 1.1', :require => 'em-http'
9
+ gem 'em-synchrony', '>= 1.0', :require => ['em-synchrony', 'em-synchrony/em-http']
10
+ gem 'excon', '>= 0.25.3'
11
+ gem 'leftright', '>= 0.9', :require => false
12
+ gem 'net-http-persistent', '>= 2.5', :require => false
13
+ gem 'patron', '>= 0.4.2', :platforms => :ruby
14
+ gem 'rack-test', '>= 0.6', :require => 'rack/test'
15
+ gem 'simplecov'
16
+ gem 'sinatra', '~> 1.3'
17
+ gem 'typhoeus', '~> 0.3.3', :platforms => :ruby
24
18
  end
25
19
 
26
20
  gemspec
@@ -1,5 +1,5 @@
1
1
  module Faraday
2
- VERSION = "0.8.7"
2
+ VERSION = "0.8.8"
3
3
 
4
4
  class << self
5
5
  attr_accessor :root_path, :lib_path
@@ -7,7 +7,6 @@ module Faraday
7
7
  module Options
8
8
  def connection_config(env)
9
9
  options = {}
10
- configure_ssl(options, env)
11
10
  configure_proxy(options, env)
12
11
  configure_timeout(options, env)
13
12
  options
@@ -21,9 +20,6 @@ module Faraday
21
20
  # :file => 'path/to/file', # stream data off disk
22
21
  }
23
22
  configure_compression(options, env)
24
- # configure_proxy_auth
25
- # :proxy => {:authorization => [user, pass]}
26
- # proxy[:username] && proxy[:password]
27
23
  options
28
24
  end
29
25
 
@@ -32,20 +28,12 @@ module Faraday
32
28
  body.respond_to?(:read) ? body.read : body
33
29
  end
34
30
 
35
- def configure_ssl(options, env)
36
- if ssl = env[:ssl]
37
- # :ssl => {
38
- # :private_key_file => '/tmp/server.key',
39
- # :cert_chain_file => '/tmp/server.crt',
40
- # :verify_peer => false
41
- end
42
- end
43
-
44
31
  def configure_proxy(options, env)
45
32
  if proxy = request_options(env)[:proxy]
46
33
  options[:proxy] = {
47
34
  :host => proxy[:uri].host,
48
- :port => proxy[:uri].port
35
+ :port => proxy[:uri].port,
36
+ :authorization => [proxy[:user], proxy[:password]]
49
37
  }
50
38
  end
51
39
  end
@@ -114,6 +102,12 @@ module Faraday
114
102
  }
115
103
  end
116
104
  end
105
+ rescue EventMachine::Connectify::CONNECTError => err
106
+ if err.message.include?("Proxy Authentication Required")
107
+ raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
108
+ else
109
+ raise Error::ConnectionFailed, err
110
+ end
117
111
  end
118
112
 
119
113
  # TODO: reuse the connection to support pipelining
@@ -140,6 +134,8 @@ module Faraday
140
134
  elsif msg == Errno::ECONNREFUSED
141
135
  errklass = Faraday::Error::ConnectionFailed
142
136
  msg = "connection refused"
137
+ elsif msg == "connection closed by server"
138
+ errklass = Faraday::Error::ConnectionFailed
143
139
  end
144
140
  raise errklass, msg
145
141
  end
@@ -52,6 +52,8 @@ module Faraday
52
52
  client = block.call
53
53
  end
54
54
 
55
+ raise client.error if client.error
56
+
55
57
  save_response(env, client.response_header.status, client.response) do |resp_headers|
56
58
  client.response_header.each do |name, value|
57
59
  resp_headers[name.to_sym] = value
@@ -62,6 +64,12 @@ module Faraday
62
64
  @app.call env
63
65
  rescue Errno::ECONNREFUSED
64
66
  raise Error::ConnectionFailed, $!
67
+ rescue EventMachine::Connectify::CONNECTError => err
68
+ if err.message.include?("Proxy Authentication Required")
69
+ raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
70
+ else
71
+ raise Error::ConnectionFailed, err
72
+ end
65
73
  end
66
74
  end
67
75
  end
@@ -28,6 +28,16 @@ module Faraday
28
28
  opts[:connect_timeout] = req[:open_timeout]
29
29
  opts[:write_timeout] = req[:open_timeout]
30
30
  end
31
+
32
+ if req[:proxy]
33
+ opts[:proxy] = {
34
+ :host => req[:proxy][:uri].host,
35
+ :port => req[:proxy][:uri].port,
36
+ :scheme => req[:proxy][:uri].scheme,
37
+ :user => req[:proxy][:user],
38
+ :password => req[:proxy][:password]
39
+ }
40
+ end
31
41
  end
32
42
 
33
43
  conn = ::Excon.new(env[:url].to_s, opts)
@@ -1,4 +1,6 @@
1
- require 'faraday/adapter/net_http'
1
+ # Rely on autoloading instead of explicit require; helps avoid the "already
2
+ # initialized constant" warning on Ruby 1.8.7 when NetHttp is refereced below.
3
+ # require 'faraday/adapter/net_http'
2
4
 
3
5
  module Faraday
4
6
  class Adapter
@@ -6,18 +8,26 @@ module Faraday
6
8
  class NetHttpPersistent < NetHttp
7
9
  dependency 'net/http/persistent'
8
10
 
9
- # TODO: investigate is it safe to create a new Persistent instance for
10
- # every request, or does it defy the purpose of persistent connections
11
11
  def net_http_connection(env)
12
- Net::HTTP::Persistent.new 'Faraday',
13
- env[:request][:proxy] ? env[:request][:proxy][:uri] : nil
12
+ if proxy = env[:request][:proxy]
13
+ proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
14
+ proxy_uri.user = proxy_uri.password = nil
15
+ # awful patch for net-http-persistent 2.8 not unescaping user/password
16
+ (class << proxy_uri; self; end).class_eval do
17
+ define_method(:user) { proxy[:user] }
18
+ define_method(:password) { proxy[:password] }
19
+ end if proxy[:user]
20
+ end
21
+ Net::HTTP::Persistent.new 'Faraday', proxy_uri
14
22
  end
15
23
 
16
24
  def perform_request(http, env)
17
25
  http.request env[:url], create_request(env)
18
26
  rescue Net::HTTP::Persistent::Error => error
19
- if error.message.include? 'Timeout::Error'
27
+ if error.message.include? 'Timeout'
20
28
  raise Faraday::Error::TimeoutError, error
29
+ elsif error.message.include? 'connection refused'
30
+ raise Faraday::Error::ConnectionFailed, error
21
31
  else
22
32
  raise
23
33
  end
@@ -5,7 +5,7 @@ module Faraday
5
5
 
6
6
  def initialize(app, &block)
7
7
  super(app)
8
- @block = block if block_given?
8
+ @block = block
9
9
  end
10
10
 
11
11
  def call(env)
@@ -19,19 +19,19 @@ module Faraday
19
19
  if req = env[:request]
20
20
  session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
21
21
  session.connect_timeout = req[:open_timeout] if req[:open_timeout]
22
-
22
+
23
23
  if proxy = req[:proxy]
24
- session.proxy = proxy[:uri].to_s
25
- if proxy[:user] && proxy[:password]
26
- prepend_proxy_auth_string(proxy, session)
27
- end
24
+ proxy_uri = proxy[:uri].dup
25
+ proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
26
+ proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
27
+ session.proxy = proxy_uri.to_s
28
28
  end
29
29
  end
30
30
 
31
31
  response = begin
32
32
  data = env[:body] ? env[:body].to_s : nil
33
33
  session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
34
- rescue Errno::ECONNREFUSED
34
+ rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
35
35
  raise Error::ConnectionFailed, $!
36
36
  end
37
37
 
@@ -40,6 +40,12 @@ module Faraday
40
40
  @app.call env
41
41
  rescue ::Patron::TimeoutError => err
42
42
  raise Faraday::Error::TimeoutError, err
43
+ rescue ::Patron::Error => err
44
+ if err.message.include?("code 407")
45
+ raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
46
+ else
47
+ raise Error::ConnectionFailed, err
48
+ end
43
49
  end
44
50
 
45
51
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -58,9 +64,5 @@ module Faraday
58
64
  session
59
65
  end
60
66
  end
61
-
62
- def prepend_proxy_auth_string(proxy, session)
63
- session.proxy.insert(7, "#{proxy[:user]}:#{proxy[:password]}@")
64
- end
65
67
  end
66
68
  end
@@ -31,8 +31,13 @@ module Faraday
31
31
  end
32
32
 
33
33
  def request(env)
34
+ method = env[:method]
35
+ # For some reason, prevents Typhoeus from using "100-continue".
36
+ # We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
37
+ method = method.to_s.upcase if method == :put
38
+
34
39
  req = ::Typhoeus::Request.new env[:url].to_s,
35
- :method => env[:method],
40
+ :method => method,
36
41
  :body => env[:body],
37
42
  :headers => env[:request_headers],
38
43
  :disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
@@ -50,6 +55,15 @@ module Faraday
50
55
  end
51
56
  end
52
57
 
58
+ case resp.curl_return_code
59
+ when 0
60
+ # everything OK
61
+ when 7
62
+ raise Error::ConnectionFailed, resp.curl_error_message
63
+ else
64
+ raise Error::ClientError, resp.curl_error_message
65
+ end
66
+
53
67
  save_response(env, resp.code, resp.body) do |response_headers|
54
68
  response_headers.parse resp.headers
55
69
  end
@@ -76,8 +90,8 @@ module Faraday
76
90
 
77
91
  req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
78
92
 
79
- if proxy[:username] && proxy[:password]
80
- req.proxy_username = proxy[:username]
93
+ if proxy[:user] && proxy[:password]
94
+ req.proxy_username = proxy[:user]
81
95
  req.proxy_password = proxy[:password]
82
96
  end
83
97
  end
@@ -54,7 +54,13 @@ module Faraday
54
54
  @headers.update options[:headers] if options[:headers]
55
55
 
56
56
  @proxy = nil
57
- proxy(options.fetch(:proxy) { ENV['http_proxy'] })
57
+ proxy(options.fetch(:proxy) {
58
+ uri = ENV['http_proxy']
59
+ if uri && !uri.empty?
60
+ uri = 'http://' + uri if uri !~ /^http/i
61
+ uri
62
+ end
63
+ })
58
64
 
59
65
  yield self if block_given?
60
66
 
@@ -7,7 +7,7 @@ module Faraday
7
7
  match_content_type(env) do |params|
8
8
  env[:request] ||= {}
9
9
  env[:request][:boundary] ||= DEFAULT_BOUNDARY
10
- env[:request_headers][CONTENT_TYPE] += ";boundary=#{env[:request][:boundary]}"
10
+ env[:request_headers][CONTENT_TYPE] += "; boundary=#{env[:request][:boundary]}"
11
11
  env[:body] = create_multipart(env, params)
12
12
  end
13
13
  @app.call env
@@ -4,6 +4,9 @@ module Faraday
4
4
  case env[:status]
5
5
  when 404
6
6
  raise Faraday::Error::ResourceNotFound, response_values(env)
7
+ when 407
8
+ # mimic the behavior that we get with proxy requests with HTTPS
9
+ raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
7
10
  when 400...600
8
11
  raise Faraday::Error::ClientError, response_values(env)
9
12
  end
@@ -173,8 +173,8 @@ module Faraday
173
173
  ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/
174
174
 
175
175
  def escape(s)
176
- s.to_s.gsub(ESCAPE_RE) {
177
- '%' + $&.unpack('H2' * $&.bytesize).join('%').upcase
176
+ s.to_s.gsub(ESCAPE_RE) {|match|
177
+ '%' + match.unpack('H2' * match.bytesize).join('%').upcase
178
178
  }.tr(' ', '+')
179
179
  end
180
180
 
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: generate_certs
3
+ # Generate test certs for testing Faraday with SSL
4
+
5
+ require 'openssl'
6
+ require 'fileutils'
7
+
8
+ $shell = ARGV.include? '-s'
9
+
10
+ # Adapted from WEBrick::Utils. Skips cert extensions so it
11
+ # can be used as a CA bundle
12
+ def create_self_signed_cert(bits, cn, comment)
13
+ rsa = OpenSSL::PKey::RSA.new(bits)
14
+ cert = OpenSSL::X509::Certificate.new
15
+ cert.version = 2
16
+ cert.serial = 1
17
+ name = OpenSSL::X509::Name.new(cn)
18
+ cert.subject = name
19
+ cert.issuer = name
20
+ cert.not_before = Time.now
21
+ cert.not_after = Time.now + (365*24*60*60)
22
+ cert.public_key = rsa.public_key
23
+ cert.sign(rsa, OpenSSL::Digest::SHA1.new)
24
+ return [cert, rsa]
25
+ end
26
+
27
+ def write(file, contents, env_var)
28
+ FileUtils.mkdir_p(File.dirname(file))
29
+ File.open(file, 'w') {|f| f.puts(contents) }
30
+ puts %(export #{env_var}="#{file}") if $shell
31
+ end
32
+
33
+
34
+ # One cert / CA for ease of testing when ignoring verification
35
+ cert, key = create_self_signed_cert(1024, [['CN', 'localhost']], 'Faraday Test CA')
36
+ write 'tmp/faraday-cert.key', key, 'SSL_KEY'
37
+ write 'tmp/faraday-cert.crt', cert, 'SSL_FILE'
38
+
39
+ # And a second CA to prove that verification can fail
40
+ cert, key = create_self_signed_cert(1024, [['CN', 'real-ca.com']], 'A different CA')
41
+ write 'tmp/faraday-different-ca-cert.key', key, 'SSL_KEY_ALT'
42
+ write 'tmp/faraday-different-ca-cert.crt', cert, 'SSL_FILE_ALT'
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: script/proxy-server [-p PORT] [-u USER:PASSWORD]
3
+ require 'webrick'
4
+ require 'webrick/httpproxy'
5
+
6
+ port = 4001
7
+
8
+ if found = ARGV.index('-p')
9
+ port = ARGV[found + 1].to_i
10
+ end
11
+ if found = ARGV.index('-u')
12
+ username, password = ARGV[found + 1].split(':', 2)
13
+ end
14
+
15
+ match_credentials = lambda { |credentials|
16
+ got_username, got_password = credentials.to_s.unpack("m*")[0].split(":", 2)
17
+ got_username == username && got_password == password
18
+ }
19
+
20
+ log_io = $stdout
21
+ log_io.sync = true
22
+
23
+ webrick_opts = {
24
+ :Port => port, :Logger => WEBrick::Log::new(log_io),
25
+ :AccessLog => [[log_io, "[%{X-Faraday-Adapter}i] %m %U -> %s %b"]],
26
+ :ProxyAuthProc => lambda { |req, res|
27
+ if username
28
+ type, credentials = req.header['proxy-authorization'].first.to_s.split(/\s+/, 2)
29
+ unless "Basic" == type && match_credentials.call(credentials)
30
+ raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
31
+ end
32
+ end
33
+ }
34
+ }
35
+
36
+ proxy = WEBrick::HTTPProxyServer.new(webrick_opts)
37
+
38
+ trap(:TERM) { proxy.shutdown }
39
+ trap(:INT) { proxy.shutdown }
40
+
41
+ proxy.start
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ old_verbose, $VERBOSE = $VERBOSE, nil
3
+ begin
4
+ require File.expand_path('../../test/live_server', __FILE__)
5
+ ensure
6
+ $VERBOSE = old_verbose
7
+ end
8
+ require 'webrick'
9
+
10
+ port = 4000
11
+ if found = ARGV.index('-p')
12
+ port = ARGV[found + 1].to_i
13
+ end
14
+
15
+ log_io = $stdout
16
+ log_io.sync = true
17
+
18
+ webrick_opts = {
19
+ :Port => port, :Logger => WEBrick::Log::new(log_io),
20
+ :AccessLog => [[log_io, "[%{X-Faraday-Adapter}i] %m %U -> %s %b"]]
21
+ }
22
+
23
+ if ENV['SSL_KEY']
24
+ require 'openssl'
25
+ require 'webrick/https'
26
+ webrick_opts.update \
27
+ :SSLEnable => true,
28
+ :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read(ENV['SSL_KEY'])),
29
+ :SSLCertificate => OpenSSL::X509::Certificate.new(File.read(ENV['SSL_FILE'])),
30
+ :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
31
+ end
32
+
33
+ Rack::Handler::WEBrick.run(Faraday::LiveServer, webrick_opts) do |server|
34
+ trap(:INT) { server.stop }
35
+ trap(:TERM) { server.stop }
36
+ end
@@ -1,131 +1,170 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env bash
2
+ # Usage: script/test [file] [adapter]... -- [test/unit options]
2
3
  # Runs the test suite against a local server spawned automatically in a
3
4
  # thread. After tests are done, the server is shut down.
4
5
  #
5
6
  # If filename arguments are given, only those files are run. If arguments given
6
7
  # are not filenames, they are taken as words that filter the list of files to run.
7
8
  #
8
- # Examples
9
+ # Examples:
9
10
  #
10
11
  # $ script/test
11
12
  # $ script/test test/env_test.rb
12
13
  # $ script/test excon typhoeus
14
+ #
15
+ # # Run only tests matching /ssl/ for the net_http adapter, with SSL enabled.
13
16
  # $ SSL=yes script/test net_http -- -n /ssl/
17
+ #
18
+ # # Run against multiple rbenv versions
19
+ # $ RBENV_VERSIONS="1.9.3-p194 ree-1.8.7-2012.02" script/test
20
+ set -e
21
+
22
+ if [[ "$RUBYOPT" != *"bundler/setup"* ]]; then
23
+ export RUBYOPT="-rbundler/setup $RUBYOPT"
24
+ fi
25
+
26
+ port=3999
27
+ proxy_port=3998
28
+ scheme=http
29
+
30
+ if [ "$SSL" = "yes" ]; then
31
+ scheme=https
32
+ if [ -z "$SSL_KEY" ] || [ -z "$SSL_FILE" ]; then
33
+ eval "$(script/generate_certs -s)"
34
+ fi
35
+ fi
36
+
37
+ find_test_files() {
38
+ find "$1" -name '*_test.rb'
39
+ }
14
40
 
15
- require 'rubygems'
16
- require 'bundler'
17
- begin
18
- Bundler.setup
19
- rescue Bundler::GemNotFound
20
- $stderr.print "Error: "
21
- $stderr.puts $!.message
22
- warn "Run `bundle install` to install missing gems."
23
- exit 1
24
- end
25
-
26
- $VERBOSE = true
27
-
28
- host = 'localhost'
29
- logfile = 'log/test.log'
30
- test_glob = 'test/**/*_test.rb'
31
-
32
- if ssl_mode = ENV['SSL'] == 'yes'
33
- unless ENV['SSL_KEY'] and ENV['SSL_FILE']
34
- key_file = ENV['SSL_KEY'] = 'tmp/faraday-cert.key'
35
- cert_file = ENV['SSL_FILE'] = 'tmp/faraday-cert.crt'
36
- system 'rake', key_file, cert_file
37
- abort unless $?.success?
38
- end
39
- end
40
-
41
- require 'fileutils'
42
- FileUtils.mkdir_p 'log'
43
-
44
- # find available port
45
- require 'socket'
46
- port = begin
47
- server = TCPServer.new(host, 0)
48
- server.addr[1]
49
- ensure
50
- server.close if server
51
- end
52
-
53
- server = nil
54
-
55
- Thread.abort_on_exception = true
56
-
57
- # start test server in a separate thread
58
- thread = Thread.new do
59
- old_verbose, $VERBOSE = $VERBOSE, nil
60
- begin
61
- require File.expand_path('../../test/live_server', __FILE__)
62
- ensure
63
- $VERBOSE = old_verbose
64
- end
65
- require 'webrick'
66
- log_io = File.open logfile, 'w'
67
- log_io.sync = true
68
- webrick_opts = {
69
- :Port => port, :Logger => WEBrick::Log::new(log_io),
70
- :AccessLog => [[log_io, "[%{X-Faraday-Adapter}i] %m %U -> %s %b"]]
71
- }
72
- if ssl_mode
73
- require 'webrick/https'
74
- webrick_opts.update \
75
- :SSLEnable => true,
76
- :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read(key_file)),
77
- :SSLCertificate => OpenSSL::X509::Certificate.new(File.read(cert_file)),
78
- :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
79
- end
80
- Rack::Handler::WEBrick.run(Faraday::LiveServer, webrick_opts) {|serv| server = serv }
81
- end
82
-
83
- # find files to test
84
- test_files = Dir[test_glob]
85
- if ARGV.any?
86
- all_files, test_files = test_files, []
87
- args, extra_args = ARGV, []
88
- if idx = args.index('--')
89
- extra_args = args[(idx+1)..-1]
90
- args = args[0, idx]
91
- end
92
- for arg in args
93
- re = /(\b|_)#{arg}(\b|_)/
94
- test_files.concat all_files.select { |f| f =~ re }
95
- end
96
- test_files.concat extra_args
97
- end
98
-
99
- require 'net/https'
100
- conn = Net::HTTP.new host, port
101
- conn.open_timeout = conn.read_timeout = 0.1
102
- conn.use_ssl = ssl_mode
103
- conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
104
-
105
- # test if test server is accepting requests
106
- responsive = lambda { |path|
107
- begin
108
- res = conn.start { conn.get(path) }
109
- res.is_a?(Net::HTTPSuccess)
110
- rescue Errno::ECONNREFUSED, Errno::EBADF, Timeout::Error, Net::HTTPBadResponse
111
- false
112
- end
41
+ filter_matching() {
42
+ pattern="$1"
43
+ shift
44
+ for line in "$@"; do
45
+ [[ $line == *"$pattern"* ]] && echo "$line"
46
+ done
47
+ }
48
+
49
+ start_server() {
50
+ mkdir -p log
51
+ script/server -p $port >log/test.log 2>&1 &
52
+ echo $!
113
53
  }
114
54
 
115
- server_pings = 0
116
- begin
117
- # block until test server is ready
118
- thread.join 0.05
119
- server_pings += 1
120
- abort "test server didn't manage to start" if server_pings >= 50
121
- end until responsive.call('/echo')
55
+ start_proxy() {
56
+ mkdir -p log
57
+ script/proxy-server -p $proxy_port -u "faraday@test.local:there is cake" >log/proxy.log 2>&1 &
58
+ echo $!
59
+ }
122
60
 
123
- ENV['LIVE'] = "http#{ssl_mode ? 's' : ''}://#{host}:#{port}"
124
- ok = system 'ruby', '-Ilib:test',
125
- '-e', 'load(ARGV.shift) while ARGV.first =~ /^[^-]/',
126
- *test_files
61
+ server_started() {
62
+ lsof -i :${1?} >/dev/null
63
+ }
64
+
65
+ timestamp() {
66
+ date +%s
67
+ }
127
68
 
128
- server.respond_to?(:stop!) ? server.stop! : server.stop
129
- thread.join
69
+ wait_for_server() {
70
+ timeout=$(( `timestamp` + $1 ))
71
+ while true; do
72
+ if server_started "$2"; then
73
+ break
74
+ elif [ `timestamp` -gt "$timeout" ]; then
75
+ echo "timed out after $1 seconds" >&2
76
+ return 1
77
+ fi
78
+ done
79
+ }
80
+
81
+ filtered=
82
+ IFS=$'\n' test_files=($(find_test_files "test"))
83
+ declare -a explicit_files
84
+
85
+ # Process filter arguments:
86
+ # - test filenames as taken as-is
87
+ # - other words are taken as pattern to match the list of known files against
88
+ # - arguments after "--" are forwarded to the ruby process
89
+ while [ $# -gt 0 ]; do
90
+ arg="$1"
91
+ shift
92
+ if [ "$arg" = "--" ]; then
93
+ break
94
+ elif [ -f "$arg" ]; then
95
+ filtered=true
96
+ explicit_files[${#explicit_files[@]}+1]="$arg"
97
+ else
98
+ filtered=true
99
+ IFS=$'\n' explicit_files=(
100
+ ${explicit_files[@]}
101
+ $(filter_matching "$arg" "${test_files[@]}" || true)
102
+ )
103
+ fi
104
+ done
105
+
106
+ # If there were filter args, replace test files list with the results
107
+ if [ -n "$filtered" ]; then
108
+ if [ ${#explicit_files[@]} -eq 0 ]; then
109
+ echo "Error: no test files match" >&2
110
+ exit 1
111
+ else
112
+ test_files=(${explicit_files[@]})
113
+ echo running "${test_files[@]}"
114
+ fi
115
+ fi
116
+
117
+ # If there are any adapter tests, spin up the HTTP server
118
+ if [ -n "$(filter_matching "adapters" "${test_files[@]}")" ]; then
119
+ if server_started $port; then
120
+ echo "aborted: another instance of server running on $port" >&2
121
+ exit 1
122
+ fi
123
+ server_pid=$(start_server)
124
+ proxy_pid=$(start_proxy)
125
+ wait_for_server 15 $port || {
126
+ cat log/test.log
127
+ exit 1
128
+ }
129
+ wait_for_server 5 $proxy_port
130
+ cleanup() {
131
+ if [ $? -ne 0 ] && [ -n "$TRAVIS" ]; then
132
+ cat log/test.log
133
+ fi
134
+ kill "$server_pid"
135
+ kill "$proxy_pid"
136
+ }
137
+ trap cleanup INT EXIT
138
+ export LIVE="${scheme}://localhost:${port}"
139
+ export LIVE_PROXY="http://faraday%40test.local:there%20is%20cake@localhost:${proxy_port}"
140
+ fi
141
+
142
+ warnings="${TMPDIR:-/tmp}/faraday-warnings.$$"
143
+
144
+ run_test_files() {
145
+ # Save warnings on stderr to a separate file
146
+ RUBYOPT="$RUBYOPT -w" ruby -e 'while f=ARGV.shift and f!="--"; load f; end' "${test_files[@]}" -- "$@" \
147
+ 2> >(tee >(grep 'warning:' >"$warnings") | grep -v 'warning:')
148
+ }
149
+
150
+ check_warnings() {
151
+ # Display Ruby warnings from this project's source files. Abort if any were found.
152
+ num="$(grep -F "$PWD" "$warnings" | grep -v "${PWD}/bundle" | sort | uniq -c | sort -rn | tee /dev/stderr | wc -l)"
153
+ rm -f "$warnings"
154
+ if [ "$num" -gt 0 ]; then
155
+ echo "FAILED: this test suite doesn't tolerate Ruby syntax warnings!" >&2
156
+ exit 1
157
+ fi
158
+ }
130
159
 
131
- exit 1 unless ok
160
+ if [ -n "$RBENV_VERSIONS" ]; then
161
+ IFS=' ' versions=($RBENV_VERSIONS)
162
+ for version in "${versions[@]}"; do
163
+ echo "[${version}]"
164
+ RBENV_VERSION="$version" run_test_files "$@"
165
+ done
166
+ else
167
+ run_test_files "$@"
168
+ fi
169
+
170
+ check_warnings
@@ -8,6 +8,10 @@ module Adapters
8
8
  Integration.apply(self, :NonParallel) do
9
9
  # https://github.com/geemus/excon/issues/126 ?
10
10
  undef :test_timeout if ssl_mode?
11
+
12
+ # Excon lets OpenSSL::SSL::SSLError be raised without any way to
13
+ # distinguish whether it happened because of a 407 proxy response
14
+ undef :test_proxy_auth_fail if ssl_mode?
11
15
  end
12
16
  end
13
17
  end
@@ -57,7 +57,7 @@ module Adapters
57
57
  module Compression
58
58
  def test_GET_handles_compression
59
59
  res = get('echo_header', :name => 'accept-encoding')
60
- assert_match /gzip;.+\bdeflate\b/, res.body
60
+ assert_match(/gzip;.+\bdeflate\b/, res.body)
61
61
  end
62
62
  end
63
63
 
@@ -117,7 +117,7 @@ module Adapters
117
117
  resp = post('file') do |req|
118
118
  req.body = {'uploaded_file' => Faraday::UploadIO.new(__FILE__, 'text/x-ruby')}
119
119
  end
120
- assert_equal "file integration.rb text/x-ruby", resp.body
120
+ assert_equal "file integration.rb text/x-ruby #{File.size(__FILE__)}", resp.body
121
121
  end
122
122
 
123
123
  def test_PUT_send_url_encoded_params
@@ -166,6 +166,40 @@ module Adapters
166
166
  end
167
167
  end
168
168
 
169
+ def test_connection_error
170
+ assert_raise Faraday::Error::ConnectionFailed do
171
+ get 'http://localhost:4'
172
+ end
173
+ end
174
+
175
+ def test_proxy
176
+ proxy_uri = URI(ENV['LIVE_PROXY'])
177
+ conn = create_connection(:proxy => proxy_uri)
178
+
179
+ res = conn.get '/echo'
180
+ assert_equal 'get', res.body
181
+
182
+ unless self.class.ssl_mode?
183
+ # proxy can't append "Via" header for HTTPS responses
184
+ assert_match(/:#{proxy_uri.port}$/, res['via'])
185
+ end
186
+ end
187
+
188
+ def test_proxy_auth_fail
189
+ proxy_uri = URI(ENV['LIVE_PROXY'])
190
+ proxy_uri.password = 'WRONG'
191
+ conn = create_connection(:proxy => proxy_uri)
192
+
193
+ err = assert_raise Faraday::Error::ConnectionFailed do
194
+ conn.get '/echo'
195
+ end
196
+
197
+ unless self.class.ssl_mode? && self.class.jruby?
198
+ # JRuby raises "End of file reached" which cannot be distinguished from a 407
199
+ assert_equal %{407 "Proxy Authentication Required "}, err.message
200
+ end
201
+ end
202
+
169
203
  def adapter
170
204
  raise NotImplementedError.new("Need to override #adapter")
171
205
  end
@@ -5,10 +5,7 @@ module Adapters
5
5
 
6
6
  def adapter() :net_http_persistent end
7
7
 
8
- Integration.apply(self, :NonParallel) do
9
- # https://github.com/drbrain/net-http-persistent/issues/33
10
- undef :test_timeout
11
- end
8
+ Integration.apply(self, :NonParallel)
12
9
 
13
10
  end
14
11
  end
@@ -22,5 +22,10 @@ module Adapters
22
22
  rescue Faraday::Error::ClientError
23
23
  end
24
24
  end
25
+
26
+ # test not applicable
27
+ undef test_connection_error
28
+ undef test_proxy
29
+ undef test_proxy_auth_fail
25
30
  end
26
31
  end
@@ -8,6 +8,13 @@ module Adapters
8
8
  Integration.apply(self, :Parallel) do
9
9
  # https://github.com/dbalatero/typhoeus/issues/75
10
10
  undef :test_GET_with_body
11
+
12
+ # Not a Typhoeus bug, but WEBrick inability to handle "100-continue"
13
+ # which libcurl seems to generate for this particular request:
14
+ undef :test_POST_sends_files
15
+
16
+ # inconsistent outcomes ranging from successful response to connection error
17
+ undef :test_proxy_auth_fail if ssl_mode?
11
18
  end unless jruby?
12
19
 
13
20
  end
@@ -37,9 +37,9 @@ class AuthenticationMiddlewareTest < Faraday::TestCase
37
37
  response = conn { |b|
38
38
  b.request :token_auth, 'baz', :foo => 42
39
39
  }.get('/auth-echo')
40
- assert_match /^Token /, response.body
41
- assert_match /token="baz"/, response.body
42
- assert_match /foo="42"/, response.body
40
+ assert_match(/^Token /, response.body)
41
+ assert_match(/token="baz"/, response.body)
42
+ assert_match(/foo="42"/, response.body)
43
43
  end
44
44
 
45
45
  def test_token_middleware_does_not_interfere_with_existing_authorization
@@ -52,14 +52,14 @@ class AuthenticationMiddlewareTest < Faraday::TestCase
52
52
  response = conn { |b|
53
53
  b.request :authorization, 'custom', 'abc def'
54
54
  }.get('/auth-echo')
55
- assert_match /^custom abc def$/, response.body
55
+ assert_match(/^custom abc def$/, response.body)
56
56
  end
57
57
 
58
58
  def test_authorization_middleware_with_hash
59
59
  response = conn { |b|
60
60
  b.request :authorization, 'baz', :foo => 42
61
61
  }.get('/auth-echo')
62
- assert_match /^baz /, response.body
63
- assert_match /foo="42"/, response.body
62
+ assert_match(/^baz /, response.body)
63
+ assert_match(/foo="42"/, response.body)
64
64
  end
65
65
  end
@@ -93,9 +93,9 @@ class TestConnection < Faraday::TestCase
93
93
 
94
94
  conn.token_auth 'abcdef', :nonce => 'abc'
95
95
  assert auth = conn.headers['Authorization']
96
- assert_match /^Token /, auth
97
- assert_match /token="abcdef"/, auth
98
- assert_match /nonce="abc"/, auth
96
+ assert_match(/^Token /, auth)
97
+ assert_match(/token="abcdef"/, auth)
98
+ assert_match(/nonce="abc"/, auth)
99
99
  end
100
100
 
101
101
  def test_build_url_uses_connection_host_as_default_uri_host
@@ -263,6 +263,35 @@ class TestConnection < Faraday::TestCase
263
263
  end
264
264
  end
265
265
 
266
+ def test_proxy_accepts_env_without_scheme
267
+ with_env 'http_proxy', "localhost:8888" do
268
+ uri = Faraday::Connection.new.proxy[:uri]
269
+ assert_equal 'localhost', uri.host
270
+ assert_equal 8888, uri.port
271
+ end
272
+ end
273
+
274
+ def test_no_proxy_from_env
275
+ with_env 'http_proxy', nil do
276
+ conn = Faraday::Connection.new
277
+ assert_equal nil, conn.proxy
278
+ end
279
+ end
280
+
281
+ def test_no_proxy_from_blank_env
282
+ with_env 'http_proxy', '' do
283
+ conn = Faraday::Connection.new
284
+ assert_equal nil, conn.proxy
285
+ end
286
+ end
287
+
288
+ def test_proxy_doesnt_accept_uppercase_env
289
+ with_env 'HTTP_PROXY', "http://localhost:8888/" do
290
+ conn = Faraday::Connection.new
291
+ assert_nil conn.proxy
292
+ end
293
+ end
294
+
266
295
  def test_proxy_requires_uri
267
296
  conn = Faraday::Connection.new
268
297
  assert_raises ArgumentError do
@@ -3,6 +3,7 @@ unless ENV['CI']
3
3
  require 'simplecov'
4
4
  SimpleCov.start do
5
5
  add_filter 'test'
6
+ add_filter '/bundle/'
6
7
  end
7
8
  rescue LoadError
8
9
  end
@@ -20,14 +21,6 @@ end
20
21
 
21
22
  require File.expand_path('../../lib/faraday', __FILE__)
22
23
 
23
- begin
24
- require 'ruby-debug'
25
- rescue LoadError
26
- # ignore
27
- else
28
- Debugger.start
29
- end
30
-
31
24
  require 'stringio'
32
25
  require 'uri'
33
26
 
@@ -25,9 +25,11 @@ class LiveServer < Sinatra::Base
25
25
 
26
26
  post '/file' do
27
27
  if params[:uploaded_file].respond_to? :each_key
28
- "file %s %s" % [
28
+ "file %s %s %d" % [
29
29
  params[:uploaded_file][:filename],
30
- params[:uploaded_file][:type]]
30
+ params[:uploaded_file][:type],
31
+ params[:uploaded_file][:tempfile].size
32
+ ]
31
33
  else
32
34
  status 400
33
35
  end
@@ -0,0 +1 @@
1
+ ファイル
@@ -67,7 +67,7 @@ class RequestMiddlewareTest < Faraday::TestCase
67
67
  response = @conn.post('/echo', {:str => "eé cç aã aâ"})
68
68
  assert_equal "str=e%C3%A9+c%C3%A7+a%C3%A3+a%C3%A2", response.body
69
69
  }
70
- assert err.empty?
70
+ assert err.empty?, "stderr did include: #{err}"
71
71
  end
72
72
 
73
73
  def test_url_encoded_unicode_with_kcode_set
@@ -76,7 +76,7 @@ class RequestMiddlewareTest < Faraday::TestCase
76
76
  response = @conn.post('/echo', {:str => "eé cç aã aâ"})
77
77
  assert_equal "str=e%C3%A9+c%C3%A7+a%C3%A3+a%C3%A2", response.body
78
78
  }
79
- assert err.empty?
79
+ assert err.empty?, "stderr did include: #{err}"
80
80
  end
81
81
  end
82
82
 
@@ -96,7 +96,7 @@ class RequestMiddlewareTest < Faraday::TestCase
96
96
  response = @conn.post('/echo', payload)
97
97
 
98
98
  assert_kind_of Faraday::CompositeReadIO, response.body
99
- assert_equal "multipart/form-data;boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
99
+ assert_equal "multipart/form-data; boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
100
100
  response.headers['Content-Type']
101
101
 
102
102
  response.body.send(:ios).map{|io| io.read}.each do |io|
@@ -106,7 +106,7 @@ class RequestMiddlewareTest < Faraday::TestCase
106
106
  end
107
107
  assert_equal [], regexes
108
108
  end
109
-
109
+
110
110
  def test_multipart_with_arrays
111
111
  # assume params are out of order
112
112
  regexes = [
@@ -118,7 +118,7 @@ class RequestMiddlewareTest < Faraday::TestCase
118
118
  response = @conn.post('/echo', payload)
119
119
 
120
120
  assert_kind_of Faraday::CompositeReadIO, response.body
121
- assert_equal "multipart/form-data;boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
121
+ assert_equal "multipart/form-data; boundary=%s" % Faraday::Request::Multipart::DEFAULT_BOUNDARY,
122
122
  response.headers['Content-Type']
123
123
 
124
124
  response.body.send(:ios).map{|io| io.read}.each do |io|
@@ -128,5 +128,5 @@ class RequestMiddlewareTest < Faraday::TestCase
128
128
  end
129
129
  assert_equal [], regexes
130
130
  end
131
-
131
+
132
132
  end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestUtils < Faraday::TestCase
4
+
5
+ # emulates ActiveSupport::SafeBuffer#gsub
6
+ FakeSafeBuffer = Struct.new(:string) do
7
+ def to_s() self end
8
+ def gsub(regex)
9
+ string.gsub(regex) {
10
+ match, = $&, '' =~ /a/
11
+ yield match
12
+ }
13
+ end
14
+ end
15
+
16
+ def test_escaping_safe_buffer
17
+ str = FakeSafeBuffer.new('$32,000.00')
18
+ assert_equal '%2432%2C000.00', Faraday::Utils.escape(str)
19
+ end
20
+
21
+ end
22
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-24 00:00:00.000000000 Z
12
+ date: 2013-07-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multipart-post
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '1.1'
21
+ version: 1.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: '1.1'
29
+ version: 1.2.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rake
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -119,6 +119,11 @@ files:
119
119
  - test/middleware_stack_test.rb
120
120
  - test/request_middleware_test.rb
121
121
  - test/response_middleware_test.rb
122
+ - test/utils_test.rb
123
+ - test/multibyte.txt
124
+ - script/generate_certs
125
+ - script/proxy-server
126
+ - script/server
122
127
  - script/test
123
128
  homepage: https://github.com/lostisland/faraday
124
129
  licenses: