@ -30,7 +30,8 @@ class Request
@verb = verb
@verb = verb
@url = Addressable :: URI . parse ( url ) . normalize
@url = Addressable :: URI . parse ( url ) . normalize
@http_client = options . delete ( :http_client )
@http_client = options . delete ( :http_client )
@options = options . merge ( use_proxy? ? Rails . configuration . x . http_client_proxy : { socket_class : Socket } )
@options = options . merge ( socket_class : use_proxy? ? ProxySocket : Socket )
@options = @options . merge ( Rails . configuration . x . http_client_proxy ) if use_proxy?
@headers = { }
@headers = { }
raise Mastodon :: HostValidationError , 'Instance does not support hidden service connections' if block_hidden_service?
raise Mastodon :: HostValidationError , 'Instance does not support hidden service connections' if block_hidden_service?
@ -177,19 +178,22 @@ class Request
class Socket < TCPSocket
class Socket < TCPSocket
class << self
class << self
def open ( host , * args )
def open ( host , * args )
return super ( host , * args ) if thru_hidden_service? ( host )
outer_e = nil
outer_e = nil
port = args . first
port = args . first
addresses = [ ]
begin
addresses = [ IPAddr . new ( host ) ]
rescue IPAddr :: InvalidAddressError
Resolv :: DNS . open do | dns |
Resolv :: DNS . open do | dns |
dns . timeouts = 5
dns . timeouts = 5
addresses = dns . getaddresses ( host ) . take ( 2 )
addresses = dns . getaddresses ( host ) . take ( 2 )
end
end
addresses . each do | address |
addresses . each do | address |
begin
begin
raise Mastodon :: HostValidationError if PrivateAddressCheck . private_address? ( IPAddr . new ( address . to_s ) )
check_private_address ( address )
sock = :: Socket . new ( address . is_a? ( Resolv :: IPv6 ) ? :: Socket :: AF_INET6 : :: Socket :: AF_INET , :: Socket :: SOCK_STREAM , 0 )
sock = :: Socket . new ( address . is_a? ( Resolv :: IPv6 ) ? :: Socket :: AF_INET6 : :: Socket :: AF_INET , :: Socket :: SOCK_STREAM , 0 )
sockaddr = :: Socket . pack_sockaddr_in ( port , address . to_s )
sockaddr = :: Socket . pack_sockaddr_in ( port , address . to_s )
@ -219,7 +223,6 @@ class Request
outer_e = e
outer_e = e
end
end
end
end
end
if outer_e
if outer_e
raise outer_e
raise outer_e
@ -230,11 +233,21 @@ class Request
alias new open
alias new open
def thru_hidden_service? ( host )
def check_private_address ( address )
Rails . configuration . x . access_to_hidden_service && / \ .(onion|i2p)$ / . match ( host )
raise Mastodon :: HostValidationError if PrivateAddressCheck . private_address? ( IPAddr . new ( address . to_s ) )
end
end
end
class ProxySocket < Socket
class << self
def check_private_address ( _address )
# Accept connections to private addresses as HTTP proxies will usually
# be on local addresses
nil
end
end
end
end
end
end
private_constant :ClientLimit , :Socket
private_constant :ClientLimit , :Socket , :ProxySocket
end
end