From ddcb2df09a5724577e297542bc2c0291bda3682f Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Mon, 16 Sep 2024 11:28:57 +1200 Subject: [PATCH 1/2] Initial idea. --- lib/protocol/http/body/buffered.rb | 4 ++++ lib/protocol/http/body/readable.rb | 6 ++++++ lib/protocol/http/body/reader.rb | 8 ++++++++ lib/protocol/http/body/wrapper.rb | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/lib/protocol/http/body/buffered.rb b/lib/protocol/http/body/buffered.rb index 088252b..9753a00 100644 --- a/lib/protocol/http/body/buffered.rb +++ b/lib/protocol/http/body/buffered.rb @@ -90,6 +90,10 @@ def read end end + def discard + clear + end + def write(chunk) @chunks << chunk end diff --git a/lib/protocol/http/body/readable.rb b/lib/protocol/http/body/readable.rb index 68e075c..4dc1259 100644 --- a/lib/protocol/http/body/readable.rb +++ b/lib/protocol/http/body/readable.rb @@ -133,6 +133,12 @@ def finish Buffered.read(self) end + def discard + while chunk = self.read + chunk.clear + end + end + def as_json(...) { class: self.class.name, diff --git a/lib/protocol/http/body/reader.rb b/lib/protocol/http/body/reader.rb index 274d6a0..8859db9 100644 --- a/lib/protocol/http/body/reader.rb +++ b/lib/protocol/http/body/reader.rb @@ -40,6 +40,14 @@ def finish end end + # Discard the body as efficiently as possible. + def discard + if body = @body + @body = nil + body.discard + end + end + # Buffer the entire request/response body. # @returns [Reader] itself. def buffered! diff --git a/lib/protocol/http/body/wrapper.rb b/lib/protocol/http/body/wrapper.rb index 7c4189b..f1dd2b7 100644 --- a/lib/protocol/http/body/wrapper.rb +++ b/lib/protocol/http/body/wrapper.rb @@ -59,6 +59,10 @@ def read @body.read end + def discard + @body.discard + end + def as_json(...) { class: self.class.name, From d5de7ae6af01277cd81912ec41244089ea8d0466 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Tue, 17 Sep 2024 14:04:30 +1200 Subject: [PATCH 2/2] Introduce support for discard. --- lib/protocol/http/body/buffered.rb | 4 +++- lib/protocol/http/body/readable.rb | 6 +++++- test/protocol/http/body/buffered.rb | 8 ++++++++ test/protocol/http/body/readable.rb | 7 +++++++ test/protocol/http/body/reader.rb | 7 +++++++ test/protocol/http/body/wrapper.rb | 7 +++++++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/protocol/http/body/buffered.rb b/lib/protocol/http/body/buffered.rb index 9753a00..3f3a07b 100644 --- a/lib/protocol/http/body/buffered.rb +++ b/lib/protocol/http/body/buffered.rb @@ -59,6 +59,8 @@ def finish # Ensure that future reads return nil, but allow for rewinding. def close(error = nil) @index = @chunks.length + + return nil end def clear @@ -91,7 +93,7 @@ def read end def discard - clear + self.close end def write(chunk) diff --git a/lib/protocol/http/body/readable.rb b/lib/protocol/http/body/readable.rb index 4dc1259..ec021ce 100644 --- a/lib/protocol/http/body/readable.rb +++ b/lib/protocol/http/body/readable.rb @@ -133,9 +133,13 @@ def finish Buffered.read(self) end + # Discard the body as efficiently as possible. + # + # The default implementation simply reads all chunks until the body is empty. + # + # Useful for discarding the body when it is not needed, but preserving the underlying connection. def discard while chunk = self.read - chunk.clear end end diff --git a/test/protocol/http/body/buffered.rb b/test/protocol/http/body/buffered.rb index be72de7..b2d8a11 100644 --- a/test/protocol/http/body/buffered.rb +++ b/test/protocol/http/body/buffered.rb @@ -175,4 +175,12 @@ expect(body.inspect).to be =~ /\d+ chunks, \d+ bytes/ end end + + with "#discard" do + it "closes the body" do + expect(body).to receive(:close) + + expect(body.discard).to be == nil + end + end end diff --git a/test/protocol/http/body/readable.rb b/test/protocol/http/body/readable.rb index fadba64..dbca1a6 100644 --- a/test/protocol/http/body/readable.rb +++ b/test/protocol/http/body/readable.rb @@ -58,6 +58,13 @@ end end + with "#discard" do + it "should read all chunks" do + expect(body).to receive(:read).and_return(nil) + expect(body.discard).to be_nil + end + end + with "#as_json" do it "generates a JSON representation" do expect(body.as_json).to have_keys( diff --git a/test/protocol/http/body/reader.rb b/test/protocol/http/body/reader.rb index 49e6038..11eefc9 100644 --- a/test/protocol/http/body/reader.rb +++ b/test/protocol/http/body/reader.rb @@ -29,6 +29,13 @@ def initialize(body) end end + with "#discard" do + it 'discards the body' do + expect(body).to receive(:discard) + expect(reader.discard).to be_nil + end + end + with '#buffered!' do it 'buffers the body' do expect(reader.buffered!).to be_equal(reader) diff --git a/test/protocol/http/body/wrapper.rb b/test/protocol/http/body/wrapper.rb index 991225a..398352f 100644 --- a/test/protocol/http/body/wrapper.rb +++ b/test/protocol/http/body/wrapper.rb @@ -104,4 +104,11 @@ body.call(stream) end end + + with "#discard" do + it "should proxy discard" do + expect(source).to receive(:discard).and_return(nil) + expect(body.discard).to be_nil + end + end end