awsraw 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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