protocol-http 0.52.0 → 0.54.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/headers.md +94 -0
- data/context/index.yaml +3 -0
- data/lib/protocol/http/body/buffered.rb +4 -2
- data/lib/protocol/http/body/completable.rb +18 -1
- data/lib/protocol/http/body/deflate.rb +13 -2
- data/lib/protocol/http/body/digestable.rb +11 -1
- data/lib/protocol/http/body/file.rb +6 -2
- data/lib/protocol/http/body/head.rb +7 -0
- data/lib/protocol/http/body/inflate.rb +1 -1
- data/lib/protocol/http/body/rewindable.rb +11 -1
- data/lib/protocol/http/body/stream.rb +15 -0
- data/lib/protocol/http/body/streamable.rb +18 -2
- data/lib/protocol/http/body/writable.rb +3 -3
- data/lib/protocol/http/header/accept.rb +6 -0
- data/lib/protocol/http/header/authorization.rb +7 -1
- data/lib/protocol/http/header/connection.rb +7 -0
- data/lib/protocol/http/header/cookie.rb +7 -0
- data/lib/protocol/http/header/date.rb +8 -1
- data/lib/protocol/http/header/digest.rb +70 -0
- data/lib/protocol/http/header/etag.rb +7 -0
- data/lib/protocol/http/header/multiple.rb +7 -0
- data/lib/protocol/http/header/server_timing.rb +92 -0
- data/lib/protocol/http/header/split.rb +7 -0
- data/lib/protocol/http/header/te.rb +131 -0
- data/lib/protocol/http/header/trailer.rb +23 -0
- data/lib/protocol/http/header/transfer_encoding.rb +78 -0
- data/lib/protocol/http/headers.rb +55 -7
- data/lib/protocol/http/response.rb +1 -1
- data/lib/protocol/http/version.rb +1 -1
- data/readme.md +12 -0
- data/releases.md +54 -0
- data.tar.gz.sig +0 -0
- metadata +7 -2
- metadata.gz.sig +0 -0
- data/agent.md +0 -145
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "split"
|
7
|
+
require_relative "quoted_string"
|
8
|
+
require_relative "../error"
|
9
|
+
|
10
|
+
module Protocol
|
11
|
+
module HTTP
|
12
|
+
module Header
|
13
|
+
# The `te` header indicates the transfer encodings the client is willing to accept. AKA `accept-transfer-encoding`. How we ended up with `te` instead of `accept-transfer-encoding` is a mystery lost to time.
|
14
|
+
#
|
15
|
+
# The `te` header allows a client to indicate which transfer encodings it can handle, and in what order of preference using quality factors.
|
16
|
+
class TE < Split
|
17
|
+
ParseError = Class.new(Error)
|
18
|
+
|
19
|
+
# Transfer encoding token pattern
|
20
|
+
TOKEN = /[!#$%&'*+\-.0-9A-Z^_`a-z|~]+/
|
21
|
+
|
22
|
+
# Quality value pattern (0.0 to 1.0)
|
23
|
+
QVALUE = /0(\.[0-9]{0,3})?|1(\.[0]{0,3})?/
|
24
|
+
|
25
|
+
# Pattern for parsing transfer encoding with optional quality factor
|
26
|
+
TRANSFER_CODING = /\A(?<name>#{TOKEN})(\s*;\s*q=(?<q>#{QVALUE}))?\z/
|
27
|
+
|
28
|
+
# The `chunked` transfer encoding
|
29
|
+
CHUNKED = "chunked"
|
30
|
+
|
31
|
+
# The `gzip` transfer encoding
|
32
|
+
GZIP = "gzip"
|
33
|
+
|
34
|
+
# The `deflate` transfer encoding
|
35
|
+
DEFLATE = "deflate"
|
36
|
+
|
37
|
+
# The `compress` transfer encoding
|
38
|
+
COMPRESS = "compress"
|
39
|
+
|
40
|
+
# The `identity` transfer encoding
|
41
|
+
IDENTITY = "identity"
|
42
|
+
|
43
|
+
# The `trailers` pseudo-encoding indicates willingness to accept trailer fields
|
44
|
+
TRAILERS = "trailers"
|
45
|
+
|
46
|
+
# A single transfer coding entry with optional quality factor
|
47
|
+
TransferCoding = Struct.new(:name, :q) do
|
48
|
+
def quality_factor
|
49
|
+
(q || 1.0).to_f
|
50
|
+
end
|
51
|
+
|
52
|
+
def <=> other
|
53
|
+
other.quality_factor <=> self.quality_factor
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
if q && q != 1.0
|
58
|
+
"#{name};q=#{q}"
|
59
|
+
else
|
60
|
+
name.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Initializes the TE header with the given value. The value is split into distinct entries and converted to lowercase for normalization.
|
66
|
+
#
|
67
|
+
# @parameter value [String | Nil] the raw header value containing transfer encodings separated by commas.
|
68
|
+
def initialize(value = nil)
|
69
|
+
super(value&.downcase)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Adds one or more comma-separated values to the TE header. The values are converted to lowercase for normalization.
|
73
|
+
#
|
74
|
+
# @parameter value [String] the value or values to add, separated by commas.
|
75
|
+
def << value
|
76
|
+
super(value.downcase)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Parse the `te` header value into a list of transfer codings with quality factors.
|
80
|
+
#
|
81
|
+
# @returns [Array(TransferCoding)] the list of transfer codings and their associated quality factors.
|
82
|
+
def transfer_codings
|
83
|
+
self.map do |value|
|
84
|
+
if match = value.match(TRANSFER_CODING)
|
85
|
+
TransferCoding.new(match[:name], match[:q])
|
86
|
+
else
|
87
|
+
raise ParseError.new("Could not parse transfer coding: #{value.inspect}")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @returns [Boolean] whether the `chunked` encoding is accepted.
|
93
|
+
def chunked?
|
94
|
+
self.any? {|value| value.start_with?(CHUNKED)}
|
95
|
+
end
|
96
|
+
|
97
|
+
# @returns [Boolean] whether the `gzip` encoding is accepted.
|
98
|
+
def gzip?
|
99
|
+
self.any? {|value| value.start_with?(GZIP)}
|
100
|
+
end
|
101
|
+
|
102
|
+
# @returns [Boolean] whether the `deflate` encoding is accepted.
|
103
|
+
def deflate?
|
104
|
+
self.any? {|value| value.start_with?(DEFLATE)}
|
105
|
+
end
|
106
|
+
|
107
|
+
# @returns [Boolean] whether the `compress` encoding is accepted.
|
108
|
+
def compress?
|
109
|
+
self.any? {|value| value.start_with?(COMPRESS)}
|
110
|
+
end
|
111
|
+
|
112
|
+
# @returns [Boolean] whether the `identity` encoding is accepted.
|
113
|
+
def identity?
|
114
|
+
self.any? {|value| value.start_with?(IDENTITY)}
|
115
|
+
end
|
116
|
+
|
117
|
+
# @returns [Boolean] whether trailers are accepted.
|
118
|
+
def trailers?
|
119
|
+
self.any? {|value| value.start_with?(TRAILERS)}
|
120
|
+
end
|
121
|
+
|
122
|
+
# Whether this header is acceptable in HTTP trailers.
|
123
|
+
# TE headers negotiate transfer encodings and must not appear in trailers.
|
124
|
+
# @returns [Boolean] `false`, as TE headers are hop-by-hop and control message framing.
|
125
|
+
def self.trailer?
|
126
|
+
false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "split"
|
7
|
+
|
8
|
+
module Protocol
|
9
|
+
module HTTP
|
10
|
+
module Header
|
11
|
+
# Represents headers that can contain multiple distinct values separated by commas.
|
12
|
+
#
|
13
|
+
# This isn't a specific header class is a utility for handling headers with comma-separated values, such as `accept`, `cache-control`, and other similar headers. The values are split and stored as an array internally, and serialized back to a comma-separated string when needed.
|
14
|
+
class Trailer < Split
|
15
|
+
# Whether this header is acceptable in HTTP trailers.
|
16
|
+
# @returns [Boolean] `false`, as Trailer headers control trailer processing and must appear before the message body.
|
17
|
+
def self.trailer?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "split"
|
7
|
+
|
8
|
+
module Protocol
|
9
|
+
module HTTP
|
10
|
+
module Header
|
11
|
+
# The `transfer-encoding` header indicates the encoding transformations that have been applied to the message body.
|
12
|
+
#
|
13
|
+
# The `transfer-encoding` header is used to specify the form of encoding used to safely transfer the message body between the sender and receiver.
|
14
|
+
class TransferEncoding < Split
|
15
|
+
# The `chunked` transfer encoding allows a server to send data of unknown length by breaking it into chunks.
|
16
|
+
CHUNKED = "chunked"
|
17
|
+
|
18
|
+
# The `gzip` transfer encoding compresses the message body using the gzip algorithm.
|
19
|
+
GZIP = "gzip"
|
20
|
+
|
21
|
+
# The `deflate` transfer encoding compresses the message body using the deflate algorithm.
|
22
|
+
DEFLATE = "deflate"
|
23
|
+
|
24
|
+
# The `compress` transfer encoding compresses the message body using the compress algorithm.
|
25
|
+
COMPRESS = "compress"
|
26
|
+
|
27
|
+
# The `identity` transfer encoding indicates no transformation has been applied.
|
28
|
+
IDENTITY = "identity"
|
29
|
+
|
30
|
+
# Initializes the transfer encoding header with the given value. The value is split into distinct entries and converted to lowercase for normalization.
|
31
|
+
#
|
32
|
+
# @parameter value [String | Nil] the raw header value containing transfer encodings separated by commas.
|
33
|
+
def initialize(value = nil)
|
34
|
+
super(value&.downcase)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Adds one or more comma-separated values to the transfer encoding header. The values are converted to lowercase for normalization.
|
38
|
+
#
|
39
|
+
# @parameter value [String] the value or values to add, separated by commas.
|
40
|
+
def << value
|
41
|
+
super(value.downcase)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @returns [Boolean] whether the `chunked` encoding is present.
|
45
|
+
def chunked?
|
46
|
+
self.include?(CHUNKED)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @returns [Boolean] whether the `gzip` encoding is present.
|
50
|
+
def gzip?
|
51
|
+
self.include?(GZIP)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @returns [Boolean] whether the `deflate` encoding is present.
|
55
|
+
def deflate?
|
56
|
+
self.include?(DEFLATE)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @returns [Boolean] whether the `compress` encoding is present.
|
60
|
+
def compress?
|
61
|
+
self.include?(COMPRESS)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @returns [Boolean] whether the `identity` encoding is present.
|
65
|
+
def identity?
|
66
|
+
self.include?(IDENTITY)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Whether this header is acceptable in HTTP trailers.
|
70
|
+
# Transfer-Encoding headers control message framing and must not appear in trailers.
|
71
|
+
# @returns [Boolean] `false`, as Transfer-Encoding headers are hop-by-hop and must precede the message body.
|
72
|
+
def self.trailer?
|
73
|
+
false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -17,11 +17,16 @@ require_relative "header/vary"
|
|
17
17
|
require_relative "header/authorization"
|
18
18
|
require_relative "header/date"
|
19
19
|
require_relative "header/priority"
|
20
|
+
require_relative "header/trailer"
|
21
|
+
require_relative "header/server_timing"
|
22
|
+
require_relative "header/digest"
|
20
23
|
|
21
24
|
require_relative "header/accept"
|
22
25
|
require_relative "header/accept_charset"
|
23
26
|
require_relative "header/accept_encoding"
|
24
27
|
require_relative "header/accept_language"
|
28
|
+
require_relative "header/transfer_encoding"
|
29
|
+
require_relative "header/te"
|
25
30
|
|
26
31
|
module Protocol
|
27
32
|
module HTTP
|
@@ -65,7 +70,7 @@ module Protocol
|
|
65
70
|
#
|
66
71
|
# @parameter fields [Array] An array of `[key, value]` pairs.
|
67
72
|
# @parameter tail [Integer | Nil] The index of the trailer start in the @fields array.
|
68
|
-
def initialize(fields = [], tail = nil, indexed: nil)
|
73
|
+
def initialize(fields = [], tail = nil, indexed: nil, policy: POLICY)
|
69
74
|
@fields = fields
|
70
75
|
|
71
76
|
# Marks where trailer start in the @fields array:
|
@@ -73,6 +78,21 @@ module Protocol
|
|
73
78
|
|
74
79
|
# The cached index of headers:
|
75
80
|
@indexed = nil
|
81
|
+
|
82
|
+
@policy = policy
|
83
|
+
end
|
84
|
+
|
85
|
+
# @attribute [Hash] The policy for the headers.
|
86
|
+
attr :policy
|
87
|
+
|
88
|
+
# Set the policy for the headers.
|
89
|
+
#
|
90
|
+
# The policy is used to determine how headers are merged and normalized. For example, if a header is specified multiple times, the policy will determine how the values are merged.
|
91
|
+
#
|
92
|
+
# @parameter policy [Hash] The policy for the headers.
|
93
|
+
def policy=(policy)
|
94
|
+
@policy = policy
|
95
|
+
@indexed = nil
|
76
96
|
end
|
77
97
|
|
78
98
|
# Initialize a copy of the headers.
|
@@ -250,17 +270,23 @@ module Protocol
|
|
250
270
|
"content-disposition" => false,
|
251
271
|
"content-length" => false,
|
252
272
|
"content-type" => false,
|
273
|
+
"expect" => false,
|
253
274
|
"from" => false,
|
254
275
|
"host" => false,
|
255
276
|
"location" => false,
|
256
277
|
"max-forwards" => false,
|
278
|
+
"range" => false,
|
257
279
|
"referer" => false,
|
258
280
|
"retry-after" => false,
|
281
|
+
"server" => false,
|
282
|
+
"transfer-encoding" => Header::TransferEncoding,
|
259
283
|
"user-agent" => false,
|
284
|
+
"trailer" => Header::Trailer,
|
260
285
|
|
261
286
|
# Custom headers:
|
262
287
|
"connection" => Header::Connection,
|
263
288
|
"cache-control" => Header::CacheControl,
|
289
|
+
"te" => Header::TE,
|
264
290
|
"vary" => Header::Vary,
|
265
291
|
"priority" => Header::Priority,
|
266
292
|
|
@@ -299,6 +325,12 @@ module Protocol
|
|
299
325
|
"accept-charset" => Header::AcceptCharset,
|
300
326
|
"accept-encoding" => Header::AcceptEncoding,
|
301
327
|
"accept-language" => Header::AcceptLanguage,
|
328
|
+
|
329
|
+
# Performance headers:
|
330
|
+
"server-timing" => Header::ServerTiming,
|
331
|
+
|
332
|
+
# Content integrity headers:
|
333
|
+
"digest" => Header::Digest,
|
302
334
|
}.tap{|hash| hash.default = Split}
|
303
335
|
|
304
336
|
# Delete all header values for the given key, and return the merged value.
|
@@ -316,7 +348,7 @@ module Protocol
|
|
316
348
|
|
317
349
|
if @indexed
|
318
350
|
return @indexed.delete(key)
|
319
|
-
elsif policy =
|
351
|
+
elsif policy = @policy[key]
|
320
352
|
(key, value), *tail = deleted
|
321
353
|
merged = policy.new(value)
|
322
354
|
|
@@ -334,14 +366,24 @@ module Protocol
|
|
334
366
|
# @parameter hash [Hash] The hash to merge into.
|
335
367
|
# @parameter key [String] The header key.
|
336
368
|
# @parameter value [String] The raw header value.
|
337
|
-
protected def merge_into(hash, key, value)
|
338
|
-
if policy =
|
369
|
+
protected def merge_into(hash, key, value, trailer = @tail)
|
370
|
+
if policy = @policy[key]
|
371
|
+
# Check if we're adding to trailers and this header is allowed:
|
372
|
+
if trailer && !policy.trailer?
|
373
|
+
return false
|
374
|
+
end
|
375
|
+
|
339
376
|
if current_value = hash[key]
|
340
377
|
current_value << value
|
341
378
|
else
|
342
379
|
hash[key] = policy.new(value)
|
343
380
|
end
|
344
381
|
else
|
382
|
+
# By default, headers are not allowed in trailers:
|
383
|
+
if trailer
|
384
|
+
return false
|
385
|
+
end
|
386
|
+
|
345
387
|
if hash.key?(key)
|
346
388
|
raise DuplicateHeaderError, key
|
347
389
|
end
|
@@ -362,11 +404,17 @@ module Protocol
|
|
362
404
|
#
|
363
405
|
# @returns [Hash] A hash table of `{key, value}` pairs.
|
364
406
|
def to_h
|
365
|
-
@indexed
|
366
|
-
|
407
|
+
unless @indexed
|
408
|
+
@indexed = {}
|
367
409
|
|
368
|
-
|
410
|
+
@fields.each_with_index do |(key, value), index|
|
411
|
+
trailer = (@tail && index >= @tail)
|
412
|
+
|
413
|
+
merge_into(@indexed, key.downcase, value, trailer)
|
414
|
+
end
|
369
415
|
end
|
416
|
+
|
417
|
+
return @indexed
|
370
418
|
end
|
371
419
|
|
372
420
|
alias as_json to_h
|
data/readme.md
CHANGED
@@ -18,6 +18,8 @@ Please see the [project documentation](https://socketry.github.io/protocol-http/
|
|
18
18
|
|
19
19
|
- [Message Body](https://socketry.github.io/protocol-http/guides/message-body/index) - This guide explains how to work with HTTP request and response message bodies using `Protocol::HTTP::Body` classes.
|
20
20
|
|
21
|
+
- [Headers](https://socketry.github.io/protocol-http/guides/headers/index) - This guide explains how to work with HTTP headers using `protocol-http`.
|
22
|
+
|
21
23
|
- [Middleware](https://socketry.github.io/protocol-http/guides/middleware/index) - This guide explains how to build and use HTTP middleware with `Protocol::HTTP::Middleware`.
|
22
24
|
|
23
25
|
- [Hypertext References](https://socketry.github.io/protocol-http/guides/hypertext-references/index) - This guide explains how to use `Protocol::HTTP::Reference` for constructing and manipulating hypertext references (URLs with parameters).
|
@@ -32,6 +34,16 @@ Please see the [project documentation](https://socketry.github.io/protocol-http/
|
|
32
34
|
|
33
35
|
Please see the [project releases](https://socketry.github.io/protocol-http/releases/index) for all releases.
|
34
36
|
|
37
|
+
### v0.54.0
|
38
|
+
|
39
|
+
- Introduce rich support for `Header::Digest`, `Header::ServerTiming`, `Header::TE`, `Header::Trailer` and `Header::TransferEncoding`.
|
40
|
+
- [Improved HTTP Trailer Security](https://socketry.github.io/protocol-http/releases/index#improved-http-trailer-security)
|
41
|
+
|
42
|
+
### v0.53.0
|
43
|
+
|
44
|
+
- Improve consistency of Body `#inspect`.
|
45
|
+
- Improve `as_json` support for Body wrappers.
|
46
|
+
|
35
47
|
### v0.52.0
|
36
48
|
|
37
49
|
- Add `Protocol::HTTP::Headers#to_a` method that returns the fields array, providing compatibility with standard Ruby array conversion pattern.
|
data/releases.md
CHANGED
@@ -1,5 +1,59 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v0.54.0
|
4
|
+
|
5
|
+
- Introduce rich support for `Header::Digest`, `Header::ServerTiming`, `Header::TE`, `Header::Trailer` and `Header::TransferEncoding`.
|
6
|
+
|
7
|
+
### Improved HTTP Trailer Security
|
8
|
+
|
9
|
+
This release introduces significant security improvements for HTTP trailer handling, addressing potential HTTP request smuggling vulnerabilities by implementing a restrictive-by-default policy for trailer headers.
|
10
|
+
|
11
|
+
- **Security-by-default**: HTTP trailers are now validated and restricted by default to prevent HTTP request smuggling attacks.
|
12
|
+
- Only safe headers are permitted in trailers:
|
13
|
+
- `date` - Response generation timestamps (safe metadata)
|
14
|
+
- `digest` - Content integrity verification (safe metadata)
|
15
|
+
- `etag` - Cache validation tags (safe metadata)
|
16
|
+
- `server-timing` - Performance metrics (safe metadata)
|
17
|
+
- All other trailers are ignored by default.
|
18
|
+
|
19
|
+
If you are using this library for gRPC, you will need to use a custom policy to allow the `grpc-status` and `grpc-message` trailers:
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
module GRPCStatus
|
23
|
+
def self.new(value)
|
24
|
+
Integer(value)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.trailer?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module GRPCMessage
|
33
|
+
def self.new(value)
|
34
|
+
value
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.trailer?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
GRPC_POLICY = Protocol::HTTP::Headers::POLICY.dup
|
43
|
+
GRPC_POLICY['grpc-status'] = GRPCStatus
|
44
|
+
GRPC_POLICY['grpc-message'] = GRPCMessage
|
45
|
+
|
46
|
+
# Reinterpret the headers using the new policy:
|
47
|
+
response.headers.policy = GRPC_POLICY
|
48
|
+
response.headers['grpc-status'] # => 0
|
49
|
+
response.headers['grpc-message'] # => "OK"
|
50
|
+
```
|
51
|
+
|
52
|
+
## v0.53.0
|
53
|
+
|
54
|
+
- Improve consistency of Body `#inspect`.
|
55
|
+
- Improve `as_json` support for Body wrappers.
|
56
|
+
|
3
57
|
## v0.52.0
|
4
58
|
|
5
59
|
- Add `Protocol::HTTP::Headers#to_a` method that returns the fields array, providing compatibility with standard Ruby array conversion pattern.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.54.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -53,9 +53,9 @@ executables: []
|
|
53
53
|
extensions: []
|
54
54
|
extra_rdoc_files: []
|
55
55
|
files:
|
56
|
-
- agent.md
|
57
56
|
- context/design-overview.md
|
58
57
|
- context/getting-started.md
|
58
|
+
- context/headers.md
|
59
59
|
- context/hypertext-references.md
|
60
60
|
- context/index.yaml
|
61
61
|
- context/message-body.md
|
@@ -91,12 +91,17 @@ files:
|
|
91
91
|
- lib/protocol/http/header/connection.rb
|
92
92
|
- lib/protocol/http/header/cookie.rb
|
93
93
|
- lib/protocol/http/header/date.rb
|
94
|
+
- lib/protocol/http/header/digest.rb
|
94
95
|
- lib/protocol/http/header/etag.rb
|
95
96
|
- lib/protocol/http/header/etags.rb
|
96
97
|
- lib/protocol/http/header/multiple.rb
|
97
98
|
- lib/protocol/http/header/priority.rb
|
98
99
|
- lib/protocol/http/header/quoted_string.rb
|
100
|
+
- lib/protocol/http/header/server_timing.rb
|
99
101
|
- lib/protocol/http/header/split.rb
|
102
|
+
- lib/protocol/http/header/te.rb
|
103
|
+
- lib/protocol/http/header/trailer.rb
|
104
|
+
- lib/protocol/http/header/transfer_encoding.rb
|
100
105
|
- lib/protocol/http/header/vary.rb
|
101
106
|
- lib/protocol/http/headers.rb
|
102
107
|
- lib/protocol/http/methods.rb
|
metadata.gz.sig
CHANGED
Binary file
|
data/agent.md
DELETED
@@ -1,145 +0,0 @@
|
|
1
|
-
# Agent
|
2
|
-
|
3
|
-
## Context
|
4
|
-
|
5
|
-
This section provides links to documentation from installed packages. It is automatically generated and may be updated by running `bake agent:context:install`.
|
6
|
-
|
7
|
-
**Important:** Before performing any code, documentation, or analysis tasks, always read and apply the full content of any relevant documentation referenced in the following sections. These context files contain authoritative standards and best practices for documentation, code style, and project-specific workflows. **Do not proceed with any actions until you have read and incorporated the guidance from relevant context files.**
|
8
|
-
|
9
|
-
**Setup Instructions:** If the referenced files are not present or if dependencies have been updated, run `bake agent:context:install` to install the latest context files.
|
10
|
-
|
11
|
-
### agent-context
|
12
|
-
|
13
|
-
Install and manage context files from Ruby gems.
|
14
|
-
|
15
|
-
#### [Getting Started](.context/agent-context/getting-started.md)
|
16
|
-
|
17
|
-
This guide explains how to use `agent-context`, a tool for discovering and installing contextual information from Ruby gems to help AI agents.
|
18
|
-
|
19
|
-
### async
|
20
|
-
|
21
|
-
A concurrency framework for Ruby.
|
22
|
-
|
23
|
-
#### [Getting Started](.context/async/getting-started.md)
|
24
|
-
|
25
|
-
This guide shows how to add async to your project and run code asynchronously.
|
26
|
-
|
27
|
-
#### [Scheduler](.context/async/scheduler.md)
|
28
|
-
|
29
|
-
This guide gives an overview of how the scheduler is implemented.
|
30
|
-
|
31
|
-
#### [Tasks](.context/async/tasks.md)
|
32
|
-
|
33
|
-
This guide explains how asynchronous tasks work and how to use them.
|
34
|
-
|
35
|
-
#### [Best Practices](.context/async/best-practices.md)
|
36
|
-
|
37
|
-
This guide gives an overview of best practices for using Async.
|
38
|
-
|
39
|
-
#### [Debugging](.context/async/debugging.md)
|
40
|
-
|
41
|
-
This guide explains how to debug issues with programs that use Async.
|
42
|
-
|
43
|
-
#### [Thread safety](.context/async/thread-safety.md)
|
44
|
-
|
45
|
-
This guide explains thread safety in Ruby, focusing on fibers and threads, common pitfalls, and best practices to avoid problems like data corruption, race conditions, and deadlocks.
|
46
|
-
|
47
|
-
### async-service
|
48
|
-
|
49
|
-
A service layer for Async.
|
50
|
-
|
51
|
-
#### [Getting Started](.context/async-service/getting-started.md)
|
52
|
-
|
53
|
-
This guide explains how to get started with `async-service` to create and run services in Ruby.
|
54
|
-
|
55
|
-
#### [Service Architecture](.context/async-service/service-architecture.md)
|
56
|
-
|
57
|
-
This guide explains the key architectural components of `async-service` and how they work together to provide a clean separation of concerns.
|
58
|
-
|
59
|
-
#### [Best Practices](.context/async-service/best-practices.md)
|
60
|
-
|
61
|
-
This guide outlines recommended patterns and practices for building robust, maintainable services with `async-service`.
|
62
|
-
|
63
|
-
### decode
|
64
|
-
|
65
|
-
Code analysis for documentation generation.
|
66
|
-
|
67
|
-
#### [Getting Started with Decode](.context/decode/getting-started.md)
|
68
|
-
|
69
|
-
The Decode gem provides programmatic access to Ruby code structure and metadata. It can parse Ruby files and extract definitions, comments, and documentation pragmas, enabling code analysis, documentation generation, and other programmatic manipulations of Ruby codebases.
|
70
|
-
|
71
|
-
#### [Documentation Coverage](.context/decode/coverage.md)
|
72
|
-
|
73
|
-
This guide explains how to test and monitor documentation coverage in your Ruby projects using the Decode gem's built-in bake tasks.
|
74
|
-
|
75
|
-
#### [Ruby Documentation](.context/decode/ruby-documentation.md)
|
76
|
-
|
77
|
-
This guide covers documentation practices and pragmas supported by the Decode gem for documenting Ruby code. These pragmas provide structured documentation that can be parsed and used to generate API documentation and achieve complete documentation coverage.
|
78
|
-
|
79
|
-
#### [Setting Up RBS Types and Steep Type Checking for Ruby Gems](.context/decode/types.md)
|
80
|
-
|
81
|
-
This guide covers the process for establishing robust type checking in Ruby gems using RBS and Steep, focusing on automated generation from source documentation and proper validation.
|
82
|
-
|
83
|
-
### falcon
|
84
|
-
|
85
|
-
A fast, asynchronous, rack-compatible web server.
|
86
|
-
|
87
|
-
#### [Getting Started](.context/falcon/getting-started.md)
|
88
|
-
|
89
|
-
This guide gives an overview of how to use Falcon for running Ruby web applications.
|
90
|
-
|
91
|
-
#### [Rails Integration](.context/falcon/rails-integration.md)
|
92
|
-
|
93
|
-
This guide explains how to host Rails applications with Falcon.
|
94
|
-
|
95
|
-
#### [Deployment](.context/falcon/deployment.md)
|
96
|
-
|
97
|
-
This guide explains how to deploy applications using the Falcon web server. It covers the recommended deployment methods, configuration options, and examples for different environments, including systemd and kubernetes.
|
98
|
-
|
99
|
-
#### [Performance Tuning](.context/falcon/performance-tuning.md)
|
100
|
-
|
101
|
-
This guide explains the performance characteristics of Falcon.
|
102
|
-
|
103
|
-
#### [WebSockets](.context/falcon/websockets.md)
|
104
|
-
|
105
|
-
This guide explains how to use WebSockets with Falcon.
|
106
|
-
|
107
|
-
#### [Interim Responses](.context/falcon/interim-responses.md)
|
108
|
-
|
109
|
-
This guide explains how to use interim responses in Falcon to send early hints to the client.
|
110
|
-
|
111
|
-
#### [How It Works](.context/falcon/how-it-works.md)
|
112
|
-
|
113
|
-
This guide gives an overview of how Falcon handles an incoming web request.
|
114
|
-
|
115
|
-
### sus
|
116
|
-
|
117
|
-
A fast and scalable test runner.
|
118
|
-
|
119
|
-
#### [Using Sus Testing Framework](.context/sus/usage.md)
|
120
|
-
|
121
|
-
Sus is a modern Ruby testing framework that provides a clean, BDD-style syntax for writing tests. It's designed to be fast, simple, and expressive.
|
122
|
-
|
123
|
-
#### [Mocking](.context/sus/mocking.md)
|
124
|
-
|
125
|
-
There are two types of mocking in sus: `receive` and `mock`. The `receive` matcher is a subset of full mocking and is used to set expectations on method calls, while `mock` can be used to replace method implementations or set up more complex behavior.
|
126
|
-
|
127
|
-
#### [Shared Test Behaviors and Fixtures](.context/sus/shared.md)
|
128
|
-
|
129
|
-
Sus provides shared test contexts which can be used to define common behaviours or tests that can be reused across one or more test files.
|
130
|
-
|
131
|
-
### utopia-project
|
132
|
-
|
133
|
-
A project documentation tool based on Utopia.
|
134
|
-
|
135
|
-
#### [Getting Started](.context/utopia-project/getting-started.md)
|
136
|
-
|
137
|
-
This guide explains how to use `utopia-project` to add documentation to your project.
|
138
|
-
|
139
|
-
#### [Documentation Guides](.context/utopia-project/documentation-guidelines.md)
|
140
|
-
|
141
|
-
This guide explains how to create and maintain documentation for your project using `utopia-project`.
|
142
|
-
|
143
|
-
#### [GitHub Pages Integration](.context/utopia-project/github-pages-integration.md)
|
144
|
-
|
145
|
-
This guide shows you how to use `utopia-project` with GitHub Pages to deploy documentation.
|