9 # class for making http requests easier (mainly for plugins to use)
10 # this class can check the bot proxy configuration to determine if a proxy
11 # needs to be used, which includes support for per-url proxy configuration.
13 BotConfig.register BotConfigBooleanValue.new('http.use_proxy',
14 :default => false, :desc => "should a proxy be used for HTTP requests?")
15 BotConfig.register BotConfigStringValue.new('http.proxy_uri', :default => false,
16 :desc => "Proxy server to use for HTTP requests (URI, e.g http://proxy.host:port)")
17 BotConfig.register BotConfigStringValue.new('http.proxy_user',
19 :desc => "User for authenticating with the http proxy (if required)")
20 BotConfig.register BotConfigStringValue.new('http.proxy_pass',
22 :desc => "Password for authenticating with the http proxy (if required)")
23 BotConfig.register BotConfigArrayValue.new('http.proxy_include',
25 :desc => "List of regexps to check against a URI's hostname/ip to see if we should use the proxy to access this URI. All URIs are proxied by default if the proxy is set, so this is only required to re-include URIs that might have been excluded by the exclude list. e.g. exclude /.*\.foo\.com/, include bar\.foo\.com")
26 BotConfig.register BotConfigArrayValue.new('http.proxy_exclude',
28 :desc => "List of regexps to check against a URI's hostname/ip to see if we should use avoid the proxy to access this URI and access it directly")
29 BotConfig.register BotConfigIntegerValue.new('http.max_redir',
31 :desc => "Maximum number of redirections to be used when getting a document")
36 'User-Agent' => "rbot http util #{$version} (http://linuxbrit.co.uk/rbot/)",
40 # if http_proxy_include or http_proxy_exclude are set, then examine the
41 # uri to see if this is a proxied uri
42 # the in/excludes are a list of regexps, and each regexp is checked against
43 # the server name, and its IP addresses
44 def proxy_required(uri)
46 if @bot.config["http.proxy_exclude"].empty? && @bot.config["http.proxy_include"].empty?
52 list.concat Resolv.getaddresses(uri.host)
53 rescue StandardError => err
54 warning "couldn't resolve host uri.host"
57 unless @bot.config["http.proxy_exclude"].empty?
58 re = @bot.config["http.proxy_exclude"].collect{|r| Regexp.new(r)}
68 unless @bot.config["http.proxy_include"].empty?
69 re = @bot.config["http.proxy_include"].collect{|r| Regexp.new(r)}
79 debug "using proxy for uri #{uri}?: #{use_proxy}"
83 # uri:: Uri to create a proxy for
85 # return a net/http Proxy object, which is configured correctly for
86 # proxying based on the bot's proxy configuration.
87 # This will include per-url proxy configuration based on the bot config
88 # +http_proxy_include/exclude+ options.
96 if @bot.config["http.use_proxy"]
97 if (ENV['http_proxy'])
98 proxy = URI.parse ENV['http_proxy'] rescue nil
100 if (@bot.config["http.proxy_uri"])
101 proxy = URI.parse @bot.config["http.proxy_uri"] rescue nil
104 debug "proxy is set to #{proxy.host} port #{proxy.port}"
105 if proxy_required(uri)
106 proxy_host = proxy.host
107 proxy_port = proxy.port
108 proxy_user = @bot.config["http.proxy_user"]
109 proxy_pass = @bot.config["http.proxy_pass"]
114 h = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port, proxy_user, proxy_port)
115 h.use_ssl = true if uri.scheme == "https"
119 # uri:: uri to query (Uri object)
120 # readtimeout:: timeout for reading the response
121 # opentimeout:: timeout for opening the connection
123 # simple get request, returns response body if the status code is 200 and
124 # the request doesn't timeout.
125 def get(uri, readtimeout=10, opentimeout=5, redirs=0)
126 proxy = get_proxy(uri)
127 proxy.open_timeout = opentimeout
128 proxy.read_timeout = readtimeout
131 proxy.start() {|http|
132 resp = http.get(uri.request_uri(), @headers)
137 debug "Redirecting #{uri} to #{resp['location']}"
138 if redirs < @bot.config["http.max_redir"]
139 return get( URI.parse(resp['location']), readtimeout, opentimeout, redirs+1 )
141 warning "Max redirection reached, not going to #{resp['location']}"
145 debug "HttpUtil.get return code #{resp.code} #{resp.body}"
149 rescue StandardError, Timeout::Error => e
150 error "HttpUtil.get exception: #{e.inspect}, while trying to get #{uri}"