You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

126 lines
3.0 KiB

class Cask::Audit
attr_reader :cask, :errors, :warnings, :headers, :response_status
def initialize(cask, fetcher=Cask::Fetcher)
@cask = cask
@errors = []
@warnings = []
@headers = {}
@fetcher = fetcher
end
def run!
_check_required_fields
return if errors?
_get_data_from_request
return if errors?
_check_response_status
return if errors?
_check_content_length
end
def add_error(message)
@errors << message
end
def add_warning(message)
@warnings << message
end
def errors?
!@errors.empty?
end
def warnings?
!@warnings.empty?
end
def result
if errors?
"#{Tty.red}failed#{Tty.reset}"
elsif warnings?
"#{Tty.yellow}warning#{Tty.reset}"
else
"#{Tty.green}passed#{Tty.reset}"
end
end
def summary
summary = ["audit for #{cask}: #{result}"]
@errors.each do |error|
summary << " #{Tty.red}-#{Tty.reset} #{error}"
end
@warnings.each do |warning|
summary << " #{Tty.yellow}-#{Tty.reset} #{warning}"
end
summary.join("\n")
end
def _check_required_fields
add_error "url is required" unless cask.url
add_error "version is required" unless cask.version
add_error "homepage is required" unless cask.homepage
end
http_responses = [
'HTTP/1.0 200 OK',
'HTTP/1.1 200 OK'
]
OK_RESPONSES = {
'http' => http_responses,
'https' => http_responses,
'ftp' => [ 'OK' ]
}
def _check_response_status
ok = OK_RESPONSES[cask.url.scheme]
unless ok.include?(@response_status)
add_error "unexpected http response, expecting #{ok.map(&:inspect).join(' or ')}, got #{@response_status.inspect}"
end
end
def _check_content_length
remote_content_length = @headers['Content-Length']
if cask.content_length.nil?
add_warning "specify content_length so we can check against URL, currently: content_length '#{remote_content_length}'"
else
unless cask.content_length == remote_content_length
add_warning "unexpected content_length for #{cask}; specified #{cask.content_length.inspect}, but got #{remote_content_length.inspect}"
end
end
end
def _get_data_from_request
response = @fetcher.head(cask.url)
if response.empty?
add_error "timeout while requesting #{cask.url}"
return
end
response_lines = response.split("\n").map(&:chomp)
case cask.url.scheme
when 'http', 'https' then
@response_status = response_lines.grep(/^HTTP/).last
http_headers = response_lines[(response_lines.index(@response_status)+1)..-1]
http_headers.each { |line|
header_name, header_value = line.split(': ')
@headers[header_name] = header_value
}
when 'ftp' then
@response_status = 'OK'
response_lines.each { |line|
header_name, header_value = line.split(': ')
@headers[header_name] = header_value
}
else
add_error "unknown scheme for #{cask.url}"
end
end
end