ridley 0.8.1 → 0.8.2

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.
@@ -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