Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ def write_request(authority, method, target, version, headers)
@stream.write("host: #{authority}\r\n") if authority

write_headers(headers)
rescue
raise ::Protocol::HTTP::RequestRefusedError
end

# Write a response to the connection. It is expected you will write the body after this method.
Expand Down
2 changes: 1 addition & 1 deletion protocol-http1.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ Gem::Specification.new do |spec|

spec.required_ruby_version = ">= 3.3"

spec.add_dependency "protocol-http", "~> 0.58"
spec.add_dependency "protocol-http", "~> 0.61"
end
4 changes: 4 additions & 0 deletions releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Releases

## Unreleased

- `write_request` now raises `Protocol::HTTP::RequestRefusedError` if the request line or headers cannot be written, indicating the request was not processed and can be safely retried.

## v0.37.1

- Defer `body.close` in `write_chunked_body`, `write_fixed_length_body`, and `write_body_and_close` until after the response is fully written and flushed. Previously, `body.each` called `close` in its `ensure` block before the terminal chunk (chunked encoding) or final flush was written, causing `rack.response_finished` callbacks to delay the client-visible response completion.
Expand Down
10 changes: 9 additions & 1 deletion test/protocol/http1/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -699,12 +699,20 @@
expect(client).to be(:closed?)
end

it "raises RequestRefusedError when the stream is broken" do
client.stream.close

expect do
client.write_request("localhost", "GET", "/", "HTTP/1.1", {})
end.to raise_exception(Protocol::HTTP::RequestRefusedError)
end

it "can't write a request in the closed state" do
client.state = :closed

expect do
client.write_request("localhost", "GET", "/", "HTTP/1.0", {})
end.to raise_exception(Protocol::HTTP1::ProtocolError)
end.to raise_exception(Protocol::HTTP::RequestRefusedError)
end

it "can't read a response in the closed state" do
Expand Down
Loading