Class: Hooks::Utils::Normalize

Inherits:
Object
  • Object
show all
Defined in:
lib/hooks/utils/normalize.rb

Overview

Utility class for normalizing HTTP headers

Provides a robust method to consistently format HTTP headers across the application, handling various edge cases and formats.

Class Method Summary collapse

Class Method Details

.header(header) ⇒ String?

Normalize a single HTTP header name

Examples:

Single header normalization

Normalize.header("  Content-Type  ")  # => "content-type"
Normalize.header("X-GitHub-Event")    # => "x-github-event"
Normalize.header("")                  # => ""
Normalize.header(nil)                 # => nil

Parameters:

  • header (String)

    Header name to normalize

Returns:

  • (String, nil)

    Normalized header name (downcased and trimmed), or nil if input is nil

Raises:

  • (ArgumentError)

    If input is not a String or nil



106
107
108
109
110
111
112
113
# File 'lib/hooks/utils/normalize.rb', line 106

def self.header(header)
  return nil if header.nil?
  if header.is_a?(String)
    header.downcase.strip
  else
    raise ArgumentError, "Expected a String for header normalization"
  end
end

.headers(headers) ⇒ Hash

Normalize a hash of HTTP headers

Examples:

Hash of headers normalization

headers = { "Content-Type" => "  application/json  ", "X-GitHub-Event" => "push" }
normalized = Normalize.headers(headers)
# => { "content-type" => "application/json", "x-github-event" => "push" }

Handle various input types

Normalize.headers(nil)                    # => nil
Normalize.headers({})                     # => {}
Normalize.headers({ "KEY" => ["a", "b"] }) # => { "key" => "a" }
Normalize.headers({ "Key" => 123 })       # => { "key" => "123" }

Parameters:

  • headers (Hash, #each)

    Headers hash or hash-like object

Returns:

  • (Hash)

    Normalized headers hash with downcased keys and trimmed values



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/hooks/utils/normalize.rb', line 25

def self.headers(headers)
  # Handle nil input
  return nil if headers.nil?

  # Fast path for non-enumerable inputs (numbers, etc.)
  return {} unless headers.respond_to?(:each)

  normalized = {}

  headers.each do |key, value|
    # Skip nil keys or values entirely
    next if key.nil? || value.nil?

    # Convert key to string, downcase, and strip in one operation
    normalized_key = key.to_s.downcase.strip
    next if normalized_key.empty?

    # Handle different value types efficiently
    normalized_value = case value
                       when String
                         value.strip
                       when Array
                         # Take first non-empty element for multi-value headers
                         first_valid = value.find { |v| v && !v.to_s.strip.empty? }
                         first_valid ? first_valid.to_s.strip : nil
                       else
                         value.to_s.strip
                       end

    # Only add if we have a non-empty value
    normalized[normalized_key] = normalized_value if normalized_value && !normalized_value.empty?
  end

  normalized
end

.symbolize_headers(headers) ⇒ Hash

Symbolize header keys in a hash

Examples:

Header symbolization

headers = { "content-type" => "application/json", "x-github-event" => "push" }
symbolized = Normalize.symbolize_headers(headers)
# => { content_type: "application/json", x_github_event: "push" }

Handle various input types

Normalize.symbolize_headers(nil)  # => nil
Normalize.symbolize_headers({})   # => {}

Parameters:

  • headers (Hash, #each)

    Headers hash or hash-like object

Returns:

  • (Hash)

    Hash with symbolized keys (hyphens converted to underscores)



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/hooks/utils/normalize.rb', line 74

def self.symbolize_headers(headers)
  # Handle nil input
  return nil if headers.nil?

  # Fast path for non-enumerable inputs
  return {} unless headers.respond_to?(:each)

  symbolized = {}

  headers.each do |key, value|
    next if key.nil?

    # Convert key to symbol, replacing hyphens with underscores
    symbolized_key = key.to_s.tr("-", "_").to_sym
    symbolized[symbolized_key] = value
  end

  symbolized
end