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