http: automatically follow redirects.
* Automatically follow redirects (up to 5, return a synthetic 598 error after that). * Add `put` and `timeout` methods. * Add tests.
This commit is contained in:
@@ -1,17 +1,22 @@
|
|||||||
module Danbooru
|
module Danbooru
|
||||||
class Http
|
class Http
|
||||||
DEFAULT_TIMEOUT = 3
|
DEFAULT_TIMEOUT = 3
|
||||||
|
MAX_REDIRECTS = 5
|
||||||
|
|
||||||
attr_writer :cache, :http
|
attr_writer :cache, :http
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
delegate :get, :post, :delete, :cache, :auth, :basic_auth, :headers, to: :new
|
delegate :get, :put, :post, :delete, :cache, :timeout, :auth, :basic_auth, :headers, to: :new
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(url, **options)
|
def get(url, **options)
|
||||||
request(:get, url, **options)
|
request(:get, url, **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def put(url, **options)
|
||||||
|
request(:get, url, **options)
|
||||||
|
end
|
||||||
|
|
||||||
def post(url, **options)
|
def post(url, **options)
|
||||||
request(:post, url, **options)
|
request(:post, url, **options)
|
||||||
end
|
end
|
||||||
@@ -24,6 +29,10 @@ module Danbooru
|
|||||||
dup.tap { |o| o.cache = expiry.to_i }
|
dup.tap { |o| o.cache = expiry.to_i }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def timeout(*args)
|
||||||
|
dup.tap { |o| o.http = o.http.timeout(*args) }
|
||||||
|
end
|
||||||
|
|
||||||
def auth(*args)
|
def auth(*args)
|
||||||
dup.tap { |o| o.http = o.http.auth(*args) }
|
dup.tap { |o| o.http = o.http.auth(*args) }
|
||||||
end
|
end
|
||||||
@@ -44,9 +53,11 @@ module Danbooru
|
|||||||
else
|
else
|
||||||
raw_request(method, url, **options)
|
raw_request(method, url, **options)
|
||||||
end
|
end
|
||||||
|
rescue HTTP::Redirector::TooManyRedirectsError
|
||||||
|
::HTTP::Response.new(status: 598, body: "", version: "1.1")
|
||||||
rescue HTTP::TimeoutError
|
rescue HTTP::TimeoutError
|
||||||
# return a synthetic http error on connection timeouts
|
# return a synthetic http error on connection timeouts
|
||||||
::HTTP::Response.new(status: 522, body: "", version: "1.1")
|
::HTTP::Response.new(status: 599, body: "", version: "1.1")
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_request(method, url, **options)
|
def cached_request(method, url, **options)
|
||||||
@@ -65,7 +76,12 @@ module Danbooru
|
|||||||
end
|
end
|
||||||
|
|
||||||
def http
|
def http
|
||||||
@http ||= ::HTTP.timeout(DEFAULT_TIMEOUT).use(:auto_inflate).headers(Danbooru.config.http_headers).headers("Accept-Encoding" => "gzip")
|
@http ||= ::HTTP.
|
||||||
|
follow(max_hops: MAX_REDIRECTS).
|
||||||
|
timeout(DEFAULT_TIMEOUT).
|
||||||
|
use(:auto_inflate).
|
||||||
|
headers(Danbooru.config.http_headers).
|
||||||
|
headers("Accept-Encoding" => "gzip")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
49
test/unit/danbooru_http_test.rb
Normal file
49
test/unit/danbooru_http_test.rb
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class DanbooruHttpTest < ActiveSupport::TestCase
|
||||||
|
context "Danbooru::Http" do
|
||||||
|
context "#get method" do
|
||||||
|
should "work for all basic methods" do
|
||||||
|
%i[get put post delete].each do |method|
|
||||||
|
response = Danbooru::Http.send(method, "https://httpbin.org/status/200")
|
||||||
|
assert_equal(200, response.status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
should "follow redirects" do
|
||||||
|
response = Danbooru::Http.get("https://httpbin.org/absolute-redirect/3")
|
||||||
|
assert_equal(200, response.status)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "fail if redirected too many times" do
|
||||||
|
response = Danbooru::Http.get("https://httpbin.org/absolute-redirect/10")
|
||||||
|
assert_equal(598, response.status)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "fail if the request takes too long to connect" do
|
||||||
|
response = Danbooru::Http.timeout(1).get("https://httpbin.org/delay/5")
|
||||||
|
assert_equal(599, response.status)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "fail if the request takes too long to download" do
|
||||||
|
response = Danbooru::Http.timeout(1).get("https://httpbin.org/drip?duration=5&numbytes=5")
|
||||||
|
assert_equal(599, response.status)
|
||||||
|
end
|
||||||
|
|
||||||
|
should "automatically decompress gzipped responses" do
|
||||||
|
response = Danbooru::Http.get("https://httpbin.org/gzip")
|
||||||
|
assert_equal(200, response.status)
|
||||||
|
assert_equal(true, response.parse["gzipped"])
|
||||||
|
end
|
||||||
|
|
||||||
|
should "cache requests" do
|
||||||
|
response1 = Danbooru::Http.cache(1.minute).get("https://httpbin.org/uuid")
|
||||||
|
assert_equal(200, response1.status)
|
||||||
|
|
||||||
|
response2 = Danbooru::Http.cache(1.minute).get("https://httpbin.org/uuid")
|
||||||
|
assert_equal(200, response2.status)
|
||||||
|
assert_equal(response2.body, response1.body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user