protocol-http1 0.37.0 → 0.37.1
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/lib/protocol/http1/connection.rb +57 -49
- data/lib/protocol/http1/error.rb +1 -1
- data/lib/protocol/http1/version.rb +2 -2
- data/readme.md +4 -4
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +3 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97a6f38e50bdc78455b7f57895ef25df4dde6492142c2c60c40373b632c3db3b
|
|
4
|
+
data.tar.gz: 0fb9af13fd1beeb21082c7d1860604b1bc947d343598c6347387d99707990894
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3cb82192723452081180be601e36491fe2a5d2b5f05fcc3556080a9311c846bdf2844c499981ac52338170cefdd097584ba8b53c52153af54cc29fbb4a405d9
|
|
7
|
+
data.tar.gz: a4013c3278818c2a632d3f41e46a6625c286f59391990819bda5b29c3c5d4fd82c328acae59107a4abeb5268deebc16bf91e3d3584a3b1be42ab3105a941a352
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2019-
|
|
4
|
+
# Copyright, 2019-2026, by Samuel Williams.
|
|
5
5
|
# Copyright, 2019, by Brian Morearty.
|
|
6
6
|
# Copyright, 2020, by Bruno Sutic.
|
|
7
7
|
# Copyright, 2023-2024, by Thomas Morgan.
|
|
@@ -614,32 +614,34 @@ module Protocol
|
|
|
614
614
|
|
|
615
615
|
if head
|
|
616
616
|
@stream.flush
|
|
617
|
+
else
|
|
618
|
+
@stream.flush unless body.ready?
|
|
617
619
|
|
|
618
|
-
|
|
620
|
+
chunk_length = 0
|
|
621
|
+
# Use a manual read loop (not body.each) so that body.close runs after the response is fully written and flushed. This ensures completion callbacks (e.g. rack.response_finished) don't delay the client.
|
|
622
|
+
while chunk = body.read
|
|
623
|
+
chunk_length += chunk.bytesize
|
|
624
|
+
|
|
625
|
+
if chunk_length > length
|
|
626
|
+
raise ContentLengthError, "Trying to write #{chunk_length} bytes, but content length was #{length} bytes!"
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
@stream.write(chunk)
|
|
630
|
+
@stream.flush unless body.ready?
|
|
631
|
+
end
|
|
619
632
|
|
|
620
|
-
|
|
621
|
-
end
|
|
622
|
-
|
|
623
|
-
@stream.flush unless body.ready?
|
|
624
|
-
|
|
625
|
-
chunk_length = 0
|
|
626
|
-
body.each do |chunk|
|
|
627
|
-
chunk_length += chunk.bytesize
|
|
633
|
+
@stream.flush
|
|
628
634
|
|
|
629
|
-
if chunk_length
|
|
630
|
-
raise ContentLengthError, "
|
|
635
|
+
if chunk_length != length
|
|
636
|
+
raise ContentLengthError, "Wrote #{chunk_length} bytes, but content length was #{length} bytes!"
|
|
631
637
|
end
|
|
632
|
-
|
|
633
|
-
@stream.write(chunk)
|
|
634
|
-
@stream.flush unless body.ready?
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
@stream.flush
|
|
638
|
-
|
|
639
|
-
if chunk_length != length
|
|
640
|
-
raise ContentLengthError, "Wrote #{chunk_length} bytes, but content length was #{length} bytes!"
|
|
641
638
|
end
|
|
639
|
+
rescue => error
|
|
640
|
+
raise
|
|
642
641
|
ensure
|
|
642
|
+
# Close the body after the response is fully flushed, so that completion callbacks run after the client has received the response:
|
|
643
|
+
body.close(error)
|
|
644
|
+
|
|
643
645
|
self.send_end_stream!
|
|
644
646
|
end
|
|
645
647
|
|
|
@@ -657,34 +659,36 @@ module Protocol
|
|
|
657
659
|
|
|
658
660
|
if head
|
|
659
661
|
@stream.flush
|
|
662
|
+
else
|
|
663
|
+
@stream.flush unless body.ready?
|
|
660
664
|
|
|
661
|
-
body.close
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
665
|
+
# Use a manual read loop (not body.each) so that body.close runs after the terminal chunk is written. With body.each, the ensure { close } fires before the terminal "0\r\n\r\n" is sent, delaying the client.
|
|
666
|
+
while chunk = body.read
|
|
667
|
+
next if chunk.size == 0
|
|
668
|
+
|
|
669
|
+
@stream.write("#{chunk.bytesize.to_s(16).upcase}\r\n")
|
|
670
|
+
@stream.write(chunk)
|
|
671
|
+
@stream.write(CRLF)
|
|
672
|
+
|
|
673
|
+
@stream.flush unless body.ready?
|
|
674
|
+
end
|
|
670
675
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
676
|
+
if trailer&.any?
|
|
677
|
+
@stream.write("0\r\n")
|
|
678
|
+
write_headers(trailer)
|
|
679
|
+
@stream.write("\r\n")
|
|
680
|
+
else
|
|
681
|
+
@stream.write("0\r\n\r\n")
|
|
682
|
+
end
|
|
674
683
|
|
|
675
|
-
@stream.flush
|
|
676
|
-
end
|
|
677
|
-
|
|
678
|
-
if trailer&.any?
|
|
679
|
-
@stream.write("0\r\n")
|
|
680
|
-
write_headers(trailer)
|
|
681
|
-
@stream.write("\r\n")
|
|
682
|
-
else
|
|
683
|
-
@stream.write("0\r\n\r\n")
|
|
684
|
+
@stream.flush
|
|
684
685
|
end
|
|
685
|
-
|
|
686
|
-
|
|
686
|
+
rescue => error
|
|
687
|
+
raise
|
|
687
688
|
ensure
|
|
689
|
+
# Close the body after the complete chunked response (including terminal chunk) is flushed, so that completion callbacks don't block the client from seeing the response as complete:
|
|
690
|
+
body.close(error)
|
|
691
|
+
|
|
688
692
|
self.send_end_stream!
|
|
689
693
|
end
|
|
690
694
|
|
|
@@ -697,12 +701,11 @@ module Protocol
|
|
|
697
701
|
@persistent = false
|
|
698
702
|
|
|
699
703
|
@stream.write("\r\n")
|
|
700
|
-
@stream.flush unless body.ready?
|
|
701
704
|
|
|
702
|
-
|
|
703
|
-
body.
|
|
704
|
-
|
|
705
|
-
body.
|
|
705
|
+
unless head
|
|
706
|
+
@stream.flush unless body.ready?
|
|
707
|
+
|
|
708
|
+
while chunk = body.read
|
|
706
709
|
@stream.write(chunk)
|
|
707
710
|
|
|
708
711
|
@stream.flush unless body.ready?
|
|
@@ -711,7 +714,12 @@ module Protocol
|
|
|
711
714
|
|
|
712
715
|
@stream.flush
|
|
713
716
|
@stream.close_write
|
|
717
|
+
rescue => error
|
|
718
|
+
raise
|
|
714
719
|
ensure
|
|
720
|
+
# Close the body after the stream is fully written and half-closed, so that completion callbacks run after the client has received the full response:
|
|
721
|
+
body.close(error)
|
|
722
|
+
|
|
715
723
|
self.send_end_stream!
|
|
716
724
|
end
|
|
717
725
|
|
data/lib/protocol/http1/error.rb
CHANGED
data/readme.md
CHANGED
|
@@ -30,6 +30,10 @@ Please see the [project documentation](https://socketry.github.io/protocol-http1
|
|
|
30
30
|
|
|
31
31
|
Please see the [project releases](https://socketry.github.io/protocol-http1/releases/index) for all releases.
|
|
32
32
|
|
|
33
|
+
### v0.37.1
|
|
34
|
+
|
|
35
|
+
- 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.
|
|
36
|
+
|
|
33
37
|
### v0.37.0
|
|
34
38
|
|
|
35
39
|
- `Protocol::HTTP1::BadRequest` now includes `Protocol::HTTP::BadRequest` for better interoperability and handling of bad request errors across different HTTP protocol implementations.
|
|
@@ -69,10 +73,6 @@ Please see the [project releases](https://socketry.github.io/protocol-http1/rele
|
|
|
69
73
|
|
|
70
74
|
- Enforce one-way transition for persistent connections to prevent invalid state changes.
|
|
71
75
|
|
|
72
|
-
### v0.30.0
|
|
73
|
-
|
|
74
|
-
- Make `authority` header optional in HTTP requests for improved flexibility.
|
|
75
|
-
|
|
76
76
|
## Contributing
|
|
77
77
|
|
|
78
78
|
We welcome contributions to this project.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.37.1
|
|
4
|
+
|
|
5
|
+
- 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.
|
|
6
|
+
|
|
3
7
|
## v0.37.0
|
|
4
8
|
|
|
5
9
|
- `Protocol::HTTP1::BadRequest` now includes `Protocol::HTTP::BadRequest` for better interoperability and handling of bad request errors across different HTTP protocol implementations.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: protocol-http1
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.37.
|
|
4
|
+
version: 0.37.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -90,14 +90,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
90
90
|
requirements:
|
|
91
91
|
- - ">="
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
|
-
version: '3.
|
|
93
|
+
version: '3.3'
|
|
94
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
|
96
96
|
- - ">="
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '0'
|
|
99
99
|
requirements: []
|
|
100
|
-
rubygems_version: 4.0.
|
|
100
|
+
rubygems_version: 4.0.6
|
|
101
101
|
specification_version: 4
|
|
102
102
|
summary: A low level implementation of the HTTP/1 protocol.
|
|
103
103
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|