ridley 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -60,7 +60,6 @@ module Ridley
60
60
  end
61
61
 
62
62
  uri_hash = Addressable::URI.parse(server_url).to_hash.slice(:scheme, :host, :port)
63
-
64
63
  unless uri_hash[:port]
65
64
  uri_hash[:port] = (uri_hash[:scheme] == "https" ? 443 : 80)
66
65
  end
@@ -69,13 +68,8 @@ module Ridley
69
68
  @organization = org_match[1]
70
69
  end
71
70
 
72
- unless @organization.nil?
73
- uri_hash[:path] = "/organizations/#{@organization}"
74
- end
75
-
76
- server_uri = Addressable::URI.new(uri_hash)
77
-
78
- super(server_uri, options)
71
+ super(Addressable::URI.new(uri_hash), options)
72
+ @headers[:user_agent] = "Ridley v#{Ridley::VERSION}"
79
73
  end
80
74
 
81
75
  # @return [Symbol]
data/lib/ridley/errors.rb CHANGED
@@ -39,6 +39,16 @@ module Ridley
39
39
  class ClientKeyFileNotFound < BootstrapError; end
40
40
  class EncryptedDataBagSecretNotFound < BootstrapError; end
41
41
 
42
+ # Exception thrown when the maximum amount of requests is exceeded.
43
+ class RedirectLimitReached < RidleyError
44
+ attr_reader :response
45
+
46
+ def initialize(response)
47
+ super "too many redirects; last one to: #{response['location']}"
48
+ @response = response
49
+ end
50
+ end
51
+
42
52
  class HTTPError < RidleyError
43
53
  class << self
44
54
  def fabricate(env)
@@ -87,9 +97,15 @@ module Ridley
87
97
  end
88
98
  end
89
99
 
100
+ class HTTP3XXError < HTTPError; end
90
101
  class HTTP4XXError < HTTPError; end
91
102
  class HTTP5XXError < HTTPError; end
92
103
 
104
+ # 3XX
105
+ class HTTPMovedPermanently < HTTP3XXError; register_error(301); end
106
+ class HTTPFound < HTTP3XXError; register_error(302); end
107
+
108
+ # 4XX
93
109
  class HTTPBadRequest < HTTP4XXError; register_error(400); end
94
110
  class HTTPUnauthorized < HTTP4XXError; register_error(401); end
95
111
  class HTTPForbidden < HTTP4XXError; register_error(403); end
@@ -97,7 +113,8 @@ module Ridley
97
113
  class HTTPMethodNotAllowed < HTTP4XXError; register_error(405); end
98
114
  class HTTPRequestTimeout < HTTP4XXError; register_error(408); end
99
115
  class HTTPConflict < HTTP4XXError; register_error(409); end
100
-
116
+
117
+ # 5XX
101
118
  class HTTPInternalServerError < HTTP5XXError; register_error(500); end
102
119
  class HTTPNotImplemented < HTTP5XXError; register_error(501); end
103
120
  class HTTPBadGateway < HTTP5XXError; register_error(502); end
@@ -6,6 +6,7 @@ module Ridley
6
6
  require 'ridley/middleware/parse_json'
7
7
  require 'ridley/middleware/chef_response'
8
8
  require 'ridley/middleware/chef_auth'
9
+ require 'ridley/middleware/follow_redirects'
9
10
  require 'ridley/middleware/retry'
10
11
 
11
12
  Faraday.register_middleware :request,
@@ -17,6 +18,9 @@ module Ridley
17
18
  Faraday.register_middleware :response,
18
19
  json: -> { Ridley::Middleware::ParseJson }
19
20
 
21
+ Faraday.register_middleware :response,
22
+ follow_redirects: -> { Ridley::Middleware::FollowRedirects }
23
+
20
24
  Faraday.register_middleware :response,
21
25
  chef_response: -> { Ridley::Middleware::ChefResponse }
22
26
  end
