]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - lib/rbot/httputil.rb
Sun Jul 31 02:20:08 BST 2005 Tom Gilbert <tom@linuxbrit.co.uk>
[user/henk/code/ruby/rbot.git] / lib / rbot / httputil.rb
1 module Irc
2 module Utils
3
4 require 'resolv'
5 require 'net/http'
6 Net::HTTP.version_1_2
7   
8 # class for making http requests easier (mainly for plugins to use)
9 # this class can check the bot proxy configuration to determine if a proxy
10 # needs to be used, which includes support for per-url proxy configuration.
11 class HttpUtil
12     BotConfig.register BotConfigBooleanValue.new('http.use_proxy',
13       :default => false, :desc => "should a proxy be used for HTTP requests?")
14     BotConfig.register BotConfigStringValue.new('http.proxy_uri', :default => false,
15       :desc => "Proxy server to use for HTTP requests (URI, e.g http://proxy.host:port)")
16     BotConfig.register BotConfigStringValue.new('http.proxy_user',
17       :default => nil,
18       :desc => "User for authenticating with the http proxy (if required)")
19     BotConfig.register BotConfigStringValue.new('http.proxy_pass',
20       :default => nil,
21       :desc => "Password for authenticating with the http proxy (if required)")
22     BotConfig.register BotConfigArrayValue.new('http.proxy_include',
23       :default => [],
24       :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")
25     BotConfig.register BotConfigArrayValue.new('http.proxy_exclude',
26       :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")
27
28   def initialize(bot)
29     @bot = bot
30     @headers = {
31       'User-Agent' => "rbot http util #{$version} (http://linuxbrit.co.uk/rbot/)",
32     }
33   end
34
35   # if http_proxy_include or http_proxy_exclude are set, then examine the
36   # uri to see if this is a proxied uri
37   # the in/excludes are a list of regexps, and each regexp is checked against
38   # the server name, and its IP addresses
39   def proxy_required(uri)
40     use_proxy = true
41     if @bot.config["http.proxy_exclude"].empty? && @bot.config["http.proxy_include"].empty?
42       return use_proxy
43     end
44
45     list = [uri.host]
46     begin
47       list.push Resolv.getaddresses(uri.host)
48     rescue StandardError => err
49       puts "warning: couldn't resolve host uri.host"
50     end
51
52     unless @bot.config["http.proxy_exclude"].empty?
53       re = @bot.config["http.proxy_exclude"].collect{|r| Regexp.new(r)}
54       re.each do |r|
55         list.each do |item|
56           if r.match(item)
57             use_proxy = false
58             break
59           end
60         end
61       end
62     end
63     unless @bot.config["http.proxy_include"].empty?
64       re = @bot.config["http.proxy_include"].collect{|r| Regexp.new(r)}
65       re.each do |r|
66         list.each do |item|
67           if r.match(item)
68             use_proxy = true
69             break
70           end
71         end
72       end
73     end
74     debug "using proxy for uri #{uri}?: #{use_proxy}"
75     return use_proxy
76   end
77
78   # uri:: Uri to create a proxy for
79   #
80   # return a net/http Proxy object, which is configured correctly for
81   # proxying based on the bot's proxy configuration. 
82   # This will include per-url proxy configuration based on the bot config
83   # +http_proxy_include/exclude+ options.
84   def get_proxy(uri)
85     proxy = nil
86     proxy_host = nil
87     proxy_port = nil
88     proxy_user = nil
89     proxy_pass = nil
90
91     if @bot.config["http.use_proxy"]
92       if (ENV['http_proxy'])
93         proxy = URI.parse ENV['http_proxy']
94       end
95       if (@bot.config["http.proxy_uri"])
96         proxy = URI.parse ENV['http_proxy_uri']
97       end
98       if proxy
99         debug "proxy is set to #{proxy.uri}"
100         if proxy_required(uri)
101           proxy_host = proxy.host
102           proxy_port = proxy.port
103           proxy_user = @bot.config["http.proxy_user"]
104           proxy_pass = @bot.config["http.proxy_pass"]
105         end
106       end
107     end
108     
109     return Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port, proxy_user, proxy_port)
110   end
111
112   # uri::         uri to query (Uri object)
113   # readtimeout:: timeout for reading the response
114   # opentimeout:: timeout for opening the connection
115   #
116   # simple get request, returns response body if the status code is 200 and
117   # the request doesn't timeout.
118   def get(uri, readtimeout=10, opentimeout=5)
119     proxy = get_proxy(uri)
120     proxy.open_timeout = opentimeout
121     proxy.read_timeout = readtimeout
122    
123     begin
124       proxy.start() {|http|
125         resp = http.get(uri.request_uri(), @headers)
126         if resp.code == "200"
127           return resp.body
128         else
129           puts "HttpUtil.get return code #{resp.code} #{resp.body}"
130         end
131         return nil
132       }
133     rescue StandardError, Timeout::Error => e
134       $stderr.puts "HttpUtil.get exception: #{e}, while trying to get #{uri}"
135     end
136     return nil
137   end
138 end
139 end
140 end