awsraw 0.1.9 → 1.0.0.alpha.1

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.
@@ -1,19 +0,0 @@
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
@@ -1,65 +0,0 @@
1
- require 'digest/md5'
2
- require 'time'
3
- require 'uri'
4
-
5
- module AWSRaw
6
- module S3
7
-
8
- US_STANDARD = "us-east-1"
9
-
10
- # Note that we use path style (rather than virtual hosted style) requests.
11
- # This is because virtual hosted requests only support lower case bucket
12
- # names.
13
- #
14
- # See http://docs.amazonwebservices.com/AmazonS3/latest/dev/VirtualHosting.html
15
- class Request
16
- def initialize(params, signer)
17
- @method = params[:method]
18
- @bucket = params[:bucket]
19
- @region = params[:region]
20
- @key = params[:key]
21
- @query = params[:query]
22
- @headers = params[:headers] || {}
23
- @content = params[:content]
24
-
25
- raise "Content without Content-Type" if !@content.nil? && @headers["Content-Type"].nil?
26
-
27
- headers["Content-MD5"] = content_md5 unless content.nil?
28
- headers["Date"] = Time.now.rfc2822
29
- headers["Authorization"] = signer.signature(self)
30
- end
31
-
32
- attr_reader :method
33
- attr_reader :bucket
34
- attr_reader :key
35
- attr_reader :query
36
- attr_reader :headers
37
- attr_reader :content
38
-
39
- def host
40
- if @region && @region != US_STANDARD
41
- S3.configuration.regional_hosts[@region]
42
- else
43
- S3.configuration.host
44
- end
45
- end
46
-
47
- def path
48
- @path ||= URI.escape("/#{bucket}#{key}")
49
- end
50
-
51
- def uri
52
- @uri ||= URI::HTTP.build(
53
- :host => host,
54
- :path => path,
55
- :query => query
56
- )
57
- end
58
-
59
- def content_md5
60
- @content_md5 ||= Base64.encode64(MD5Digester.new(content).digest).strip
61
- end
62
- end
63
-
64
- end
65
- end
@@ -1,26 +0,0 @@
1
- module AWSRaw
2
- module S3
3
-
4
- class Response
5
- def initialize(params = {})
6
- @code = params[:code]
7
- @headers = params[:headers]
8
- @content = params[:content]
9
- end
10
-
11
- attr_accessor :code
12
- attr_accessor :headers
13
- attr_accessor :content
14
-
15
- def success?
16
- code =~ /^2\d\d$/
17
- end
18
-
19
- def failure?
20
- !success?
21
- end
22
- end
23
-
24
- end
25
- end
26
-
@@ -1,86 +0,0 @@
1
- require 'digest/sha1'
2
- require 'openssl'
3
- require 'uri'
4
- require 'base64'
5
-
6
- module AWSRaw
7
- module S3
8
-
9
- # Generates the Authorization header for a REST request to S3.
10
- #
11
- # See http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html
12
- class Signer
13
- SUBRESOURCES = %w(acl lifecycle location logging notification partNumber policy requestPayment torrent uploadId uploads versionId versioning versions website)
14
-
15
- def initialize(access_key_id, secret_access_key)
16
- @access_key_id = access_key_id
17
- @secret_access_key = secret_access_key
18
- end
19
-
20
- def authorization_header_value(request)
21
- string_to_sign = string_to_sign(request)
22
- signature = encoded_signature(string_to_sign)
23
-
24
- "AWS #{@access_key_id}:#{signature}"
25
- end
26
-
27
- # Backwards compatibility
28
- alias_method :signature, :authorization_header_value
29
-
30
- def encoded_signature(string_to_sign)
31
- digest = OpenSSL::Digest.new("sha1")
32
- sha = OpenSSL::HMAC.digest(digest, @secret_access_key, string_to_sign)
33
- signature = Base64.encode64(sha).strip
34
- end
35
-
36
- def string_to_sign(request)
37
- [
38
- request.method,
39
- request.headers["Content-MD5"] || "",
40
- request.headers["Content-Type"] || "",
41
- request.headers["Date"],
42
- canonicalized_amz_headers(request.headers),
43
- canonicalized_resource(request)
44
- ].flatten.join("\n")
45
- end
46
-
47
- private
48
-
49
- def canonicalized_amz_headers(headers)
50
- header_names = headers.keys.
51
- select {|name| name =~ /^x-amz-/i }.
52
- sort_by {|name| name.downcase }
53
-
54
- header_names.map do |name|
55
- "#{name.downcase}:#{headers[name]}"
56
- end
57
- end
58
-
59
- def canonicalized_resource(request)
60
- if request.host =~ /^(.+)\.s3\.amazonaws\.com/
61
- bucket = request.host.split(/\./).first
62
- resource = '/' + bucket + request.path
63
- else
64
- resource = request.path
65
- end
66
- resource + canonicalized_subresource(request)
67
- end
68
-
69
- def canonicalized_subresource(request)
70
- return "" unless request.query
71
- subresources =
72
- request.query.split('&')
73
- .map { |s| s.split('=') }
74
- .select { |k,v| SUBRESOURCES.include? k }
75
- .map { |k,v| k + (v ? "=#{v}" : "") }
76
- if subresources.any?
77
- "?" + subresources.join("&")
78
- else
79
- ""
80
- end
81
- end
82
-
83
- end
84
-
85
- end
86
- end
@@ -1,27 +0,0 @@
1
- require 'awsraw/s3/client'
2
-
3
- describe AWSRaw::S3::Client do
4
-
5
- subject { AWSRaw::S3::Client.new("dummy_access_key_id", "dummy_secret_access_key") }
6
-
7
- describe "#request!" do
8
- it "returns if the response indicates success" do
9
- response = double(:failure? => false)
10
- subject.stub(:request => response)
11
-
12
- expect {
13
- subject.request!(:method => "PUT")
14
- }.to_not raise_error
15
- end
16
-
17
- it "raises an error if the response indicates failure" do
18
- response = double(:failure? => true)
19
- subject.stub(:request => response)
20
-
21
- expect {
22
- subject.request!(:method => "PUT")
23
- }.to raise_error(::AWSRaw::S3::ConnectionError)
24
- end
25
- end
26
- end
27
-
@@ -1,23 +0,0 @@
1
- require 'awsraw/s3/configuration'
2
-
3
- describe AWSRaw::S3::Configuration do
4
- subject(:configuration) { AWSRaw::S3::Configuration.new }
5
-
6
- it 'has the default S3 host' do
7
- expect(configuration.host).to eq 's3.amazonaws.com'
8
- end
9
-
10
- it 'has the default S3 regional host' do
11
- expect(configuration.regional_hosts['ap-southeast-2']).to eq 's3-ap-southeast-2.amazonaws.com'
12
- end
13
-
14
- describe 'with a custom regional hosts hash' do
15
- before do
16
- configuration.regional_hosts = { 'ap-southeast-2' => 's3.envato.dev' }
17
- end
18
-
19
- it 'returns the custom regional host' do
20
- expect(configuration.regional_hosts['ap-southeast-2']).to eq 's3.envato.dev'
21
- end
22
- end
23
- end
@@ -1,45 +0,0 @@
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
- double(
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
@@ -1,21 +0,0 @@
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
-
@@ -1,23 +0,0 @@
1
- require 'awsraw/s3/client'
2
-
3
- describe AWSRaw::S3::Request do
4
- let(:signer) { double(:signature => "signature") }
5
-
6
- describe "#host" do
7
- it "defaults to the standard host" do
8
- request = described_class.new({}, signer)
9
- request.host.should == "s3.amazonaws.com"
10
- end
11
-
12
- it "ignores the region if it is the standard region" do
13
- request = described_class.new({ :region => "us-east-1" }, signer)
14
- request.host.should == "s3.amazonaws.com"
15
- end
16
-
17
- it "uses the region specific host when a non standard region is supplied" do
18
- request = described_class.new({ :region => "ap-southeast-2" }, signer)
19
- request.host.should == "s3-ap-southeast-2.amazonaws.com"
20
- end
21
- end
22
-
23
- end
@@ -1,75 +0,0 @@
1
- require 'awsraw/s3/signer'
2
-
3
- describe AWSRaw::S3::Signer do
4
- let(:access_key_id) { "AKIAIOSFODNN7EXAMPLE" }
5
- let(:secret_access_key) { "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }
6
-
7
- subject { AWSRaw::S3::Signer.new(access_key_id, secret_access_key) }
8
-
9
- context "examples from Amazon docs" do
10
- context "Example Object GET" do
11
- it "signs a get request correctly" do
12
- request = double(
13
- :method => "GET",
14
- :host => "s3.amazonaws.com",
15
- :path => "/johnsmith/photos/puppy.jpg",
16
- :query => nil,
17
- :headers => { "Date" => "Tue, 27 Mar 2007 19:36:42 +0000" }
18
- )
19
-
20
- subject.string_to_sign(request).should ==
21
- "GET\n\n\nTue, 27 Mar 2007 19:36:42 +0000\n/johnsmith/photos/puppy.jpg"
22
-
23
- subject.signature(request).should == "AWS #{access_key_id}:bWq2s1WEIj+Ydj0vQ697zp+IXMU="
24
- end
25
-
26
- it "signs an upload correctly" do
27
- request = double(
28
- :method => "PUT",
29
- :host => "s3.amazonaws.com",
30
- :path => "/static.johnsmith.net/db-backup.dat.gz",
31
- :query => nil,
32
- :headers => {
33
- "User-Agent" => "curl/7.15.5",
34
- "Date" => "Tue, 27 Mar 2007 21:06:08 +0000",
35
- "x-amz-acl" => "public-read",
36
- "Content-Type" => "application/x-download",
37
- "Content-MD5" => "4gJE4saaMU4BqNR0kLY+lw==",
38
- "X-Amz-Meta-ReviewedBy" => "joe@johnsmith.net,jane@johnsmith.net",
39
- "X-Amz-Meta-FileChecksum" => "0x02661779",
40
- "X-Amz-Meta-ChecksumAlgorithm" => "crc32",
41
- "Content-Disposition" => "attachment; filename=database.dat",
42
- "Content-Encoding" => "gzip",
43
- "Content-Length" => "5913339"
44
- }
45
- )
46
-
47
- subject.string_to_sign(request).should ==
48
- "PUT\n4gJE4saaMU4BqNR0kLY+lw==\napplication/x-download\nTue, 27 Mar 2007 21:06:08 +0000\nx-amz-acl:public-read\nx-amz-meta-checksumalgorithm:crc32\nx-amz-meta-filechecksum:0x02661779\nx-amz-meta-reviewedby:joe@johnsmith.net,jane@johnsmith.net\n/static.johnsmith.net/db-backup.dat.gz"
49
-
50
- subject.signature(request).should == "AWS #{access_key_id}:ilyl83RwaSoYIEdixDQcA4OnAnc="
51
- end
52
- end
53
-
54
- context "Example Fetch" do
55
- let(:request) do
56
- double(
57
- :method => "GET",
58
- :host => "johnsmith.s3.amazonaws.com",
59
- :path => "/",
60
- :query => "acl",
61
- :headers => { "Date" => "Tue, 27 Mar 2007 19:44:46 +0000" }
62
- )
63
- end
64
-
65
- it "generates the correct string to sign" do
66
- subject.string_to_sign(request).should ==
67
- "GET\n\n\nTue, 27 Mar 2007 19:44:46 +0000\n/johnsmith/?acl"
68
- end
69
-
70
- it "signs the request correctly" do
71
- subject.signature(request).should == "AWS #{access_key_id}:c2WLPFtWHVgbEmeEG93a4cG37dM="
72
- end
73
- end
74
- end
75
- end
metadata.gz.sig DELETED
@@ -1 +0,0 @@
1
- ����R�眝RZ��m�E"������x����N�Z���O�S��R���J;/H��_�%"4P�z����@�b嗺N�?,&�H )R��#Y/M[o��S[�="�Ms���9�\0*�H�ɂ2͈��~5v�)7]�“