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