Module: Faraday::Middlewares::BuildService::HttpHelpers

Included in:
Authentication, SshSigner
Defined in:
lib/faraday/middlewares/build_service/http_helpers.rb

Overview

Collection of low level HTTP Helpers

Instance Method Summary collapse

Instance Method Details

#pairs_to_payload(pairs) ⇒ Object

Convert a list of pairs into signature string format

As per the last part of datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12#section-2.3 the format is:

header: value – for static http headers

Parameters:

  • pairs (Array of [String, String])

    String pairs to format



17
18
19
# File 'lib/faraday/middlewares/build_service/http_helpers.rb', line 17

def pairs_to_payload(pairs)
  pairs.map { |k, v| "#{k}: #{v}" }.join("\n")
end

#pairs_to_quoted_string(pairs) ⇒ Object

Convert a list of pairs into signature string format

As per the last part of datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12#section-2.3 the format is:

header: value – for static http headers

Parameters:

  • pairs (Array of [String, String])

    String pairs to format



30
31
32
33
34
35
# File 'lib/faraday/middlewares/build_service/http_helpers.rb', line 30

def pairs_to_quoted_string(pairs)
  pairs.map do |key, value|
    value = value.to_s.gsub('"', '\\"') # escape inner quotes
    %(#{key}="#{value}")
  end.join(",")
end

#parse_authorization_header(header) ⇒ Object

Parse an WWW-Authenticate Header a hash of challenges

The WWW-Authenticate grammar is defined in datatracker.ietf.org/doc/html/rfc7235#section-4.1

given this input: ‘Signature realm=“yourealm”,headers=“abcdef”’ it returns { Signature: “yourealm”, headers: “abcdef” }

This implementation is generic enough to get information about multiple challenges as long as they’re not the same.

Parameters:

  • header (String)

    WWW-Authenticate Header



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/faraday/middlewares/build_service/http_helpers.rb', line 116

def parse_authorization_header(header)
  result = {}
  current_section = nil

  parse_list_header(header).each do |item|
    result[item] = nil and next unless item.include?("=")

    name, value = item.split("=", 2)

    if name.include?(" ")
      current_section, name = name.split(" ", 2)
    end

    if value[0] == value[-1] && value[0] == '"'
      value = unquote(value[1..])
    end

    (result[current_section.to_sym] ||= {})[name.to_sym] = value
  end

  result
end

#parse_list_header(list_string) ⇒ Object

Parse an http header list into a ruby list. This is not a regexable (at least not a simple regex can do it so far) since the quoted values can have commas. Is written as a tokenizer for this reason.

example input: ‘Signature realm=“Use your developer account”,headers=“(created)”, Basic realm=“somerealm”’

example output: [‘Signature realm=“Use your developer account”’, ‘headers=“(created)”’, ‘Basic realm=“somerealm”’]

Parameters:

  • list_string (String)

    HTTP List string



46
47
48
49
50
51
52
53
54
55
56
57
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
92
93
94
95
96
97
98
99
100
101
# File 'lib/faraday/middlewares/build_service/http_helpers.rb', line 46

def parse_list_header(list_string)
  res = []
  part = ""
  escape = quote = false

  list_string.each_char do |char|
    # if in escape mode, add the escaped character and reset
    # the escape flag.
    if escape
      part += char
      escape = false
      next
    end

    # if in quote mode
    if quote
      case char
      # check for a escape sequence and skip the escape character
      when "\\"
        escape = true
        next
      # check a quote and disable quote mode
      when '"'
        quote = false
      end

      # add the character to the part but don't process anything further
      # quoted commas are meant to be kept as values
      part += char
      next
    end

    # in normal case
    case char
    # comma is a signal for a new item, save the current part & reset.
    when ","
      res << part
      part = ""
      next
    # quote enables quote mode
    when '"'
      quote = true
    end

    # add the character to the part
    part += char
  end

  # if there's any pending part, add it to the final result
  if part
    res << part
  end

  # strip the surrounding spaces & remove the empty items
  res.map(&:strip).reject(&:empty?)
end

#unquote(string) ⇒ Object

Remove quotes from string

Parameters:

  • string (String)

    String to be unquoted



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/faraday/middlewares/build_service/http_helpers.rb', line 142

def unquote(string)
  s = string.dup

  case string[0, 1]
  when "'", '"', "`"
    s[0] = ""
  end

  case string[-1, 1]
  when "'", '"', "`"
    s[-1] = ""
  end

  s
end