|
|
|
|
@ -65,6 +65,7 @@ class Request
|
|
|
|
|
# and 5s timeout on the TLS handshake, meaning the worst case should take
|
|
|
|
|
# about 15s in total
|
|
|
|
|
TIMEOUT = { connect_timeout: 5, read_timeout: 10, write_timeout: 10, read_deadline: 30 }.freeze
|
|
|
|
|
SAFE_PRESERVED_CHARS = '+,'
|
|
|
|
|
|
|
|
|
|
include RoutingHelper
|
|
|
|
|
|
|
|
|
|
@ -72,7 +73,7 @@ class Request
|
|
|
|
|
raise ArgumentError if url.blank?
|
|
|
|
|
|
|
|
|
|
@verb = verb
|
|
|
|
|
@url = Addressable::URI.parse(url).normalize
|
|
|
|
|
@url = normalize_preserving_url_encodings(url, SAFE_PRESERVED_CHARS)
|
|
|
|
|
@http_client = options.delete(:http_client)
|
|
|
|
|
@allow_local = options.delete(:allow_local)
|
|
|
|
|
@options = {
|
|
|
|
|
@ -148,6 +149,34 @@ class Request
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
# Using code from https://github.com/sporkmonger/addressable/blob/3450895887d0a1770660d8831d1b6fcfed9bd9d6/lib/addressable/uri.rb#L1609-L1635
|
|
|
|
|
# to preserve some URL Encodings while normalizing
|
|
|
|
|
def normalize_preserving_url_encodings(url, preserved_chars = SAFE_PRESERVED_CHARS, *flags)
|
|
|
|
|
original_uri = Addressable::URI.parse(url)
|
|
|
|
|
normalized_uri = original_uri.normalize
|
|
|
|
|
|
|
|
|
|
if original_uri.query
|
|
|
|
|
modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
|
|
|
|
|
modified_query_class.sub!('\\&', '').sub!('\\;', '')
|
|
|
|
|
|
|
|
|
|
pairs = original_uri.query.split('&', -1)
|
|
|
|
|
pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted)
|
|
|
|
|
pairs.sort! if flags.include?(:sorted)
|
|
|
|
|
|
|
|
|
|
normalized_query = pairs.map do |pair|
|
|
|
|
|
Addressable::URI.normalize_component(
|
|
|
|
|
pair,
|
|
|
|
|
modified_query_class,
|
|
|
|
|
preserved_chars
|
|
|
|
|
)
|
|
|
|
|
end.join('&')
|
|
|
|
|
|
|
|
|
|
normalized_uri.query = normalized_query == '' ? nil : normalized_query
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
normalized_uri
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def set_common_headers!
|
|
|
|
|
@headers['User-Agent'] = Mastodon::Version.user_agent
|
|
|
|
|
@headers['Host'] = @url.host
|
|
|
|
|
|