github_api 0.15.0 → 0.16.0
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.
- 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
|