@@ -0,0 +1,133 @@
1
+ require 'set'
2
+
3
+ module Ridley
4
+ module Middleware
5
+ # Borrowed and modified from:
6
+ # {https://github.com/lostisland/faraday_middleware/blob/master/lib/faraday_middleware/response/follow_redirects.rb}
7
+ #
8
+ # Public: Follow HTTP 301, 302, 303, and 307 redirects for GET, PATCH, POST,
9
+ # PUT, and DELETE requests.
10
+ #
11
+ # This middleware does not follow the HTTP specification for HTTP 302, by
12
+ # default, in that it follows the improper implementation used by most major
13
+ # web browsers which forces the redirected request to become a GET request
14
+ # regardless of the original request method.
15
+ #
16
+ # For HTTP 301, 302, and 303, the original request is transformed into a
17
+ # GET request to the response Location, by default. However, with standards
18
+ # compliance enabled, a 302 will instead act in accordance with the HTTP
19
+ # specification, which will replay the original request to the received
20
+ # Location, just as with a 307.
21
+ #
22
+ # For HTTP 307, the original request is replayed to the response Location,
23
+ # including original HTTP request method (GET, POST, PUT, DELETE, PATCH),
24
+ # original headers, and original body.
25
+ #
26
+ # This middleware currently only works with synchronous requests; in other
27
+ # words, it doesn't support parallelism.
28
+ class FollowRedirects < Faraday::Middleware
29
+ include Ridley::Logging
30
+
31
+ # HTTP methods for which 30x redirects can be followed
32
+ ALLOWED_METHODS = Set.new [:head, :options, :get, :post, :put, :patch, :delete]
33
+ # HTTP redirect status codes that this middleware implements
34
+ REDIRECT_CODES = Set.new [301, 302, 303, 307]
35
+ # Keys in env hash which will get cleared between requests
36
+ ENV_TO_CLEAR = Set.new [:status, :response, :response_headers]
37
+
38
+ # Default value for max redirects followed
39
+ FOLLOW_LIMIT = 3
40
+
41
+ # Public: Initialize the middleware.
42
+ #
43
+ # options - An options Hash (default: {}):
44
+ # limit - A Numeric redirect limit (default: 3)
45
+ # standards_compliant - A Boolean indicating whether to respect
46
+ # the HTTP spec when following 302
47
+ # (default: false)
48
+ # cookie - Use either an array of strings
49
+ # (e.g. ['cookie1', 'cookie2']) to choose kept cookies
50
+ # or :all to keep all cookies.
51
+ def initialize(app, options = {})
52
+ super(app)
53
+ @options = options
54
+
55
+ @replay_request_codes = Set.new [307]
56
+ @replay_request_codes << 302 if standards_compliant?
57
+ end
58
+
59
+ def call(env)
60
+ perform_with_redirection(env, follow_limit)
61
+ end
62
+
63
+ private
64
+
65
+ def perform_with_redirection(env, follows)
66
+ request_body = env[:body]
67
+ response = @app.call(env)
68
+
69
+ response.on_complete do |env|
70
+ if follow_redirect?(env, response)
71
+ log.debug { "==> request redirected to #{response['location']}" }
72
+ log.debug { "request env: #{env}" }
73
+
74
+ if follows.zero?
75
+ log.debug { "==> too many redirects" }
76
+ raise Ridley::Errors::RedirectLimitReached, response
77
+ end
78
+
79
+ env = update_env(env, request_body, response)
80
+ response = perform_with_redirection(env, follows - 1)
81
+ end
82
+ end
83
+ response
84
+ end
85
+
86
+ def update_env(env, request_body, response)
87
+ env[:url] += response['location']
88
+ if @options[:cookies]
89
+ cookies = keep_cookies(env)
90
+ env[:request_headers][:cookies] = cookies unless cookies.nil?
91
+ end
92
+
93
+ env[:body] = request_body
94
+
95
+ ENV_TO_CLEAR.each {|key| env.delete key }
96
+
97
+ env
98
+ end
99
+
100
+ def follow_redirect?(env, response)
101
+ ALLOWED_METHODS.include? env[:method] and
102
+ REDIRECT_CODES.include? response.status
103
+ end
104
+
105
+ def follow_limit
106
+ @options.fetch(:limit, FOLLOW_LIMIT)
107
+ end
108
+
109
+ def keep_cookies(env)
110
+ cookies = @options.fetch(:cookies, [])
111
+ response_cookies = env[:response_headers][:cookies]
112
+ cookies == :all ? response_cookies : selected_request_cookies(response_cookies)
113
+ end
114
+
115
+ def selected_request_cookies(cookies)
116
+ selected_cookies(cookies)[0...-1]
117
+ end
118
+
119
+ def selected_cookies(cookies)
120
+ "".tap do |cookie_string|
121
+ @options[:cookies].each do |cookie|
122
+ string = /#{cookie}=?[^;]*/.match(cookies)[0] + ';'
123
+ cookie_string << string
124
+ end
125
+ end
126
+ end
127
+
128
+ def standards_compliant?
129
+ @options.fetch(:standards_compliant, false)
130
+ end
131
+ end
132
+ end
133
+ end
@@ -109,10 +109,16 @@ module Ridley
109
109
  upload_path = url.path
110
110
  url.path = ""
111
111
 
112
- Faraday.new(url, client.options.slice(*Connection::VALID_OPTIONS)) do |c|
113
- c.request :chef_auth, client.client_name, client.client_key
114
- c.adapter :net_http
115
- end.put(upload_path, contents, headers)
112
+ begin
113
+ Faraday.new(url, client.options.slice(*Connection::VALID_OPTIONS)) do |c|
114
+ c.response :chef_response
115
+ c.response :follow_redirects
116
+ c.request :chef_auth, client.client_name, client.client_key
117
+ c.adapter :net_http
118
+ end.put(upload_path, contents, headers)
119
+ rescue Ridley::Errors::HTTPError => ex
120
+ abort(ex)
121
+ end
116
122
  end
117
123
  end
118
124
  end
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "0.8.1"
2
+ VERSION = "0.8.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ridley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
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-01 00:00:00.000000000 Z
12
+ date: 2013-03-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -300,6 +300,7 @@ files:
300
300
  - lib/ridley/middleware.rb
301
301
  - lib/ridley/middleware/chef_auth.rb
302
302
  - lib/ridley/middleware/chef_response.rb
303
+ - lib/ridley/middleware/follow_redirects.rb
303
304
  - lib/ridley/middleware/parse_json.rb
304
305
  - lib/ridley/middleware/retry.rb
305
306
  - lib/ridley/mixin.rb
@@ -400,7 +401,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
400
401
  version: '0'
401
402
  segments:
402
403
  - 0
403
- hash: -2528594805736736498
404
+ hash: -4124005785219237787
404
405
  requirements: []
405
406
  rubyforge_project:
406
407
  rubygems_version: 1.8.24