awsraw 0.1.1 → 0.1.2

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.
data/README.md CHANGED
@@ -31,11 +31,15 @@ s3 = AWSRaw::S3::Client.new(
31
31
  ENV['AWS_ACCESS_KEY_ID'],
32
32
  ENV['AWS_SECRET_ACCESS_KEY'])
33
33
 
34
+ file = File.open("reaction.gif", "rb")
35
+
34
36
  s3.request(:method => "PUT",
35
37
  :bucket => "mah-sekret-buckit",
36
38
  :key => "reaction.gif",
37
- :content => File.read("reaction.gif"),
39
+ :content => file,
38
40
  :headers => { "Content-Type" => "image/gif" })
41
+
42
+ f.close
39
43
  ```
40
44
 
41
45
  Signed query-string requests, to allow authorized clients to get protected
data/awsraw.gemspec CHANGED
@@ -5,8 +5,8 @@ require "awsraw/version"
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "awsraw"
7
7
  s.version = Awsraw::VERSION
8
- s.authors = ["Pete Yandell", "David Goodlad"]
9
- s.email = ["pete@notahat.com", "david@goodlad.net"]
8
+ s.authors = ["Pete Yandell", "David Goodlad", "Jack 'chendo' Chen"]
9
+ s.email = ["pete@notahat.com", "david@goodlad.net", "gems.awsraw@chen.do"]
10
10
  s.license = 'MIT'
11
11
  s.homepage = "http://github.com/envato/awsraw"
12
12
  s.summary = %q{Minimal AWS client}
@@ -1,11 +1,14 @@
1
1
  require 'net/http'
2
2
  require 'awsraw/s3/request'
3
+ require 'awsraw/s3/http_request_builder'
3
4
  require 'awsraw/s3/response'
4
5
  require 'awsraw/s3/signer'
5
-
6
+ require 'awsraw/s3/md5_digester'
6
7
  module AWSRaw
7
8
  module S3
8
9
 
10
+ class ConnectionError < StandardError; end
11
+
9
12
  # A client for the AWS S3 rest API.
10
13
  #
11
14
  # http://docs.amazonwebservices.com/AmazonS3/latest/API/APIRest.html
@@ -19,7 +22,7 @@ module AWSRaw
19
22
  def request(params = {})
20
23
  request = Request.new(params, signer)
21
24
 
22
- http_request = construct_http_request(request)
25
+ http_request = HTTPRequestBuilder.new(request).build
23
26
 
24
27
  http_response = Net::HTTP.start(request.uri.host, request.uri.port) do |http|
25
28
  http.request(http_request)
@@ -30,36 +33,11 @@ module AWSRaw
30
33
 
31
34
  def request!(params = {})
32
35
  response = request(params)
33
- raise "Uh oh! Failure from S3." if response.failure?
36
+ raise ConnectionError, response.inspect if response.failure?
34
37
  end
35
38
 
36
39
  private
37
40
 
38
- def construct_http_request(request)
39
- klass = http_request_class(request)
40
- path = request.uri.request_uri
41
-
42
- klass.new(path).tap do |http_request|
43
- request.headers.each do |name, value|
44
- http_request[name] = value
45
- end
46
- http_request.body = request.content
47
- end
48
- end
49
-
50
- def http_request_class(request)
51
- case request.method
52
- when "GET"
53
- Net::HTTP::Get
54
- when "HEAD"
55
- Net::HTTP::Head
56
- when "PUT"
57
- Net::HTTP::Put
58
- else
59
- raise "Invalid HTTP method!"
60
- end
61
- end
62
-
63
41
  def construct_response(http_response)
64
42
  Response.new(
65
43
  :code => http_response.code,
@@ -0,0 +1,49 @@
1
+ require 'net/http'
2
+ module AWSRaw
3
+ module S3
4
+ class HTTPRequestBuilder
5
+ attr_reader :s3_request
6
+
7
+ def initialize(s3_request)
8
+ @s3_request = s3_request
9
+ end
10
+
11
+ def build
12
+ klass = http_request_class(s3_request)
13
+ path = s3_request.uri.request_uri
14
+
15
+ klass.new(path).tap do |http_request|
16
+ s3_request.headers.each do |name, value|
17
+ http_request[name] = value
18
+ end
19
+ set_content_on_request(http_request, s3_request.content)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def http_request_class(s3_request)
26
+ case s3_request.method
27
+ when "GET"
28
+ Net::HTTP::Get
29
+ when "HEAD"
30
+ Net::HTTP::Head
31
+ when "PUT"
32
+ Net::HTTP::Put
33
+ else
34
+ raise "Invalid HTTP method!"
35
+ end
36
+ end
37
+
38
+ def set_content_on_request(http_request, content)
39
+ if content.is_a?(File)
40
+ http_request.body_stream = content
41
+ http_request['Content-Length'] = content.size.to_s
42
+ else
43
+ http_request.body = content
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,19 @@
1
+ module AWSRaw
2
+ module S3
3
+ class MD5Digester
4
+ def initialize(string_or_file)
5
+ @string_or_file = string_or_file
6
+ end
7
+
8
+ def digest
9
+ if @string_or_file.is_a?(File)
10
+ Digest::MD5.file(@string_or_file.path).digest
11
+ elsif @string_or_file.is_a?(String)
12
+ Digest::MD5.digest(@string_or_file)
13
+ else
14
+ raise "Unable to digest #{@string_or_file.class}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -50,7 +50,7 @@ module AWSRaw
50
50
  end
51
51
 
52
52
  def content_md5
53
- @content_md5 ||= Base64.encode64(Digest::MD5.digest(content)).strip
53
+ @content_md5 ||= Base64.encode64(MD5Digester.new(content).digest).strip
54
54
  end
55
55
  end
56
56
 
@@ -1,3 +1,3 @@
1
1
  module Awsraw
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -4,14 +4,14 @@ describe AWSRaw::S3::Client do
4
4
 
5
5
  subject { AWSRaw::S3::Client.new("dummy_access_key_id", "dummy_secret_access_key") }
6
6
 
7
- context "#request!" do
7
+ describe "#request!" do
8
8
  it "returns if the response indicates success" do
9
9
  response = stub(:failure? => false)
10
10
  subject.stub(:request => response)
11
11
 
12
12
  expect {
13
13
  subject.request!(:method => "PUT")
14
- }.should_not raise_error
14
+ }.to_not raise_error
15
15
  end
16
16
 
17
17
  it "raises an error if the response indicates failure" do
@@ -20,9 +20,8 @@ describe AWSRaw::S3::Client do
20
20
 
21
21
  expect {
22
22
  subject.request!(:method => "PUT")
23
- }.should raise_error("Uh oh! Failure from S3.")
23
+ }.to raise_error(::AWSRaw::S3::ConnectionError)
24
24
  end
25
25
  end
26
-
27
26
  end
28
27
 
@@ -0,0 +1,45 @@
1
+ require 'awsraw/s3/http_request_builder'
2
+
3
+ describe AWSRaw::S3::HTTPRequestBuilder do
4
+ subject do
5
+ AWSRaw::S3::HTTPRequestBuilder.new(s3_request)
6
+ end
7
+
8
+ let(:content) { "hello world" }
9
+ let(:s3_request) do
10
+ stub(
11
+ :uri => URI.parse("http://foo.com/foo"),
12
+ :headers => {"Content-Type" => "application/not-real"},
13
+ :content => content,
14
+ :method => "PUT"
15
+ )
16
+ end
17
+
18
+ context "content is a string" do
19
+ let(:content) { "hello world" }
20
+ it "sets the body on the http request to content" do
21
+ subject.build.body.should == content
22
+ end
23
+ end
24
+
25
+ context "content is a file object" do
26
+ let(:content) { File.open(__FILE__, "rb") }
27
+ it "sets the body on the http request to content" do
28
+ http_request = subject.build
29
+ http_request.body_stream.should == content
30
+ http_request['Content-Length'].should == File.size(__FILE__).to_s
31
+ end
32
+ end
33
+
34
+ it "sets the path on the request" do
35
+ subject.build.path.should == "/foo"
36
+ end
37
+
38
+ it "sets the headers" do
39
+ subject.build["Content-Type"].should == "application/not-real"
40
+ end
41
+
42
+ it "returns the appropriate request class" do
43
+ subject.build.class.should == Net::HTTP::Put
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ require 'awsraw/s3/md5_digester'
3
+
4
+ describe AWSRaw::S3::MD5Digester do
5
+
6
+ describe "#digest" do
7
+ it "returns the md5 digest of the string" do
8
+ AWSRaw::S3::MD5Digester.new("hello").digest.should == Digest::MD5.digest("hello")
9
+ end
10
+
11
+ it "returns the md5 digest of a file" do
12
+ file = File.open(__FILE__, "rb")
13
+ AWSRaw::S3::MD5Digester.new(file).digest.should == Digest::MD5.file(__FILE__).digest
14
+ end
15
+
16
+ it "raises an error on unknown input" do
17
+ expect { AWSRaw::S3::MD5Digester.new(3).digest }.to raise_error("Unable to digest Fixnum")
18
+ end
19
+ end
20
+ end
21
+
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awsraw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Pete Yandell
9
9
  - David Goodlad
10
+ - Jack 'chendo' Chen
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2012-11-25 00:00:00.000000000 Z
14
+ date: 2013-02-08 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: rake
@@ -48,6 +49,7 @@ description: A client for Amazon Web Services in the style of FlickRaw
48
49
  email:
49
50
  - pete@notahat.com
50
51
  - david@goodlad.net
52
+ - gems.awsraw@chen.do
51
53
  executables: []
52
54
  extensions: []
53
55
  extra_rdoc_files: []
@@ -60,12 +62,16 @@ files:
60
62
  - awsraw.gemspec
61
63
  - lib/awsraw.rb
62
64
  - lib/awsraw/s3/client.rb
65
+ - lib/awsraw/s3/http_request_builder.rb
66
+ - lib/awsraw/s3/md5_digester.rb
63
67
  - lib/awsraw/s3/query_string_signer.rb
64
68
  - lib/awsraw/s3/request.rb
65
69
  - lib/awsraw/s3/response.rb
66
70
  - lib/awsraw/s3/signer.rb
67
71
  - lib/awsraw/version.rb
68
72
  - spec/s3/client_spec.rb
73
+ - spec/s3/http_request_builder_spec.rb
74
+ - spec/s3/md5_digester_spec.rb
69
75
  - spec/s3/query_string_signer_spec.rb
70
76
  - spec/s3/signer_spec.rb
71
77
  homepage: http://github.com/envato/awsraw
@@ -81,18 +87,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
87
  - - ! '>='
82
88
  - !ruby/object:Gem::Version
83
89
  version: '0'
84
- segments:
85
- - 0
86
- hash: -2315837560340304412
87
90
  required_rubygems_version: !ruby/object:Gem::Requirement
88
91
  none: false
89
92
  requirements:
90
93
  - - ! '>='
91
94
  - !ruby/object:Gem::Version
92
95
  version: '0'
93
- segments:
94
- - 0
95
- hash: -2315837560340304412
96
96
  requirements: []
97
97
  rubyforge_project: awsraw
98
98
  rubygems_version: 1.8.23
@@ -101,5 +101,7 @@ specification_version: 3
101
101
  summary: Minimal AWS client
102
102
  test_files:
103
103
  - spec/s3/client_spec.rb
104
+ - spec/s3/http_request_builder_spec.rb
105
+ - spec/s3/md5_digester_spec.rb
104
106
  - spec/s3/query_string_signer_spec.rb
105
107
  - spec/s3/signer_spec.rb