linzer 0.7.9.beta1 → 0.7.9.beta2

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: 1e68e3de6c89b69da86e383a47e365ab275597440ac71ffb6ce261cd10ad9f51
4
- data.tar.gz: d036d8264a8bba7a7d964432e187725da146f228ee81335d3db5c3659d1578ee
3
+ metadata.gz: f13471dec9f1ca620ac5fa94faeb2173632bec2aede20fbb1e156988c48fd10d
4
+ data.tar.gz: 4dffdf98551884ea0a1b11c892ef1cb2ee5cad1fb6234e1d54890feea210a898
5
5
  SHA512:
6
- metadata.gz: b635cf2b46a0235a7e4131719b225df2a8c03b689c175baf4d9d234dcb1e1ad9f2b4ad1b52da19296444e2883064dbf11e69509ebce96695e3ee51fe7aa31f45
7
- data.tar.gz: 729797295ce7a27128046cd6ae9714d0a74e6ba64f3db74e9f4fe48106548fd911c60a2f9442e387a5a04e82c54644294587f5b61e2d3aaa21d6a09aa5e1681e
6
+ metadata.gz: 1ca361d6e8dbc9d1960f37f33785a56cb7cd5a22a61d9fbe44228541c5cf54791acc21d9d19b4fb9a078322855776686d42aff86bbc05d4014cc017669375e9a
7
+ data.tar.gz: 89979f2b5c0e2d2a527cb04e223879f543a26c0cc81ef702ce5c3858c8f241126a38d28aeb9070bacebfbfdf488eae75e5e75f9fd0a242b5e04dfa12c76f6d6d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.7.9.beta2] - 2026-04-19
4
+
5
+ - Add support for http gem 6.x while maintaining compatibility with 5.x.
6
+ Handles API differences introduced in 6.0.
7
+ - Improve README clarity and align it with current behavior and production usage.
8
+
3
9
  ## [0.7.9.beta1] - 2026-03-03
4
10
 
5
11
  (Beta release to test gem release automation; no functional changes)
data/README.md CHANGED
@@ -9,7 +9,12 @@
9
9
  [rubydoc-badge]: https://img.shields.io/badge/docs-RubyDoc.info-blue
10
10
  [rubydoc-link]: https://www.rubydoc.info/gems/linzer
11
11
 
