2011-07-19 20:11:35 +00:00
|
|
|
require "socket"
|
|
|
|
require "proxifier"
|
|
|
|
|
|
|
|
module Proxifier
|
|
|
|
class Proxy
|
|
|
|
def open(host, port, local_host = nil, local_port = nil)
|
|
|
|
return TCPSocket.new(host, port, local_host, local_port, :proxy => nil) unless proxify?(host)
|
|
|
|
|
|
|
|
socket = TCPSocket.new(proxy.host, proxy.port, local_host, local_port, :proxy => nil)
|
|
|
|
|
|
|
|
begin
|
|
|
|
proxify(socket, host, port)
|
|
|
|
rescue
|
|
|
|
socket.close
|
|
|
|
raise
|
|
|
|
end
|
|
|
|
|
|
|
|
socket
|
|
|
|
end
|
|
|
|
end
|
2011-06-09 15:28:05 +00:00
|
|
|
|
|
|
|
module Proxify
|
|
|
|
def self.included(klass)
|
|
|
|
klass.class_eval do
|
|
|
|
alias_method :initialize_without_proxy, :initialize
|
|
|
|
alias_method :initialize, :initialize_with_proxy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize_with_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
|
|
|
|
if options_or_local_host.is_a?(Hash)
|
|
|
|
local_host = nil
|
|
|
|
options = options_or_local_host
|
|
|
|
else
|
|
|
|
local_host = options_or_local_host
|
|
|
|
options = options_if_local_host
|
|
|
|
end
|
|
|
|
|
2011-07-19 20:11:35 +00:00
|
|
|
if options[:proxy] && (proxy = Proxifier::Proxy(options.delete(:proxy), options)) && proxy.proxify?(host)
|
2011-06-09 15:28:05 +00:00
|
|
|
initialize_without_proxy(proxy.host, proxy.port, local_host, local_port)
|
|
|
|
begin
|
|
|
|
proxy.proxify(self, host, port)
|
2011-07-19 20:11:35 +00:00
|
|
|
rescue
|
2011-06-09 15:28:05 +00:00
|
|
|
close
|
|
|
|
raise
|
|
|
|
end
|
|
|
|
else
|
|
|
|
initialize_without_proxy(host, port, local_host, local_port)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module EnvironmentProxify
|
|
|
|
def self.included(klass)
|
|
|
|
klass.class_eval do
|
|
|
|
extend ClassMethods
|
|
|
|
alias_method :initialize_without_environment_proxy, :initialize
|
|
|
|
alias_method :initialize, :initialize_with_environment_proxy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize_with_environment_proxy(host, port, options_or_local_host = {}, local_port = nil, options_if_local_host = {})
|
|
|
|
if options_or_local_host.is_a?(Hash)
|
|
|
|
local_host = nil
|
|
|
|
options = options_or_local_host
|
|
|
|
else
|
|
|
|
local_host = options_or_local_host
|
|
|
|
options = options_if_local_host
|
|
|
|
end
|
|
|
|
|
|
|
|
options = { :proxy => environment_proxy, :no_proxy => environment_no_proxy }.merge(options)
|
|
|
|
initialize_without_environment_proxy(host, port, local_host, local_port, options)
|
|
|
|
end
|
|
|
|
|
|
|
|
def environment_proxy
|
|
|
|
self.class.environment_proxy
|
|
|
|
end
|
|
|
|
|
|
|
|
def environment_no_proxy
|
|
|
|
self.class.environment_no_proxy
|
|
|
|
end
|
|
|
|
|
|
|
|
module ClassMethods
|
|
|
|
def environment_proxy
|
2011-07-19 20:11:35 +00:00
|
|
|
ENV["proxy"] || ENV["PROXY"] || specific_environment_proxy
|
2011-06-09 15:28:05 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def environment_no_proxy
|
2011-07-19 20:11:35 +00:00
|
|
|
ENV["no_proxy"] || ENV["NO_PROXY"]
|
2011-06-09 15:28:05 +00:00
|
|
|
end
|
2011-07-19 20:11:35 +00:00
|
|
|
|
|
|
|
private
|
|
|
|
def specific_environment_proxy
|
|
|
|
%w(socks socks5 socks4a socks4 http).each do |type|
|
|
|
|
if proxy = ENV["#{type}_proxy"] || ENV["#{type.upcase}_PROXY"]
|
|
|
|
scheme = "#{type}://"
|
|
|
|
|
|
|
|
proxy = proxy.dup
|
|
|
|
proxy.insert(0, scheme) unless proxy.index(scheme) == 0
|
|
|
|
return proxy
|
|
|
|
end
|
|
|
|
end
|
2011-08-23 03:02:42 +00:00
|
|
|
|
|
|
|
nil
|
2011-07-19 20:11:35 +00:00
|
|
|
end
|
2011-06-09 15:28:05 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2011-07-19 20:11:35 +00:00
|
|
|
|
|
|
|
class TCPSocket
|
|
|
|
include Proxifier::Proxify
|
|
|
|
include Proxifier::EnvironmentProxify
|
|
|
|
end
|