philiprehberger-http_client 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c2d06598cd67b2eacacb8b5782991c53204d9d2d0975161e8a342f02b6ea9ea
4
- data.tar.gz: 65df219a10eff45bdd84e202dc74336881c979f0cedcfb33855118e519b0d0d9
3
+ metadata.gz: ad967beaec9e64b19f5f3ff422942f5d74af63c347eec2e4b7fa61b1038d5eea
4
+ data.tar.gz: 5d16323e87ea653e03069fbf53800840b9f6a0bef8c6dc939fa9ec8a1ec3d54e
5
5
  SHA512:
6
- metadata.gz: e4b987d048b25358a516553179038dbcdda91f417205fd43f58aa6bc10dd524a7c6835c951ac1f4e2b8e0639f3daad2de648d49876e787f6f911ce2130ee822d
7
- data.tar.gz: 48ea64a75160012db6e407df73067252dc570a370c5b7968fb061f2621f468efde0973b26ad484caed947859e6f37122d7c5f3316d0f220b62a120c8b8fd81ef
6
+ metadata.gz: 27f4f025e16759d0403e121164843047a582057e94874be251d167ad585401dc6125eb88960573bb25b1e9c2e0f8c012ef79548f1c963e2d29910fb1a4b7843d
7
+ data.tar.gz: d78db1e5fb6f70df4cdfef60f5339477c64a4a50f568f89dd6d10b32ee187ac7307543347b952caeeb30983c8fdc92a207ef25823e4b53fcab15436400adf3ed
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.2] - 2026-04-16
11
+
12
+ ### Added
13
+ - README documentation and spec coverage for `Client#head` — request signature, empty-body response contract, and full middleware/retry/pool/interceptor pipeline behavior
14
+
15
+ ## [0.8.1] - 2026-04-07
16
+
17
+ ### Added
18
+ - `ConfigurationError` raised at initialization for invalid `timeout`, `open_timeout`, `read_timeout`, `write_timeout`, `retries`, `retry_delay`, `retry_backoff`, or `retry_on_status` values — fail fast instead of producing confusing runtime errors
19
+
10
20
  ## [0.8.0] - 2026-04-05
11
21
 
12
22
  ### Added
data/README.md CHANGED
@@ -396,6 +396,21 @@ client.get("/users")
396
396
  # Prints: GET https://api.example.com/users -> 200 (0.234s)
397
397
  ```
398
398
 
399
+ ### HEAD requests
400
+
401
+ Issue a HEAD request to retrieve response headers without downloading the body. The call mirrors `#get` — same options, same middleware/retry/pool pipeline — but the returned `Response#body` is always the empty string:
402
+
403
+ ```ruby
404
+ response = client.head("/resource", headers: { "If-None-Match" => "abc123" })
405
+
406
+ response.status # => 200
407
+ response.body # => ""
408
+ response.headers["etag"] # => "W/\"abc123\""
409
+ response.headers["content-length"] # => "1024"
410
+ ```
411
+
412
+ HEAD requests honor `params`, `headers`, `timeout`, `expect`, and `request_id` just like GET.
413
+
399
414
  ### All HTTP methods
400
415
 
401
416
  ```ruby
@@ -489,6 +504,7 @@ client.head("/resource")
489
504
  | Class | Description |
490
505
  |-------|-------------|
491
506
  | `Error` | Base error class (inherits `StandardError`) |
507
+ | `ConfigurationError` | Invalid client option (negative timeout, bad retry config, etc.) |
492
508
  | `TimeoutError` | Connection or read timeout |
493
509
  | `NetworkError` | Connection refused, reset, unreachable |
494
510
  | `HttpError` | Response status mismatch (has `.response` accessor) |
@@ -32,8 +32,10 @@ module Philiprehberger
32
32
  @base_url = base_url.chomp('/')
33
33
  @default_headers = headers
34
34
  @timeout = timeout
35
+ validate_timeout!(:timeout, timeout)
35
36
  assign_timeout_opts(opts)
36
37
  assign_retry_opts(opts)
38
+ validate_config!
37
39
  assign_cookie_opts(opts)
38
40
  assign_proxy_opts(opts)
39
41
  assign_redirect_opts(opts)
@@ -229,6 +231,31 @@ module Philiprehberger
229
231
  @open_timeout = opts[:open_timeout]
230
232
  @read_timeout = opts[:read_timeout]
231
233
  @write_timeout = opts[:write_timeout]
234
+ validate_timeout!(:open_timeout, @open_timeout)
235
+ validate_timeout!(:read_timeout, @read_timeout)
236
+ validate_timeout!(:write_timeout, @write_timeout)
237
+ end
238
+
239
+ def validate_timeout!(name, value)
240
+ return if value.nil?
241
+ raise ConfigurationError, "#{name} must be Numeric, got #{value.class}" unless value.is_a?(Numeric)
242
+ raise ConfigurationError, "#{name} must be non-negative, got #{value}" if value.negative?
243
+ end
244
+
245
+ def validate_config!
246
+ unless @retries.is_a?(Integer) && !@retries.negative?
247
+ raise ConfigurationError, "retries must be a non-negative Integer, got #{@retries.inspect}"
248
+ end
249
+ unless @retry_delay.is_a?(Numeric) && !@retry_delay.negative?
250
+ raise ConfigurationError, "retry_delay must be a non-negative Numeric, got #{@retry_delay.inspect}"
251
+ end
252
+ unless %i[fixed exponential].include?(@retry_backoff)
253
+ raise ConfigurationError, "retry_backoff must be :fixed or :exponential, got #{@retry_backoff.inspect}"
254
+ end
255
+ return if @retry_on_status.nil?
256
+ return if @retry_on_status.respond_to?(:include?)
257
+
258
+ raise ConfigurationError, 'retry_on_status must be an Array of status codes'
232
259
  end
233
260
 
234
261
  def assign_retry_opts(opts)
@@ -5,6 +5,9 @@ module Philiprehberger
5
5
  # Base error class for all HTTP client errors.
6
6
  class Error < StandardError; end
7
7
 
8
+ # Raised when client configuration is invalid (e.g. negative timeout).
9
+ class ConfigurationError < Error; end
10
+
8
11
  # Raised when a connection or read timeout occurs.
9
12
  class TimeoutError < Error; end
10
13
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module HttpClient
5
- VERSION = '0.8.0'
5
+ VERSION = '0.8.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-http_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-06 00:00:00.000000000 Z
11
+ date: 2026-04-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A zero-dependency HTTP client built on Ruby's net/http with automatic
14
14
  retries, request/response interceptors, and a clean API for JSON services.