require 'openssl' require 'socket' require 'timeout' require 'uri' # # The HTTP-protocol test. # # This object is instantiated if the parser sees a line such as: # ### ### http://foo.vm.bytemark.co.uk/ must run http with content 'foo' otherwise 'ftp fail'. ### # # module Custodian module ProtocolTest class HTTPTest < TestFactory # # The line from which we were constructed. # attr_reader :line # # The URL to poll # attr_reader :url # # The expected status + content # attr_reader :expected_status, :expected_content # # The actual status & content # attr_reader :status, :content # # Constructor # def initialize( line ) # # Save the line # @line = line # # Save the URL # @url = line.split( /\s+/)[0] if ( @url !~ /^https?:/ ) raise ArgumentError, "The target wasn't an URL" end # # Is this test inverted? # if ( line =~ /must\s+not\s+run\s+/ ) @inverted = true else @inverted = false end # # Expected status # if ( line =~ /with status ([0-9]+)/ ) @expected_status = $1.dup else @expected_status = "200" end # # The content we expect to find # if ( line =~ /with content '([^']+)'/ ) @expected_content = $1.dup else @expected_content = nil end @status = nil @content = nil end # # Allow this test to be serialized. # def to_s @line end # # Run the test. # def run_test # Reset state, in case we've previously run. @error = nil # Parse the URL uri = URI.parse(@url) # # Ensure we have a path to request - to cover people who write: # # http://example.com must run http .. # if ( uri.path.empty? ) uri.path = "/" end # # Connect a socket to the host. # socket = connect( uri.host, uri.port, uri.scheme == "https" ) path = uri.path if ( uri.query ) path = "#{url.path}?#{url.query}" end req =< err @error = err ensure socket.close if socket.is_a?(Socket) and not socket.closed? end end # # If the test fails then report the error. # def error @error end register_test_type "http" register_test_type "https" end end end