github_api 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/github_api/api.rb +10 -0
- data/lib/github_api/client/repos/contents.rb +4 -1
- data/lib/github_api/configuration.rb +2 -0
- data/lib/github_api/mash.rb +7 -0
- data/lib/github_api/middleware.rb +2 -0
- data/lib/github_api/response/follow_redirects.rb +140 -0
- data/lib/github_api/response/header.rb +4 -1
- data/lib/github_api/response/mashify.rb +2 -3
- data/lib/github_api/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26afc4d14a19b64a2afdb606f617a8adb4feca39
|
4
|
+
data.tar.gz: d8dc7404e573e3795fc614f419161b5a741fca79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9aee22020a61cb8f71d7ef5906d30a06781e94106ccdc609fc6587114b051f3cbab67d70c3d9ed0bc9b2a7a4d02b63755833aa63305f468f6a081a4378e2b7d
|
7
|
+
data.tar.gz: ae1f3c5346bb2f6c231c5a2e950ee5ed966c1a3cff3d9f2ab8d4401a27e746cbc701a0149b8f681d1dca040d905d4db789b3f9610ddb8b33ecde5715f89d7113
|
data/README.md
CHANGED
data/lib/github_api/api.rb
CHANGED
@@ -79,6 +79,16 @@ module Github
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
# Disable following redirects inside a block
|
83
|
+
#
|
84
|
+
# @api public
|
85
|
+
def disable_redirects
|
86
|
+
self.follow_redirects = false
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
self.follow_redirects = true
|
90
|
+
end
|
91
|
+
|
82
92
|
# List of before callbacks
|
83
93
|
#
|
84
94
|
# @api public
|
@@ -235,7 +235,10 @@ module Github
|
|
235
235
|
archive_format = params.delete('archive_format') || 'tarball'
|
236
236
|
ref = params.delete('ref') || 'master'
|
237
237
|
|
238
|
-
|
238
|
+
disable_redirects do
|
239
|
+
response = get_request("/repos/#{arguments.user}/#{arguments.repo}/#{archive_format}/#{ref}", params)
|
240
|
+
response.headers.location
|
241
|
+
end
|
239
242
|
end
|
240
243
|
end # Client::Repos::Contents
|
241
244
|
end # Github
|
@@ -6,6 +6,7 @@ require 'github_api/response/jsonize'
|
|
6
6
|
require 'github_api/response/atom_parser'
|
7
7
|
require 'github_api/response/raise_error'
|
8
8
|
require 'github_api/response/header'
|
9
|
+
require 'github_api/response/follow_redirects'
|
9
10
|
|
10
11
|
module Github
|
11
12
|
class Middleware
|
@@ -18,6 +19,7 @@ module Github
|
|
18
19
|
builder.use Github::Request::OAuth2, api.oauth_token if api.oauth_token?
|
19
20
|
builder.use Github::Request::BasicAuth, api.authentication if api.basic_authed?
|
20
21
|
|
22
|
+
builder.use Github::Response::FollowRedirects if api.follow_redirects
|
21
23
|
builder.use Faraday::Response::Logger if ENV['DEBUG']
|
22
24
|
unless options[:raw]
|
23
25
|
builder.use Github::Response::Mashify
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
# First saw on octokit, then copied from lostisland/faraday_middleware
|
5
|
+
# and adapted for this library.
|
6
|
+
#
|
7
|
+
# faraday_middleware/lib/faraday_middleware/response/follow_redirects.rb
|
8
|
+
|
9
|
+
module Github
|
10
|
+
# Public: Exception thrown when the maximum amount of requests is exceeded.
|
11
|
+
class RedirectLimitReached < Faraday::Error::ClientError
|
12
|
+
attr_reader :response
|
13
|
+
|
14
|
+
def initialize(response)
|
15
|
+
super "too many redirects; last one to: #{response['location']}"
|
16
|
+
@response = response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Follow HTTP 301, 302, 303, 307, and 308 redirects.
|
21
|
+
#
|
22
|
+
# For HTTP 301, 302, and 303, the original GET, POST, PUT, DELETE, or PATCH
|
23
|
+
# request gets converted into a GET. With `:standards_compliant => true`,
|
24
|
+
# however, the HTTP method after 301/302 remains unchanged. This allows you
|
25
|
+
# to opt into HTTP/1.1 compliance and act unlike the major web browsers.
|
26
|
+
#
|
27
|
+
# This middleware currently only works with synchronous requests; i.e. it
|
28
|
+
# doesn't support parallelism.
|
29
|
+
#
|
30
|
+
# If you wish to persist cookies across redirects, you could use
|
31
|
+
# the faraday-cookie_jar gem:
|
32
|
+
#
|
33
|
+
# Faraday.new(:url => url) do |faraday|
|
34
|
+
# faraday.use FaradayMiddleware::FollowRedirects
|
35
|
+
# faraday.use :cookie_jar
|
36
|
+
# faraday.adapter Faraday.default_adapter
|
37
|
+
# end
|
38
|
+
|
39
|
+
class Response::FollowRedirects < Faraday::Middleware
|
40
|
+
# HTTP methods for which 30x redirects can be followed
|
41
|
+
ALLOWED_METHODS = Set.new [:head, :options, :get, :post, :put, :patch, :delete]
|
42
|
+
# HTTP redirect status codes that this middleware implements
|
43
|
+
REDIRECT_CODES = Set.new [301, 302, 303, 307, 308]
|
44
|
+
# Keys in env hash which will get cleared between requests
|
45
|
+
ENV_TO_CLEAR = Set.new [:status, :response, :response_headers]
|
46
|
+
|
47
|
+
# Default value for max redirects followed
|
48
|
+
FOLLOW_LIMIT = 3
|
49
|
+
|
50
|
+
# Regex that matches characters that need to be escaped in URLs, sans
|
51
|
+
# the "%" character which we assume already represents an escaped sequence.
|
52
|
+
URI_UNSAFE = /[^\-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]%]/
|
53
|
+
|
54
|
+
# Public: Initialize the middleware.
|
55
|
+
#
|
56
|
+
# options - An options Hash (default: {}):
|
57
|
+
# :limit - A Numeric redirect limit (default: 3)
|
58
|
+
# :standards_compliant - A Boolean indicating whether to respect
|
59
|
+
# the HTTP spec when following 301/302
|
60
|
+
# (default: false)
|
61
|
+
# :callback - A callable that will be called on redirects
|
62
|
+
# with the old and new envs
|
63
|
+
def initialize(app, options = {})
|
64
|
+
super(app)
|
65
|
+
@options = options
|
66
|
+
|
67
|
+
@convert_to_get = Set.new [303]
|
68
|
+
@convert_to_get << 301 << 302 unless standards_compliant?
|
69
|
+
end
|
70
|
+
|
71
|
+
def call(env)
|
72
|
+
perform_with_redirection(env, follow_limit)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def convert_to_get?(response)
|
78
|
+
![:head, :options].include?(response.env[:method]) &&
|
79
|
+
@convert_to_get.include?(response.status)
|
80
|
+
end
|
81
|
+
|
82
|
+
def perform_with_redirection(env, follows)
|
83
|
+
request_body = env[:body]
|
84
|
+
response = @app.call(env)
|
85
|
+
|
86
|
+
response.on_complete do |response_env|
|
87
|
+
if follow_redirect?(response_env, response)
|
88
|
+
raise RedirectLimitReached, response if follows.zero?
|
89
|
+
new_request_env = update_env(response_env.dup, request_body, response)
|
90
|
+
callback.call(response_env, new_request_env) if callback
|
91
|
+
response = perform_with_redirection(new_request_env, follows - 1)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
response
|
95
|
+
end
|
96
|
+
|
97
|
+
def update_env(env, request_body, response)
|
98
|
+
env[:url] += safe_escape(response['location'])
|
99
|
+
|
100
|
+
if convert_to_get?(response)
|
101
|
+
env[:method] = :get
|
102
|
+
env[:body] = nil
|
103
|
+
else
|
104
|
+
env[:body] = request_body
|
105
|
+
end
|
106
|
+
|
107
|
+
ENV_TO_CLEAR.each {|key| env.delete key }
|
108
|
+
|
109
|
+
env
|
110
|
+
end
|
111
|
+
|
112
|
+
def follow_redirect?(env, response)
|
113
|
+
ALLOWED_METHODS.include? env[:method] and
|
114
|
+
REDIRECT_CODES.include? response.status
|
115
|
+
end
|
116
|
+
|
117
|
+
def follow_limit
|
118
|
+
@options.fetch(:limit, FOLLOW_LIMIT)
|
119
|
+
end
|
120
|
+
|
121
|
+
def standards_compliant?
|
122
|
+
@options.fetch(:standards_compliant, false)
|
123
|
+
end
|
124
|
+
|
125
|
+
def callback
|
126
|
+
@options[:callback]
|
127
|
+
end
|
128
|
+
|
129
|
+
# Internal: escapes unsafe characters from an URL which might be a path
|
130
|
+
# component only or a fully qualified URI so that it can be joined onto an
|
131
|
+
# URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
|
132
|
+
# risk double-escaping.
|
133
|
+
def safe_escape(uri)
|
134
|
+
uri = uri.split('#')[0] # we want to remove the fragment if present
|
135
|
+
uri.to_s.gsub(URI_UNSAFE) { |match|
|
136
|
+
'%' + match.unpack('H2' * match.bytesize).join('%').upcase
|
137
|
+
}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -13,6 +13,10 @@ module Github
|
|
13
13
|
!!env
|
14
14
|
end
|
15
15
|
|
16
|
+
def [](property)
|
17
|
+
loaded? ? env[:response_headers][property] : nil
|
18
|
+
end
|
19
|
+
|
16
20
|
def oauth_scopes
|
17
21
|
loaded? ? env[:response_headers][OAUTH_SCOPES] : nil
|
18
22
|
end
|
@@ -76,7 +80,6 @@ module Github
|
|
76
80
|
def body
|
77
81
|
loaded? ? env[:body] : nil
|
78
82
|
end
|
79
|
-
|
80
83
|
end # Header
|
81
84
|
end # Response
|
82
85
|
end # Github
|
@@ -2,13 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'faraday'
|
4
4
|
require 'hashie'
|
5
|
+
require 'github_api/mash'
|
5
6
|
|
6
7
|
module Github
|
7
8
|
class Response::Mashify < Response
|
8
|
-
dependency 'hashie/mash'
|
9
|
-
|
10
9
|
define_parser do |body|
|
11
|
-
::
|
10
|
+
::Github::Mash.new body
|
12
11
|
end
|
13
12
|
|
14
13
|
def parse(body)
|
data/lib/github_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -228,6 +228,7 @@ files:
|
|
228
228
|
- lib/github_api/error/client_error.rb
|
229
229
|
- lib/github_api/error/service_error.rb
|
230
230
|
- lib/github_api/ext/faraday.rb
|
231
|
+
- lib/github_api/mash.rb
|
231
232
|
- lib/github_api/middleware.rb
|
232
233
|
- lib/github_api/mime_type.rb
|
233
234
|
- lib/github_api/normalizer.rb
|
@@ -248,6 +249,7 @@ files:
|
|
248
249
|
- lib/github_api/resource.rb
|
249
250
|
- lib/github_api/response.rb
|
250
251
|
- lib/github_api/response/atom_parser.rb
|
252
|
+
- lib/github_api/response/follow_redirects.rb
|
251
253
|
- lib/github_api/response/header.rb
|
252
254
|
- lib/github_api/response/jsonize.rb
|
253
255
|
- lib/github_api/response/mashify.rb
|