12
- Linzer is a Ruby library for [HTTP Message Signatures (RFC 9421)](https://www.rfc-editor.org/rfc/rfc9421.html).
12
+ Linzer is a Ruby library for [HTTP Message Signatures (RFC 9421)](https://www.rfc-editor.org/rfc/rfc9421.html),
13
+ allowing you to sign and verify HTTP requests and responses with
14
+ standard-compliant cryptographic signatures.
15
+
16
+ Useful for APIs, webhooks, and services that need to verify request
17
+ authenticity or prevent tampering.
13
18
 
14
19
  ## Install
15
20
 
@@ -23,48 +28,79 @@ Or just `gem install linzer`.
23
28
 
24
29
  ## Usage
25
30
 
26
- ### TL;DR: I just want to protect my application!!
31
+ ### Quick start
27
32
 
28
- Add the following middleware to your Rack application and configure it
29
- as needed, e.g.:
33
+ Add the middleware to your Rack application:
30
34
 
31
35
  ```ruby
32
36
  # config.ru
33
- use Rack::Auth::Signature, except: "/login",
34
- default_key: {material: Base64.strict_decode64(ENV["MYAPP_KEY"]), alg: "hmac-sha256"}
35
- # or: default_key: {material: IO.read("app/config/pubkey.pem"), "ed25519"}
37
+ use Rack::Auth::Signature,
38
+ except: "/login",
39
+ default_key: {
40
+ material: Base64.strict_decode64(ENV["MYAPP_KEY"]),
41
+ alg: "hmac-sha256"
42
+ }
43
+ # or using a public/private key pair:
44
+ # default_key: { material: IO.read("app/config/pubkey.pem"), alg: "ed25519" }
36
45
  ```
37
46
 
38
- or on more complex scenarios:
47
+ In this example, the middleware requires a valid HTTP Message Signature
48
+ for all endpoints except /login.
49
+
50
+ To learn how to sign requests, see the
51
+ [Signing Requests](#signing-http-requests-and-responses) section.
52
+
53
+ #### Using a configuration file
54
+
55
+ For more complex setups, you can load configuration from a file, e.g.:
39
56
 
40
57
  ```ruby
41
58
  # config.ru
42
- use Rack::Auth::Signature, except: "/login",
59
+ use Rack::Auth::Signature,
60
+ except: "/login",
43
61
  config_path: "app/configuration/http-signatures.yml"
44
62
  ```
45
63
 
46
- or with a typical Rails application:
64
+ #### Rails
65
+
66
+ In a Rails application, add the middleware in your configuration:
47
67
 
48
68
  ```ruby
49
69
  # config/application.rb
50
- config.middleware.use Rack::Auth::Signature, except: "/login",
70
+ config.middleware.use Rack::Auth::Signature,
71
+ except: "/login",
51
72
  config_path: "http-signatures.yml"
52
73
  ```
53
74
 
54
- And that's it, all routes in the example app (except `/login`) above will
55
- require a valid signature created with the respective private key held by a
56
- client. For more details on what configuration options are available, take a
57
- look at
58
- [examples/sinatra/http-signatures.yml](https://github.com/nomadium/linzer/tree/master/examples/sinatra/http-signatures.yml) to get started and/or
59
- [lib/rack/auth/signature.rb](https://github.com/nomadium/linzer/tree/master/lib/rack/auth/signature.rb) for full implementation details.
75
+ #### What this does?
76
+
77
+ Once enabled, all protected routes will require a valid signature
78
+ generated by a client using the corresponding private key. Requests
79
+ without a valid signature will be rejected.
80
+
81
+ #### Next steps
82
+
83
+ - See a full configuration example:
84
+ [examples/sinatra/http-signatures.yml](https://github.com/nomadium/linzer/tree/master/examples/sinatra/http-signatures.yml)
85
+
86
+ - Browse the middleware implementation for all options:
87
+ [lib/rack/auth/signature.rb](https://github.com/nomadium/linzer/tree/master/lib/rack/auth/signature.rb)
88
+
89
+ - For more specific scenarios and use cases, continue below.
90
+
91
+ ### Signing HTTP requests and responses
60
92
 
61
- To learn about more specific scenarios or use cases, keep reading on below.
93
+ Linzer signs HTTP requests by adding the required `Signature` and
94
+ `Signature-Input` headers based on selected request components (e.g.
95
+ method, path, headers, etc).
62
96
 
63
- ### To sign a HTTP request:
97
+ Choose your client:
64
98
 
65
- There are several options:
99
+ - Use the [http gem](https://github.com/httprb/http) → recommended (simplest)
100
+ - Use `Net::HTTP` → lower-level control
101
+ - Use `Linzer::HTTP` → quick experiments / debugging
66
102
 
67
- #### If you are using http gem:
103
+ #### Using [http gem](https://github.com/httprb/http)
68
104
 
69
105
  ```ruby
70
106
  # first require http signatures feature class ready to be used with http gem:
@@ -85,7 +121,7 @@ response.body.to_s
85
121
  => "protected content..."
86
122
  ```
87
123
 
88
- #### If you are using plain old Net::HTTP:
124
+ #### Using `Net::HTTP` (manual control)
89
125
 
90
126
  ```ruby
91
127
  key = Linzer.generate_ed25519_key
@@ -111,7 +147,7 @@ request["signature-input"]
111
147
  # => "sig1=(\"@method\" \"@request-target\" \"date\" ..."}
112
148
  ```
113
149
 
114
- Then you can submit the signed request with Net::HTTP client:
150
+ Then send the request:
115
151
 
116
152
  ```ruby
117
153
  require "net/http"
@@ -152,10 +188,7 @@ response = http.request(request)
152
188
  # => #<Net::HTTPOK 200 OK readbody=true>
153
189
  ```
154
190
 
155
- #### Or you can also use the simple HTTP client bundled with this library:
156
-
157
- (This client is probably not suitable for production use but could be useful
158
- enough to get started. It's build on top of Net::HTTP.)
191
+ #### Using the built-in client
159
192
 
160
193
  ```ruby
161
194
  key = Linzer.generate_rsa_pss_sha512_key(4096)
@@ -172,13 +205,62 @@ response =
172
205
  => #<Net::HTTPOK 200 OK readbody=true>
173
206
  ```
174
207
 
175
- ### To verify an incoming request on the server side:
208
+ (This client is intended for testing and exploration.
209
+ For production use, prefer a full-featured HTTP client).
176
210
 
177
- The middleware `Rack::Auth::Signature` can be used for this scenario
178
- [as shown above](#tldr-i-just-want-to-protect-my-application).
211
+ #### Signing HTTP responses (server-side)
179
212
 
180
- Or directly in the application controller (or routes), the incoming request can
181
- be verified with the following approach:
213
+ You can sign responses using the same API as for requests, e.g.:
214
+
215
+ ```ruby
216
+ put "/baz" do
217
+ ...
218
+ response
219
+ # => #<Sinatra::Response:0x0000000109ac40b8 ...
220
+ response.headers["x-custom-app-header"] = "..."
221
+ Linzer.sign!(response,
222
+ key: my_key,
223
+ components: %w[@status content-type content-digest x-custom-app-header],
224
+ label: "sig1",
225
+ params: {
226
+ created: Time.now.to_i
227
+ }
228
+ )
229
+ response["signature"]
230
+ # => "sig1=:2TPCzD4l48bg6LMcVXdV9u..."
231
+ response["signature-input"]
232
+ # => "sig1=(\"@status\" \"content-type\" \"content-digest\"..."
233
+ ...
234
+ end
235
+ ```
236
+
237
+ ### Verifying HTTP signatures
238
+
239
+ Linzer verifies incoming requests (or responses) by checking:
240
+
241
+ - the signature is valid for the given key
242
+ - the signed components match the actual request
243
+ - any signature parameters (e.g. created, expires) are valid
244
+
245
+ If verification fails, an exception is raised explaining the reason.
246
+
247
+ #### Recommended: Rack middleware
248
+
249
+ The easiest way to verify incoming requests is via middleware:
250
+
251
+ ```ruby
252
+ use Rack::Auth::Signature, except: "/login"
253
+ ```
254
+
255
+ This automatically:
256
+
257
+ - verifies all incoming requests
258
+ - rejects invalid or unsigned requests
259
+ - integrates cleanly with Rack-based frameworks (Rails, Sinatra, etc.)
260
+
261
+ #### Manual verification (controller / route level)
262
+
263
+ If you need more control, you can verify incoming requests manually:
182
264
 
183
265
  ```ruby
184
266
  post "/foo" do
@@ -190,18 +272,31 @@ post "/foo" do
190
272
  # "PATH_INFO" => "/api",
191
273
  # ...
192
274
 
193
- result = Linzer.verify!(request, key: some_client_key)
275
+ result = Linzer.verify!(request, key: some_client_key) rescue false
194
276
  # => true
195
277
  ...
278
+ # proceed with trusted request
196
279
  end
197
280
  ```
198
281
 
199
- If the signature is missing or invalid, the verification method will raise an
200
- exception with a message clarifying why the request signature failed verification.
282
+ If the signature is missing or invalid, verify! will raise an exception.
201
283
 
202
- Also, for additional flexibility on the server side, the method above can take
203
- a block with the `keyid` parameter extracted from the signature (if any) as argument.
204
- This can be useful to retrieve key data from databases/caches on the server side, e.g.:
284
+ ```ruby
285
+ head "/bar" do
286
+ begin
287
+ Linzer.verify!(request, key: key)
288
+ rescue Linzer::VerifyError => e
289
+ halt 401, e.message
290
+ end
291
+ end
292
+ ```
293
+
294
+ #### Dynamic key lookup
295
+
296
+ In many cases, the verification key depends on the `keyid` parameter provided in
297
+ the signature.
298
+
299
+ You can supply a block to resolve keys dynamically:
205
300
 
206
301
  ```ruby
207
302
  get "/bar" do
@@ -211,14 +306,22 @@ get "/bar" do
211
306
  end
212
307
  # => true
213
308
  ...
309
+ # request is now verified
214
310
  end
215
311
  ```
216
312
 
217
- ### To verify a received response on the client side:
313
+ This is useful when:
314
+
315
+ - you have multiple clients
316
+ - keys are stored in a database or external service
317
+ - keys rotate over time
218
318
 
219
- It's similar to verifying requests, the same method is used, see example below:
319
+ #### Verifying responses (client-side)
320
+
321
+ As expected, signed responses are verified using the same API shown previously:
220
322
 
221
323
  ```ruby
324
+ ...
222
325
  response
223
326
  # => #<Net::HTTPOK 200 OK readbody=true>
224
327
  response.body
@@ -228,43 +331,26 @@ result = Linzer.verify!(response, key: pubkey, no_older_than: 600)
228
331
  # => true
229
332
  ```
230
333
 
231
- ### To sign an outgoing response on the server side:
334
+ ### Using a custom HTTP library
232
335
 
233
- Again, the same principle used to sign outgoing requests, the same method is used,
234
- see example below:
336
+ If you’re using an HTTP library or framework other than Rack, http gem or
337
+ `Net::HTTP`, you can plug in your own adapter with very little effort.
235
338
 
236
- ```ruby
237
- put "/baz" do
238
- ...
239
- response
240
- # => #<Sinatra::Response:0x0000000109ac40b8 ...
241
- response.headers["x-custom-app-header"] = "..."
242
- Linzer.sign!(response,
243
- key: my_key,
244
- components: %w[@status content-type content-digest x-custom-app-header],
245
- label: "sig1",
246
- params: {
247
- created: Time.now.to_i
248
- }
249
- )
250
- response["signature"]
251
- # => "sig1=:2TPCzD4l48bg6LMcVXdV9u..."
252
- response["signature-input"]
253
- # => "sig1=(\"@status\" \"content-type\" \"content-digest\"..."
254
- ...
255
- end
256
- ```
339
+ In most cases, implementing an adapter just means mapping your library’s
340
+ request/response objects to the small interface Linzer expects,
341
+ then registering it.
342
+
343
+ To do this:
344
+
345
+ - implement a simple adapter for your request/response objects
346
+ - register it with `Linzer::Message`
257
347
 
258
- ### What do you do if you want to sign/verify requests and responses with your preferred HTTP ruby library/framework (not using Rack or `Net::HTTP`, for example)?
348
+ You can use the existing adapters as references:
259
349
 
260
- You can provide an adapter class and then register it with this library.
261
- For guidance on how to implement such adapters, you can consult an
262
- [example adapter for http gem response](https://github.com/nomadium/linzer/blob/master/lib/linzer/message/adapter/http_gem/response.rb)
263
- included with this gem or the ones
264
- [provided out of the box](https://github.com/nomadium/linzer/blob/master/lib/linzer/message/adapter).
350
+ - [HTTP gem response adapter](https://github.com/nomadium/linzer/blob/master/lib/linzer/message/adapter/http_gem/response.rb)
351
+ - [Built-in adapters](https://github.com/nomadium/linzer/blob/master/lib/linzer/message/adapter)
265
352
 
266
- For how to register a custom adapter and how to verify signatures in a response,
267
- see this example:
353
+ Example of how to register an adapter before using a custom HTTP library:
268
354
 
269
355
  ```ruby
270
356
  Linzer::Message.register_adapter(HTTP::Response, Linzer::Message::Adapter::HTTPGem::Response)
@@ -278,22 +364,19 @@ response["signature-input"]
278
364
  result = Linzer.verify!(response, key: my_key)
279
365
  # => true
280
366
  ```
281
- ---
282
367
 
283
- Furthermore, on some low-level scenarios where a user wants or needs additional
284
- control on how the signing and verification routines are performed, Linzer allows
285
- to manipulate instances of internal HTTP messages (requests & responses, see
286
- `Linzer::Message` class and available adapters), signature objects
287
- (`Linzer::Signature`) and how to register additional message adapters for any
288
- HTTP ruby library not supported out of the box by this gem.
368
+ ### Advanced verification
289
369
 
290
- See below for a few examples of these scenarios.
370
+ For low-level control over signing and verification, Linzer
371
+ exposes internal message and signature objects. This allows
372
+ you to work directly with `Linzer::Message` and `Linzer::Signature`,
373
+ or integrate custom HTTP adapters if needed.
291
374
 
292
- #### To verify a valid signature:
375
+ #### Verifying a signature manually
293
376
 
294
377
  ```ruby
295
378
  test_ed25519_key_pub = key.material.public_to_pem
296
- # => "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAK1ZrC4JqC356pRsUiLVJdFZ3dAjo909VfWs1li33MCQ=\n-----END PUBLIC KEY-----\n"
379
+ # => "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAK1ZrC4JqC356pRs..."
297
380
 
298
381
  pubkey = Linzer.new_ed25519_public_key(test_ed25519_key_pub, "some-key-ed25519")
299
382
  # => #<Linzer::Ed25519::Key:0x00000fe19b9384b0
@@ -306,53 +389,45 @@ Linzer.verify(pubkey, message, signature)
306
389
  # => true
307
390
  ```
308
391
 
309
- To mitigate the risk of "replay attacks" (i.e. an attacker capturing a message with a valid signature and re-sending it at a later point) applications may want to validate the `created` parameter of the signature. Linzer can do this automatically when given the optional `no_older_than` keyword argument:
392
+ #### Preventing replay attacks
310
393
 
311
- ```ruby
312
- Linzer.verify(pubkey, message, signature, no_older_than: 500)
313
- ```
394
+ To reduce the risk of replay attacks (e.g. reusing a captured
395
+ valid request), you can validate the `created` timestamp in the signature.
314
396
 
315
- `no_older_than` expects a number of seconds, but you can pass anything that to responds to `#to_i`, including an `ActiveSupport::Duration`.
316
- `::verify` will raise if the `created` parameter of the signature is older than the given number of seconds.
317
-
318
- #### What if an invalid signature if verified?
397
+ Linzer supports this via the `no_older_than` option:
319
398
 
320
399
  ```ruby
321
- result = Linzer.verify(pubkey, message, signature)
322
- lib/linzer/verifier.rb:38:in `verify_or_fail': Failed to verify message: Invalid signature. (Linzer::Error)
400
+ Linzer.verify(pubkey, message, signature, no_older_than: 500)
323
401
  ```
324
402
 
325
- #### HTTP responses are also supported
403
+ `no_older_than` expects a number of seconds, but you can pass
404
+ anything that to responds to `#to_i`, including an `ActiveSupport::Duration`.
326
405
 
327
- HTTP responses can also be signed and verified in the same way as requests.
406
+ If the signature is older than the allowed window, verification
407
+ fails with an error.
328
408
 
329
- ```ruby
330
- headers = {
331
- "date" => "Sat, 30 Mar 2024 21:40:13 GMT",
332
- "x-response-custom" => "bar"
333
- }
409
+ ## Supported algorithms
334
410
 
335
- response = Linzer.new_response("request body", 200, headers)
336
- # or just use the response object exposed by your HTTP framework
411
+ Linzer currently supports the following signature algorithms:
337
412
 
338
- message = Linzer::Message.new(response)
339
- fields = %w[@status date x-response-custom]
413
+ - RSASSA-PSS (SHA-512)
414
+ - RSASSA-PKCS1-v1_5 (SHA-256)
415
+ - HMAC-SHA256
416
+ - Ed25519
417
+ - ECDSA (P-256 and P-384 curves).
340
418
 
341
- signature = Linzer.sign(key, message, fields)
419
+ Of the JSON Web Signature (JWS) algorithms mentioned in RFC 9421,
420
+ only Ed25519 is currently supported. Support for additional
421
+ algorithms is planned and should be straightforward to add.
342
422
 
343
- pp signature.to_h
344
- # => {"signature"=>
345
- # "sig1=:tCldwXqbISktyABrmbhszo...",
346
- # "signature-input"=>"sig1=(\"@status\" \"date\" ..."}
347
-
348
- ```
423
+ The goal is to support as much of the RFC as possible before the 1.0 release.
349
424
 
350
- For now, to consult additional details just take a look at source code and/or the unit tests.
425
+ ## Documentation
351
426
 
352
- Please note that is still early days and extensive testing is still ongoing. For now the following algorithms are supported: RSASSA-PSS using SHA-512, RSASSA-PKCS1-v1_5 using SHA-256, HMAC-SHA256, Ed25519 and ECDSA (P-256 and P-384 curves). JSON Web Signature (JWS) algorithms mentioned in the RFC are not supported yet.
427
+ The codebase is well-documented, and the Ruby API documentation is
428
+ available on [Rubydoc](https://www.rubydoc.info/gems/linzer).
353
429
 
354
- I'll be expanding the library to cover more functionality specified in the RFC
355
- in subsequent releases.
430
+ For deeper details or edge cases, the source code and unit tests are also a good reference.
356
431
 
357
432
  ## Ruby version compatibility
358
433
 
@@ -360,7 +435,17 @@ linzer is built in [Continuous Integration](https://github.com/nomadium/linzer/a
360
435
 
361
436
  ## Security
362
437
 
363
- This gem is provided “as is” without any warranties. It has not been audited for security vulnerabilities. Users are advised to review the code and assess its suitability for their use case, particularly in production environments.
438
+ This gem is provided “as is” without any warranties. It has not
439
+ been independently audited for security vulnerabilities. Users
440
+ are advised to review the code and assess its suitability for their
441
+ use case, particularly in production environments.
442
+
443
+ Despite this, Linzer is already used in production by other projects
444
+ with security-sensitive requirements, including
445
+ [Mastodon](https://github.com/mastodon/mastodon)
446
+ ([since version 4.5.0](https://docs.joinmastodon.org/spec/security/#http-message-signatures)).
447
+ This does not constitute a security guarantee or endorsement,
448
+ but it may be useful context when evaluating adoption.
364
449
 
365
450
  ## Development
366
451
 
data/flake.lock CHANGED
@@ -2,7 +2,9 @@
2
2
  "nodes": {
3
3
  "bundix": {
4
4
  "inputs": {
5
- "nixpkgs": "nixpkgs"
5
+ "nixpkgs": [
6
+ "nixpkgs"
7
+ ]
6
8
  },
7
9
  "locked": {
8
10
  "lastModified": 1762235257,
@@ -20,25 +22,11 @@
20
22
  },
21
23
  "nixpkgs": {
22
24
  "locked": {
23
- "lastModified": 1761880412,
24
- "narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=",
25
+ "lastModified": 1775710090,
26
+ "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
25
27
  "owner": "NixOS",
26
28
  "repo": "nixpkgs",
27
- "rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386",
28
- "type": "github"
29
- },
30
- "original": {
31
- "id": "nixpkgs",
32
- "type": "indirect"
33
- }
34
- },
35
- "nixpkgs_2": {
36
- "locked": {
37
- "lastModified": 1770115704,
38
- "narHash": "sha256-KHFT9UWOF2yRPlAnSXQJh6uVcgNcWlFqqiAZ7OVlHNc=",
39
- "owner": "NixOS",
40
- "repo": "nixpkgs",
41
- "rev": "e6eae2ee2110f3d31110d5c222cd395303343b08",
29
+ "rev": "4c1018dae018162ec878d42fec712642d214fdfa",
42
30
  "type": "github"
43
31
  },
44
32
  "original": {
@@ -48,31 +36,19 @@
48
36
  "type": "github"
49
37
  }
50
38
  },
51
- "nixpkgs_3": {
52
- "locked": {
53
- "lastModified": 1678875422,
54
- "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
55
- "owner": "NixOS",
56
- "repo": "nixpkgs",
57
- "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
58
- "type": "github"
59
- },
60
- "original": {
61
- "id": "nixpkgs",
62
- "type": "indirect"
63
- }
64
- },
65
39
  "root": {
66
40
  "inputs": {
67
41
  "bundix": "bundix",
68
- "nixpkgs": "nixpkgs_2",
42
+ "nixpkgs": "nixpkgs",
69
43
  "ruby-nix": "ruby-nix",
70
44
  "systems": "systems"
71
45
  }
72
46
  },
73
47
  "ruby-nix": {
74
48
  "inputs": {
75
- "nixpkgs": "nixpkgs_3"
49
+ "nixpkgs": [
50
+ "nixpkgs"
51
+ ]
76
52
  },
77
53
  "locked": {
78
54
  "lastModified": 1755059052,
data/flake.nix CHANGED
@@ -1,11 +1,23 @@
1
1
  {
2
2
  inputs = {
3
3
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
4
- # XXX: should work, not tested yet on MacOS
5
- # systems.url = "github:nix-systems/default";
6
- systems.url = "github:nix-systems/default-linux";
7
- ruby-nix.url = "github:inscapist/ruby-nix";
8
- bundix.url = "github:inscapist/bundix";
4
+
5
+ systems = {
6
+ url = "github:nix-systems/default-linux";
7
+ # XXX: should work, not tested yet on MacOS
8
+ # url = "github:nix-systems/default";
9
+ inputs.nixpkgs.follows = "nixpkgs";
10
+ };
11
+
12
+ ruby-nix = {
13
+ url = "github:inscapist/ruby-nix";
14
+ inputs.nixpkgs.follows = "nixpkgs";
15
+ };
16
+
17
+ bundix = {
18
+ url = "github:inscapist/bundix";
19
+ inputs.nixpkgs.follows = "nixpkgs";
20
+ };
9
21
  };
10
22
 
11
23
  outputs = {
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Linzer
4
+ class Message
5
+ module Adapter
6
+ # http.rb gem message adapters.
7
+ #
8
+ # Provides adapters for {HTTP::Request} and {HTTP::Response} objects
9
+ # from the http.rb gem.
10
+ #
11
+ # @note These adapters are loaded on-demand when using the
12
+ # {Linzer::HTTP::SignatureFeature}.
13
+ module HTTPGem
14
+ # Shared functionality for http.rb request and response adapters.
15
+ module Common
16
+ # Retrieves a header value by name.
17
+ # @param name [String] The header name
18
+ # @return [String, nil] The header value
19
+ def header(name)
20
+ @operation.headers[name]
21
+ end
22
+
23
+ # Attaches a signature to the response.
24
+ # @param signature [Signature] The signature to attach
25
+ # @return [Object] The underlying response object
26
+ def attach!(signature)
27
+ signature.to_h.each { |h, v| @operation.headers[h] = v }
28
+ @operation
29
+ end
30
+
31
+ private
32
+
33
+ def field(name)
34
+ has_tr = name.parameters["tr"]
35
+ return nil if has_tr # XXX: is there a library actually supporting trailers?
36
+ value = @operation.headers[name.value.to_s]
37
+ value.dup&.strip
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,24 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "linzer/message/adapter/http_gem/common"
4
+
3
5
  module Linzer
4
6
  class Message
5
7
  module Adapter
6
- # http.rb gem message adapters.
7
- #
8
- # Provides adapters for {HTTP::Request} and {HTTP::Response} objects
9
- # from the http.rb gem.
10
- #
11
- # @note These adapters are loaded on-demand when using the
12
- # {Linzer::HTTP::SignatureFeature}.
13
8
  module HTTPGem
14
9
  # Adapter for {HTTP::Request} objects from http.rb gem.
15
10
  #
16
11
  # Extends the generic request adapter with http.rb-specific
17
12
  # method name retrieval.
18
13
  class Request < Generic::Request
14
+ include HTTPGem::Common
15
+
19
16
  private
20
17
 
21
18
  def derived(name)
19
+ return @operation.uri.host if name.value == "@authority"
22
20
  return @operation.verb.to_s.upcase if name.value == "@method"
23
21
  super
24
22
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "linzer/message/adapter/http_gem/common"
4
+
3
5
  module Linzer
4
6
  class Message
5
7
  module Adapter
@@ -13,6 +15,8 @@ module Linzer
13
15
  #
14
16
  # @see https://github.com/httprb/http http.rb gem
15
17
  class Response < Generic::Response
18
+ include HTTPGem::Common
19
+
16
20
  private
17
21
 
18
22
  def derived(name)
@@ -3,5 +3,5 @@
3
3
  module Linzer
4
4
  # Current version of the Linzer gem.
5
5
  # @return [String]
6
- VERSION = "0.7.9.beta1"
6
+ VERSION = "0.7.9.beta2"
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.9.beta1
4
+ version: 0.7.9.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Landaeta
@@ -199,6 +199,7 @@ files:
199
199
  - lib/linzer/message/adapter/abstract.rb
200
200
  - lib/linzer/message/adapter/generic/request.rb
201
201
  - lib/linzer/message/adapter/generic/response.rb
202
+ - lib/linzer/message/adapter/http_gem/common.rb
202
203
  - lib/linzer/message/adapter/http_gem/request.rb
203
204
  - lib/linzer/message/adapter/http_gem/response.rb
204
205
  - lib/linzer/message/adapter/net_http/request.rb