Class: Mailkube::Config
- Inherits:
-
Object
- Object
- Mailkube::Config
- Defined in:
- lib/mailkube/config.rb,
sig/mailkube/config.rbs
Overview
Resolved client configuration: the key, the origin, the timeout and the default headers.
This is the only place configuration is read, and the only place a URL is built. Keeping the origin guard here rather than in a resource protects every future link-following feature for free. Instances are frozen: a client that cannot be reconfigured after construction is a client that cannot develop a concurrency bug.
Constant Summary collapse
- ENV_API_KEY =
Environment variable holding the API key.
"MAILKUBE_API_KEY"- ENV_BASE_URL =
Environment variable overriding the API base URL.
"MAILKUBE_BASE_URL"- DEFAULT_TIMEOUT =
Per-request timeout in seconds when the caller does not set one.
30
Instance Attribute Summary collapse
-
#base_url ⇒ String
readonly
The resolved API base URL, always ending in a slash.
-
#timeout ⇒ Integer, Float
readonly
The per-request timeout in seconds.
Instance Method Summary collapse
-
#build_url(path, params = {}) ⇒ String
Join a relative path onto the base URL, attach the query, and refuse any absolute URL off the base URL's origin.
-
#default_headers ⇒ Hash{String => String}
The auth and non-browser identification headers sent on every request.
-
#initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT) ⇒ Config
constructor
Resolve configuration from the arguments, then the environment, then the defaults.
Constructor Details
#initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT) ⇒ Config
Resolve configuration from the arguments, then the environment, then the defaults.
34 35 36 37 38 39 40 41 42 |
# File 'lib/mailkube/config.rb', line 34 def initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT) key = api_key || ENV.fetch(ENV_API_KEY, nil) raise ConfigurationError, "no API key provided: pass api_key: or set #{ENV_API_KEY}" if key.nil? || key.empty? @api_key = key @base_url = base_url || ENV.fetch(ENV_BASE_URL, nil) || Mailkube::DEFAULT_BASE_URL @timeout = timeout freeze end |
Instance Attribute Details
#base_url ⇒ String (readonly)
Returns the resolved API base URL, always ending in a slash.
24 25 26 |
# File 'lib/mailkube/config.rb', line 24 def base_url @base_url end |
#timeout ⇒ Integer, Float (readonly)
Returns the per-request timeout in seconds.
26 27 28 |
# File 'lib/mailkube/config.rb', line 26 def timeout @timeout end |
Instance Method Details
#build_url(path, params = {}) ⇒ String
Join a relative path onto the base URL, attach the query, and refuse any absolute URL off the base URL's origin.
Every request carries the Authorization header, so following a link that names a foreign host would hand that host the API key.
The query is attached after the origin check and only when there is one, so an absolute
page link the API issued keeps its own query untouched and an unfiltered listing produces no
? at all. URI.encode_www_form — not Serialization.escape_segment — is correct here: a
space in a query value is +, and a space in a path segment is %20.
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/mailkube/config.rb', line 76 def build_url(path, params = {}) base = URI.parse(@base_url) resolved = base.merge(path) unless resolved.scheme == base.scheme && resolved.host == base.host && resolved.port == base.port raise ConfigurationError, "refusing to follow #{resolved}: it is not on the configured API origin" end resolved.query = URI.encode_www_form(params) unless params.empty? resolved.to_s rescue URI::InvalidURIError, URI::InvalidComponentError => e raise ConfigurationError, "invalid URL #{path.inspect}: #{e.}" end |
#default_headers ⇒ Hash{String => String}
The auth and non-browser identification headers sent on every request.
The User-Agent is required: the API rejects a request without one. It reports Mailkube::VERSION, which the gemspec also reads, so it cannot drift from the released version.
51 52 53 54 55 56 57 58 |
# File 'lib/mailkube/config.rb', line 51 def default_headers { "Authorization" => "Bearer #{@api_key}", "User-Agent" => "mailkube-ruby/#{VERSION}", "Content-Type" => "application/json", "Accept" => "application/json" } end |