mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-09-01 00:00:35 -04:00
added follow_insecure_redirects, which allows users to opt in on https-to-http redirects (shut down by default)
This commit is contained in:
parent
c521f226fc
commit
0be7efaab2
@ -1,6 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module HTTPX
|
||||
InsecureRedirectError = Class.new(Error)
|
||||
module Plugins
|
||||
module FollowRedirects
|
||||
module InstanceMethods
|
||||
@ -48,9 +49,24 @@ module HTTPX
|
||||
|
||||
private
|
||||
|
||||
def fetch_response(request)
|
||||
response = super
|
||||
if response &&
|
||||
REDIRECT_STATUS.include?(response.status) &&
|
||||
!@options.follow_insecure_redirects
|
||||
redirect_uri = __get_location_from_response(response)
|
||||
if response.uri.scheme == "https" &&
|
||||
redirect_uri.scheme == "http"
|
||||
error = InsecureRedirectError.new(redirect_uri.to_s)
|
||||
error.set_backtrace(caller)
|
||||
response = ErrorResponse.new(error, 0, @options)
|
||||
end
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
def __build_redirect_req(request, response, options)
|
||||
redirect_uri = URI(response.headers["location"])
|
||||
redirect_uri = response.uri.merge(redirect_uri) if redirect_uri.relative?
|
||||
redirect_uri = __get_location_from_response(response)
|
||||
|
||||
# TODO: integrate cookies in the next request
|
||||
# redirects are **ALWAYS** GET
|
||||
@ -58,12 +74,24 @@ module HTTPX
|
||||
body: request.body)
|
||||
__build_req(:get, redirect_uri, retry_options)
|
||||
end
|
||||
|
||||
def __get_location_from_response(response)
|
||||
location_uri = URI(response.headers["location"])
|
||||
location_uri = response.uri.merge(location_uri) if location_uri.relative?
|
||||
location_uri
|
||||
end
|
||||
end
|
||||
|
||||
module OptionsMethods
|
||||
def self.included(klass)
|
||||
super
|
||||
klass.def_option(:max_redirects)
|
||||
klass.def_option(:max_redirects) do |num|
|
||||
num = Integer(num)
|
||||
raise Error, ":max_redirects must be positive" unless num.positive?
|
||||
num
|
||||
end
|
||||
|
||||
klass.def_option(:follow_insecure_redirects)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -36,6 +36,20 @@ module Requests
|
||||
verify_status(response, 302)
|
||||
end
|
||||
|
||||
def test_plugin_follow_insecure_no_insecure_downgrade
|
||||
return unless origin.start_with?("https")
|
||||
|
||||
client = HTTPX.plugin(:follow_redirects).max_redirects(1)
|
||||
response = client.get(insecure_redirect_uri)
|
||||
assert response.is_a?(HTTPX::ErrorResponse), "request should not follow insecure URLs"
|
||||
|
||||
insecure_client = HTTPX.plugin(:follow_redirects)
|
||||
.max_redirects(1)
|
||||
.with(follow_insecure_redirects: true)
|
||||
insecure_response = insecure_client.get(insecure_redirect_uri)
|
||||
verify_status(insecure_response, 200)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_uri
|
||||
@ -46,6 +60,10 @@ module Requests
|
||||
build_uri("/redirect/#{n}")
|
||||
end
|
||||
|
||||
def insecure_redirect_uri
|
||||
build_uri("/redirect-to?url=http://www.google.com")
|
||||
end
|
||||
|
||||
def redirect_location
|
||||
build_uri("/get")
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user