Module: Kettle::Dev::PreReleaseCLI::HTTP

Defined in:
lib/kettle/dev/pre_release_cli.rb

Overview

Simple HTTP helpers for link validation

Class Method Summary collapse

Class Method Details

.head_ok?(url_str, limit: 5, timeout: 10) ⇒ Boolean

Perform HTTP HEAD against the given url.
Falls back to GET when HEAD is not allowed.

Parameters:

  • url_str (String)
  • limit (Integer) (defaults to: 5)

    max redirects

  • timeout (Integer) (defaults to: 10)

    per-request timeout seconds

Returns:

  • (Boolean)

    true when successful (2xx) after following redirects

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
# File 'lib/kettle/dev/pre_release_cli.rb', line 49

def head_ok?(url_str, limit: 5, timeout: 10)
  uri = parse_http_uri(url_str)
  raise ArgumentError, "unsupported URI scheme: #{uri.scheme.inspect}" unless %w[http https].include?(uri.scheme)

  request = Net::HTTP::Head.new(uri)
  perform(uri, request, limit: limit, timeout: timeout)
end

.parse_http_uri(url_str) ⇒ URI

Unicode-friendly HTTP URI parser with Addressable fallback.

Parameters:

  • url_str (String)

Returns:

  • (URI)


29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/kettle/dev/pre_release_cli.rb', line 29

def parse_http_uri(url_str)
  if defined?(Addressable::URI)
    addr = Addressable::URI.parse(url_str)
    # Build a standard URI with properly encoded host/path/query for Net::HTTP
    # Addressable handles unicode and punycode automatically via normalization
    addr = addr.normalize
    # Net::HTTP expects a ::URI; convert via to_s then URI.parse
    URI.parse(addr.to_s)
  else
    # Fallback: try URI.parse directly; users can add addressable to unlock unicode support
    URI.parse(url_str)
  end
end

.perform(uri, request, limit:, timeout:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/kettle/dev/pre_release_cli.rb', line 58

def perform(uri, request, limit:, timeout:)
  raise ArgumentError, "too many redirects" if limit <= 0

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"
  http.read_timeout = timeout
  http.open_timeout = timeout
  http.ssl_timeout = timeout if http.respond_to?(:ssl_timeout=)
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER if http.use_ssl?

  response = http.start { |h| h.request(request) }

  case response
  when Net::HTTPRedirection
    location = response["location"]
    return false unless location

    new_uri = parse_http_uri(location)
    new_uri = uri + location if new_uri.relative?
    head_ok?(new_uri.to_s, limit: limit - 1, timeout: timeout)
  when Net::HTTPSuccess
    true
  else
    if response.is_a?(Net::HTTPMethodNotAllowed)
      get_req = Net::HTTP::Get.new(uri)
      get_resp = http.start { |h| h.request(get_req) }
      return get_resp.is_a?(Net::HTTPSuccess)
    end
    false
  end
rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError, OpenSSL::SSL::SSLError => e
  warn("[kettle-pre-release] HTTP error for #{uri}: #{e.class}: #{e.message}")
  false
end