Releases
v0.54.0
- Introduce rich support for
Header::Digest
,Header::ServerTiming
,Header::TE
,Header::Trailer
andHeader::TransferEncoding
.
Improved HTTP Trailer Security
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.
- Security-by-default: HTTP trailers are now validated and restricted by default to prevent HTTP request smuggling attacks.
- Only safe headers are permitted in trailers:
date
- Response generation timestamps (safe metadata)digest
- Content integrity verification (safe metadata)etag
- Cache validation tags (safe metadata)server-timing
- Performance metrics (safe metadata)
- All other trailers are ignored by default.
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:
module GRPCStatus
def self.new(value)
Integer(value)
end
def self.trailer?
true
end
end
module GRPCMessage
def self.new(value)
value
end
def self.trailer?
true
end
end
GRPC_POLICY = Protocol::HTTP::Headers::POLICY.dup
GRPC_POLICY['grpc-status'] = GRPCStatus
GRPC_POLICY['grpc-message'] = GRPCMessage
# Reinterpret the headers using the new policy:
response.headers.policy = GRPC_POLICY
response.headers['grpc-status'] # => 0
response.headers['grpc-message'] # => "OK"
v0.53.0
- Improve consistency of Body
#inspect
. - Improve
as_json
support for Body wrappers.
v0.52.0
- Add
Protocol::HTTP::Headers#to_a
method that returns the fields array, providing compatibility with standard Ruby array conversion pattern. - Expose
tail
inHeaders.new
so that trailers can be accurately reproduced. - Add agent context.
v0.51.0
Protocol::HTTP::Headers
now raise aDuplicateHeaderError
when a duplicate singleton header (e.g.content-length
) is added.Protocol::HTTP::Headers#add
now coerces the value to a string when adding a header, ensuring consistent behaviour.Protocol::HTTP::Body::Head.for
now accepts an optionallength
parameter, allowing it to create a head body even when the body is not provided, based on the known content length.
v0.50.0
- Drop support for Ruby v3.1.
v0.48.0
- Add support for parsing
accept
,accept-charset
,accept-encoding
andaccept-language
headers into structured values.
v0.46.0
- Add support for
priority:
header.
v0.33.0
- Clarify behaviour of streaming bodies and copy
Protocol::Rack::Body::Streaming
toProtocol::HTTP::Body::Streamable
. - Copy
Async::HTTP::Body::Writable
toProtocol::HTTP::Body::Writable
.
v0.31.0
- Ensure chunks are flushed if required, when streaming.
v0.30.0
Request[]
and Response[]
Keyword Arguments
The Request[]
and Response[]
methods now support keyword arguments as a convenient way to set various positional arguments.
# Request keyword arguments:
client.get("/", headers: {"accept" => "text/html"}, authority: "example.com")
# Response keyword arguments:
def call(request)
return Response[200, headers: {"content-Type" => "text/html"}, body: "Hello, World!"]
Interim Response Handling
The Request
class now exposes a #interim_response
attribute which can be used to handle interim responses both on the client side and server side.
On the client side, you can pass a callback using the interim_response
keyword argument which will be invoked whenever an interim response is received:
client = ...
response = client.get("/index", interim_response: proc{|status, headers| ...})
On the server side, you can send an interim response using the #send_interim_response
method:
def call(request)
if request.headers["expect"] == "100-continue"
# Send an interim response:
request.send_interim_response(100)
end
# ...
end
v0.29.0
- Introduce
rewind
andrewindable?
methods for body rewinding capabilities. - Add support for output buffer in
read_partial
/readpartial
methods. Reader#buffered!
now returnsself
for method chaining.
v0.28.0
- Add convenient
Reader#buffered!
method to buffer the body. - Modernize gem infrastructure with RuboCop integration.
v0.27.0
- Expand stream interface to support
gets
/puts
operations. - Skip empty key/value pairs in header processing.
- Prefer lowercase method names for consistency.
- Add
as_json
support to avoid default Rails implementation. - Use
@callback
to track invocation state. - Drop
base64
gem dependency.
v0.26.0
- Prefer connection
close
overkeep-alive
when both are present. - Add support for
#readpartial
method. - Add
base64
dependency.
v0.25.0
- Introduce explicit support for informational responses (1xx status codes).
- Add
cache-control
support formust-revalidate
,proxy-revalidate
, ands-maxage
directives. - Add
#strong_match?
and#weak_match?
methods toETags
header. - Fix
last-modified
,if-modified-since
andif-unmodified-since
headers to use properDate
parsing. - Improve date/expires header parsing.
- Add tests for
Stream#close_read
. - Check if input is closed before raising
IOError
. - Ensure saved files truncate existing file by default.
v0.24.0
- Add output stream
#<<
as alias for#write
. - Add support for
Headers#include?
and#key?
methods. - Fix URL unescape functionality.
- Fix cookie parsing issues.
- Fix superclass mismatch in
Protocol::HTTP::Middleware::Builder
. - Allow trailers without explicit
trailer
header. - Fix cookie handling and Ruby 2 keyword arguments.
v0.23.0
- Improve argument handling.
- Rename
path
parameter totarget
to better match RFCs.
v0.22.0
- Rename
trailers
totrailer
for consistency.
v0.21.0
- Streaming interface improvements.
- Rename
Streamable
toCompletable
.
v0.20.0
- Improve
Authorization
header implementation.
v0.19.0
- Expose
Body#ready?
for more efficient response handling.
v0.18.0
- Add
#trailers
method which enumerates trailers without marking tail. - Don't clear trailers in
#dup
, move functionality toflatten!
. - All requests and responses must have mutable headers instance.
v0.17.0
- Remove deferred headers due to complexity.
- Remove deprecated
Headers#slice!
. - Add support for static, dynamic and streaming content to
cache-control
model. - Initial support for trailers.
- Add support for
Response#not_modified?
.
v0.16.0
- Add support for
if-match
andif-none-match
headers. - Revert
Request#target
change for HTTP/2 compatibility.
v0.15.0
- Prefer
Request#target
overRequest#path
. - Add body implementation to support HEAD requests.
- Add support for computing digest on buffered body.
- Add
Headers#set(key, value)
to replace existing values. - Add support for
vary
header. - Add support for
no-cache
&no-store
cache directives.
v0.14.0
- Add
Cacheable
body for buffering and caching responses. - Add support for
cache-control
header.
v0.13.0
- Add support for
connection
header. - Fix handling of keyword arguments.
v0.12.0
- Improved handling of
cookie
header. - Add
Headers#clear
method.
v0.11.0
- Ensure
Body#call
invokesstream.close
when done.
v0.10.0
- Allow user to specify size for character devices.
v0.9.1
- Add support for
authorization
header.
v0.8.0
- Remove
reason
fromResponse
.
v0.7.0
- Explicit path handling in
Reference#with
.
v0.6.0
- Initial version with basic HTTP protocol support.
v0.5.1
- Fix path splitting behavior when path is empty.
- Add
connect
method. - Support protocol in
[]
constructor. - Incorporate middleware functionality.
v0.4.0
- Add
Request
,Response
andBody
classes fromasync-http
. - Allow deletion of non-existent header fields.
v0.3.0
- Initial release of
protocol-http
gem. - Initial implementation of HTTP/2 flow control.
- Support for connection preface and settings frames.
- Initial headers support.
- Implementation of
Connection
,Client
&Server
classes. - HTTP/2 protocol framing and headers.