diff --git a/examples/stream_download.rb b/examples/stream_download.rb index c96ceb3..4dfcf98 100644 --- a/examples/stream_download.rb +++ b/examples/stream_download.rb @@ -9,8 +9,14 @@ url = "https://cdn.kernel.org/pub/linux/kernel/v4.x/#{filename}" File.open(filename, "w") do |file| response = HTTParty.get(url, stream_body: true) do |fragment| - print "." - file.write(fragment) + if [301, 302].include?(fragment.code) + print "skip writing for redirect" + elsif fragment.code == 200 + print "." + file.write(fragment) + else + raise StandardError, "Non-success status code while streaming #{fragment.code}" + end end end puts diff --git a/lib/httparty/fragment_with_response.rb b/lib/httparty/fragment_with_response.rb new file mode 100644 index 0000000..5bfa6ad --- /dev/null +++ b/lib/httparty/fragment_with_response.rb @@ -0,0 +1,20 @@ +require 'delegate' + +module HTTParty + # Allow access to http_response and code by delegation on fragment + class FragmentWithResponse < SimpleDelegator + extend Forwardable + + attr_reader :http_response + + def code + @http_response.code.to_i + end + + def initialize(fragment, http_response) + @fragment = fragment + @http_response = http_response + super fragment + end + end +end diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index ff3ecd0..36aa771 100644 --- a/lib/httparty/request.rb +++ b/lib/httparty/request.rb @@ -1,5 +1,6 @@ require 'erb' require 'httparty/request/body' +require 'httparty/fragment_with_response' module HTTParty class Request #:nodoc: @@ -148,7 +149,7 @@ module HTTParty http_response.read_body do |fragment| chunks << fragment unless options[:stream_body] - block.call(fragment) + block.call FragmentWithResponse.new(fragment, http_response) end chunked_body = chunks.join diff --git a/spec/httparty/fragment_with_response_spec.rb b/spec/httparty/fragment_with_response_spec.rb new file mode 100644 index 0000000..6f3aecf --- /dev/null +++ b/spec/httparty/fragment_with_response_spec.rb @@ -0,0 +1,14 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper')) + +RSpec.describe HTTParty::FragmentWithResponse do + it "access to fragment" do + fragment = HTTParty::FragmentWithResponse.new("chunk", nil) + expect(fragment).to eq("chunk") + end + it "has access to delegators" do + response = double(code: '200') + fragment = HTTParty::FragmentWithResponse.new("chunk", response) + expect(fragment.code).to eq(200) + expect(fragment.http_response).to eq response + end +end diff --git a/spec/httparty_spec.rb b/spec/httparty_spec.rb index 3db9493..2ac1176 100644 --- a/spec/httparty_spec.rb +++ b/spec/httparty_spec.rb @@ -831,6 +831,8 @@ RSpec.describe HTTParty do expect( HTTParty.get('http://www.google.com', options) do |fragment| expect(chunks).to include(fragment) + expect(fragment.code).to eql 200 + expect(fragment.http_response).to be end.parsed_response ).to eq(nil) end