Skip to content

Commit

Permalink
Merge pull request #80 from dlecocq/master
Browse files Browse the repository at this point in the history
Support for S3::Object#stream
  • Loading branch information
qoobaa committed Oct 29, 2013
2 parents 15ba762 + 4688da0 commit 7659fd6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
18 changes: 14 additions & 4 deletions lib/s3/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ def content(reload = false)
@content
end

# Streams the content of the object without caching it, providing
# successive chunks to the block
def stream(options = {}, &block)
get_object(options, &block)
end

# Saves the object, returns true if successfull.
def save
put_object
Expand Down Expand Up @@ -180,9 +186,9 @@ def copy_object(options = {})
object
end

def get_object(options = {})
def get_object(options = {}, &block)
response = object_request(:get, options)
parse_headers(response)
parse_headers(response, &block)
end

def object_headers(options = {})
Expand Down Expand Up @@ -245,7 +251,7 @@ def dump_headers
headers
end

def parse_headers(response)
def parse_headers(response, &block)
@metadata = response.to_hash.select { |k, v| k.to_s.start_with?("x-amz-meta") }
self.etag = response["etag"] if response.key?("etag")
self.content_type = response["content-type"] if response.key?("content-type")
Expand All @@ -257,7 +263,11 @@ def parse_headers(response)
self.size = response["content-range"].sub(/[^\/]+\//, "").to_i
else
self.size = response["content-length"]
self.content = response.body
if block.nil?
self.content = response.body
else
response.read_body(nil, &block)
end
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions test/object_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def setup
@object_mac.content = "test2"

@response_binary = Net::HTTPOK.new("1.1", "200", "OK")
@response_binary.stubs(:read_body).multiple_yields(*%w{t e s t})
@response_binary.stubs(:body).returns("test".respond_to?(:force_encoding) ? "test".force_encoding(Encoding::BINARY) : "test")
@response_binary["etag"] = ""
@response_binary["content-type"] = "image/png"
Expand Down Expand Up @@ -133,6 +134,21 @@ def setup
assert @object_lena.content(true)
end

test "streaming" do
@object_lena.expects(:object_request).with(:get, {}).returns(@response_binary)

expected = /test/n
io = StringIO.new
@object_lena.stream do |chunk|
io.write(chunk)
end
io.seek(0)
actual = io.read
assert_match expected, actual
assert_equal "image/png", @object_lena.content_type
assert_equal @object.instance_variable_defined?(:@content), false
end

test "retrieve" do
@object_lena.expects(:object_request).with(:head, {}).returns(@response_binary)
assert @object_lena.retrieve
Expand Down
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require "test/unit"
require "stringio"
require "mocha"
require "s3"

0 comments on commit 7659fd6

Please sign in to comment.