danbooru::http: support automatically following redirects.
Replace http.rb's builtin redirect following option with our own redirect follower. This fixes an issue with http.rb losing cookies after following a redirect.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
require "danbooru/http/html_adapter"
|
||||
require "danbooru/http/xml_adapter"
|
||||
require "danbooru/http/redirector"
|
||||
require "danbooru/http/retriable"
|
||||
require "danbooru/http/session"
|
||||
|
||||
@@ -11,12 +12,24 @@ module Danbooru
|
||||
DEFAULT_TIMEOUT = 10
|
||||
MAX_REDIRECTS = 5
|
||||
|
||||
attr_writer :cache, :max_size, :http
|
||||
attr_accessor :cache, :max_size, :http
|
||||
|
||||
class << self
|
||||
delegate :get, :head, :put, :post, :delete, :cache, :follow, :max_size, :timeout, :auth, :basic_auth, :headers, :cookies, :use, :public_only, :download_media, to: :new
|
||||
end
|
||||
|
||||
def initialize
|
||||
@http ||=
|
||||
::Danbooru::Http::ApplicationClient.new
|
||||
.timeout(DEFAULT_TIMEOUT)
|
||||
.headers(Danbooru.config.http_headers)
|
||||
.headers("Accept-Encoding" => "gzip")
|
||||
.use(:auto_inflate)
|
||||
.use(:retriable)
|
||||
.use(redirector: { max_redirects: MAX_REDIRECTS })
|
||||
.use(:session)
|
||||
end
|
||||
|
||||
def get(url, **options)
|
||||
request(:get, url, **options)
|
||||
end
|
||||
@@ -147,16 +160,5 @@ module Danbooru
|
||||
def fake_response(status, body)
|
||||
::HTTP::Response.new(status: status, version: "1.1", body: ::HTTP::Response::Body.new(body))
|
||||
end
|
||||
|
||||
def http
|
||||
@http ||=
|
||||
::Danbooru::Http::ApplicationClient.new
|
||||
.follow(strict: false, max_hops: MAX_REDIRECTS)
|
||||
.use(:session)
|
||||
.timeout(DEFAULT_TIMEOUT)
|
||||
.use(:auto_inflate)
|
||||
.headers(Danbooru.config.http_headers)
|
||||
.headers("Accept-Encoding" => "gzip")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
40
app/logical/danbooru/http/redirector.rb
Normal file
40
app/logical/danbooru/http/redirector.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
# A HTTP::Feature that automatically follows HTTP redirects.
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections
|
||||
|
||||
module Danbooru
|
||||
class Http
|
||||
class Redirector < HTTP::Feature
|
||||
HTTP::Options.register_feature :redirector, self
|
||||
|
||||
attr_reader :max_redirects
|
||||
|
||||
def initialize(max_redirects: 5)
|
||||
@max_redirects = max_redirects
|
||||
end
|
||||
|
||||
def perform(request, &block)
|
||||
response = yield request
|
||||
|
||||
redirects = max_redirects
|
||||
while response.status.redirect?
|
||||
raise HTTP::Redirector::TooManyRedirectsError if redirects <= 0
|
||||
|
||||
response = yield build_redirect(request, response)
|
||||
redirects -= 1
|
||||
end
|
||||
|
||||
response
|
||||
end
|
||||
|
||||
def build_redirect(request, response)
|
||||
location = response.headers["Location"].to_s
|
||||
uri = HTTP::URI.parse(location)
|
||||
|
||||
verb = request.verb
|
||||
verb = :get if response.status == 303 && !request.verb.in?([:get, :head])
|
||||
|
||||
request.redirect(uri, verb)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,10 +5,11 @@ class NicoSeigaApiClient
|
||||
attr_reader :http
|
||||
|
||||
# XXX temp disable following redirects.
|
||||
def initialize(work_id:, type:, http: Danbooru::Http.follow(nil))
|
||||
def initialize(work_id:, type:)
|
||||
@work_id = work_id
|
||||
@work_type = type
|
||||
@http = http
|
||||
@http = Danbooru::Http.new
|
||||
@http.http.default_options.features.reject! { |name, _| name == :redirector }
|
||||
end
|
||||
|
||||
def image_ids
|
||||
|
||||
Reference in New Issue
Block a user