C0 code coverage information

Generated on Fri Jul 11 15:55:29 -0700 2008 with rcov 0.7.0


Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
Name Total lines Lines of code Total coverage Code coverage
lib/openid/fetchers.rb 239 188
82.0% 
77.1% 
  1 require 'net/http'
  2 require 'openid'
  3 require 'openid/util'
  4 
  5 begin
  6   require 'net/https'
  7 rescue LoadError
  8   OpenID::Util.log('WARNING: no SSL support found.  Will not be able ' +
  9                    'to fetch HTTPS URLs!')
 10   require 'net/http'
 11 end
 12 
 13 MAX_RESPONSE_KB = 1024
 14 
 15 module Net
 16   class HTTP
 17     def post_connection_check(hostname)
 18       check_common_name = true
 19       cert = @socket.io.peer_cert
 20       cert.extensions.each { |ext|
 21         next if ext.oid != "subjectAltName"
 22         ext.value.split(/,\s+/).each{ |general_name|
 23           if /\ADNS:(.*)/ =~ general_name
 24             check_common_name = false
 25             reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+")
 26             return true if /\A#{reg}\z/i =~ hostname
 27           elsif /\AIP Address:(.*)/ =~ general_name
 28             check_common_name = false
 29             return true if $1 == hostname
 30           end
 31         }
 32       }
 33       if check_common_name
 34         cert.subject.to_a.each{ |oid, value|
 35           if oid == "CN"
 36             reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+")
 37             return true if /\A#{reg}\z/i =~ hostname
 38           end
 39         }
 40       end
 41       raise OpenSSL::SSL::SSLError, "hostname does not match"
 42     end
 43   end
 44 end
 45 
 46 module OpenID
 47   # Our HTTPResponse class extends Net::HTTPResponse with an additional
 48   # method, final_url.
 49   class HTTPResponse
 50     attr_accessor :final_url
 51 
 52     attr_accessor :_response
 53 
 54     def self._from_net_response(response, final_url, headers=nil)
 55       me = self.new
 56       me._response = response
 57       me.final_url = final_url
 58       return me
 59     end
 60 
 61     def method_missing(method, *args)
 62       @_response.send(method, *args)
 63     end
 64 
 65     def body=(s)
 66       @_response.instance_variable_set('@body', s)
 67       # XXX Hack to work around ruby's HTTP library behavior.  @body
 68       # is only returned if it has been read from the response
 69       # object's socket, but since we're not using a socket in this
 70       # case, we need to set the @read flag to true to avoid a bug in
 71       # Net::HTTPResponse.stream_check when @socket is nil.
 72       @_response.instance_variable_set('@read', true)
 73     end
 74   end
 75 
 76   class FetchingError < OpenIDError
 77   end
 78 
 79   class HTTPRedirectLimitReached < FetchingError
 80   end
 81 
 82   class SSLFetchingError < FetchingError
 83   end
 84 
 85   @fetcher = nil
 86 
 87   def self.fetch(url, body=nil, headers=nil,
 88                  redirect_limit=StandardFetcher::REDIRECT_LIMIT)
 89     return fetcher.fetch(url, body, headers, redirect_limit)
 90   end
 91 
 92   def self.fetcher
 93     if @fetcher.nil?
 94       @fetcher = StandardFetcher.new
 95     end
 96 
 97     return @fetcher
 98   end
 99 
100   def self.fetcher=(fetcher)
101     @fetcher = fetcher
102   end
103 
104   # Set the default fetcher to use the HTTP proxy defined in the environment
105   # variable 'http_proxy'.
106   def self.fetcher_use_env_http_proxy
107     proxy_string = ENV['http_proxy']
108     return unless proxy_string
109 
110     proxy_uri = URI.parse(proxy_string)
111     @fetcher = StandardFetcher.new(proxy_uri.host, proxy_uri.port,
112                                    proxy_uri.user, proxy_uri.password)
113   end
114   
115   class StandardFetcher
116 
117     USER_AGENT = "ruby-openid/#{OpenID::VERSION} (#{RUBY_PLATFORM})"
118 
119     REDIRECT_LIMIT = 5
120     TIMEOUT = 60
121 
122     attr_accessor :ca_file
123     attr_accessor :timeout
124 
125     # I can fetch through a HTTP proxy; arguments are as for Net::HTTP::Proxy.
126     def initialize(proxy_addr=nil, proxy_port=nil,
127                    proxy_user=nil, proxy_pass=nil)
128       @ca_file = nil
129       @proxy = Net::HTTP::Proxy(proxy_addr, proxy_port, proxy_user, proxy_pass)
130       @timeout = TIMEOUT
131     end
132 
133     def supports_ssl?(conn)
134       return conn.respond_to?(:use_ssl=)
135     end
136 
137     def make_http(uri)
138       http = @proxy.new(uri.host, uri.port)
139       http.read_timeout = @timeout
140       http.open_timeout = @timeout
141       return http
142     end
143 
144     def set_verified(conn, verify)
145       if verify
146         conn.verify_mode = OpenSSL::SSL::VERIFY_PEER
147       else
148         conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
149       end
150     end
151 
152     def make_connection(uri)
153       conn = make_http(uri)
154 
155       if !conn.is_a?(Net::HTTP)
156         raise RuntimeError, sprintf("Expected Net::HTTP object from make_http; got %s",
157                                     conn.class)
158       end
159 
160       if uri.scheme == 'https'
161         if supports_ssl?(conn)
162 
163           conn.use_ssl = true
164 
165           if @ca_file
166             set_verified(conn, true)
167             conn.ca_file = @ca_file
168           else
169             Util.log("WARNING: making https request to #{uri} without verifying " +
170                      "server certificate; no CA path was specified.")
171             set_verified(conn, false)
172           end
173         else
174           raise RuntimeError, "SSL support not found; cannot fetch #{uri}"
175         end
176       end
177 
178       return conn
179     end
180 
181     def fetch(url, body=nil, headers=nil, redirect_limit=REDIRECT_LIMIT)
182       unparsed_url = url.dup
183       url = URI::parse(url)
184       if url.nil?
185         raise FetchingError, "Invalid URL: #{unparsed_url}"
186       end
187 
188       headers ||= {}
189       headers['User-agent'] ||= USER_AGENT
190       headers['Range'] ||= "0-#{MAX_RESPONSE_KB*1024}"
191 
192       begin
193         conn = make_connection(url)
194         response = nil
195 
196         response = conn.start {
197           # Check the certificate against the URL's hostname
198           if supports_ssl?(conn) and conn.use_ssl?
199             conn.post_connection_check(url.host)
200           end
201 
202           if body.nil?
203             conn.request_get(url.request_uri, headers)
204           else
205             headers["Content-type"] ||= "application/x-www-form-urlencoded"
206             conn.request_post(url.request_uri, body, headers)
207           end
208         }
209       rescue RuntimeError => why
210         raise why
211       rescue OpenSSL::SSL::SSLError => why
212         raise SSLFetchingError, "Error connecting to SSL URL #{url}: #{why}"
213       rescue FetchingError => why
214         raise why
215       rescue Exception => why
216         # Things we've caught here include a Timeout::Error, which descends
217         # from SignalException.
218         raise FetchingError, "Error fetching #{url}: #{why}"
219       end
220 
221       case response
222       when Net::HTTPRedirection
223         if redirect_limit <= 0
224           raise HTTPRedirectLimitReached.new(
225             "Too many redirects, not fetching #{response['location']}")
226         end
227         begin
228           return fetch(response['location'], body, headers, redirect_limit - 1)
229         rescue HTTPRedirectLimitReached => e
230           raise e
231         rescue FetchingError => why
232           raise FetchingError, "Error encountered in redirect from #{url}: #{why}"
233         end
234       else
235         return HTTPResponse._from_net_response(response, unparsed_url)
236       end
237     end
238   end
239 end

Generated using the rcov code coverage analysis tool for Ruby version 0.7.0.

Valid XHTML 1.0! Valid CSS!