uber-s3 0.1.9 → 0.2.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.
- data/README.md +7 -8
- data/lib/uber-s3.rb +2 -2
- data/lib/uber-s3/bucket.rb +9 -5
- data/lib/uber-s3/connection.rb +19 -9
- data/lib/uber-s3/connection/net_http.rb +18 -15
- data/lib/uber-s3/object.rb +3 -2
- data/lib/uber-s3/version.rb +1 -1
- metadata +21 -16
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Uber-S3
|
2
2
|
|
3
|
-
A simple, but very fast, S3 client
|
4
|
-
synchronous and asynchronous
|
3
|
+
A simple, but very fast, S3 client for Ruby supporting
|
4
|
+
synchronous (net-http) and asynchronous (em+fibers) io.
|
5
5
|
|
6
6
|
|
7
7
|
## Examples
|
@@ -16,7 +16,6 @@ s3 = UberS3.new({
|
|
16
16
|
:access_key => 'abc',
|
17
17
|
:secret_access_key => 'def',
|
18
18
|
:bucket => 'funbucket',
|
19
|
-
:persistent => true,
|
20
19
|
:adapter => :em_http_fibered
|
21
20
|
})
|
22
21
|
|
@@ -103,13 +102,13 @@ s3.objects('/path').each {|obj| puts obj }
|
|
103
102
|
|
104
103
|
## Ruby version notes
|
105
104
|
|
106
|
-
* Tested on MRI 1.9.2 (net_http / em_http_fibered adapters)
|
107
|
-
*
|
108
|
-
*
|
105
|
+
* Tested on MRI 1.9.2, MRI 1.9.3 (net_http / em_http_fibered adapters)
|
106
|
+
* Tested on JRuby 1.7-dev in 1.9 mode (net_http)
|
107
|
+
* Ruby 1.8.7 works for net/http clients, em_http_fibered adapter requires fibers
|
109
108
|
|
110
109
|
## Other notes
|
111
110
|
|
112
|
-
* If Nokogiri is available, it will
|
111
|
+
* If Nokogiri is available, it will be automatically used instead of REXML
|
113
112
|
|
114
113
|
## TODO
|
115
114
|
|
@@ -151,4 +150,4 @@ Yea... async adapter dominates. The 100x1KB files were 29x faster to upload, and
|
|
151
150
|
|
152
151
|
## License
|
153
152
|
|
154
|
-
MIT License - Copyright (c)
|
153
|
+
MIT License - Copyright (c) 2012 Nulayer Inc.
|
data/lib/uber-s3.rb
CHANGED
@@ -12,7 +12,7 @@ class UberS3
|
|
12
12
|
extend Forwardable
|
13
13
|
|
14
14
|
attr_accessor :connection, :bucket
|
15
|
-
def_delegators :@bucket, :store, :set, :object, :get, :[], :exists?, :objects
|
15
|
+
def_delegators :@bucket, :store, :set, :object, :get, :head, :[], :exists?, :objects
|
16
16
|
|
17
17
|
def initialize(options={})
|
18
18
|
self.connection = Connection.open(self, options)
|
@@ -24,7 +24,7 @@ class UberS3
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def bucket=(bucket)
|
27
|
-
@bucket = bucket.is_a?(
|
27
|
+
@bucket = bucket.is_a?(String) ? Bucket.new(self, bucket) : bucket
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/lib/uber-s3/bucket.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
class UberS3
|
2
2
|
class Bucket
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :s3, :name
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
self.
|
7
|
-
self.name
|
5
|
+
def initialize(s3, name)
|
6
|
+
self.s3 = s3
|
7
|
+
self.name = name
|
8
8
|
end
|
9
9
|
|
10
10
|
def to_s
|
@@ -12,7 +12,7 @@ class UberS3
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def connection
|
15
|
-
|
15
|
+
s3.connection
|
16
16
|
end
|
17
17
|
|
18
18
|
def store(key, value, options={})
|
@@ -29,6 +29,10 @@ class UberS3
|
|
29
29
|
object(key).fetch
|
30
30
|
end
|
31
31
|
|
32
|
+
def head(key)
|
33
|
+
object(key).head
|
34
|
+
end
|
35
|
+
|
32
36
|
def exists?(key)
|
33
37
|
object(key).exists?
|
34
38
|
end
|
data/lib/uber-s3/connection.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class UberS3
|
2
2
|
module Connection
|
3
3
|
|
4
|
-
def self.open(
|
4
|
+
def self.open(s3, options={})
|
5
5
|
adapter = options.delete(:adapter) || :net_http
|
6
6
|
|
7
7
|
begin
|
@@ -11,19 +11,20 @@ class UberS3
|
|
11
11
|
raise "Cannot load #{adapter} adapter class"
|
12
12
|
end
|
13
13
|
|
14
|
-
klass.new(
|
14
|
+
klass.new(s3, options)
|
15
15
|
end
|
16
16
|
|
17
17
|
|
18
18
|
class Adapter
|
19
19
|
|
20
|
-
attr_accessor :
|
20
|
+
attr_accessor :s3, :http, :uri, :access_key, :secret_access_key, :defaults
|
21
21
|
|
22
|
-
def initialize(
|
23
|
-
self.
|
22
|
+
def initialize(s3, options={})
|
23
|
+
self.s3 = s3
|
24
|
+
self.http = nil
|
25
|
+
self.uri = nil
|
24
26
|
self.access_key = options[:access_key]
|
25
27
|
self.secret_access_key = options[:secret_access_key]
|
26
|
-
self.persistent = (options[:persistent].nil? ? true : options[:persistent])
|
27
28
|
self.defaults = options[:defaults] || {}
|
28
29
|
end
|
29
30
|
|
@@ -36,22 +37,31 @@ class UberS3
|
|
36
37
|
# Default headers
|
37
38
|
headers['Date'] = Time.now.httpdate if !headers.keys.include?('Date')
|
38
39
|
headers['User-Agent'] ||= "UberS3 v#{UberS3::VERSION}"
|
39
|
-
headers['Connection']
|
40
|
+
headers['Connection'] ||= 'keep-alive'
|
40
41
|
|
41
42
|
if body
|
42
43
|
headers['Content-Length'] ||= body.bytesize.to_s
|
43
44
|
end
|
44
45
|
|
45
46
|
# Authorize the request
|
46
|
-
signature = Authorization.sign(
|
47
|
+
signature = Authorization.sign(s3, verb, path, headers)
|
47
48
|
headers['Authorization'] = "AWS #{access_key}:#{signature}"
|
48
49
|
|
49
50
|
# Make the request
|
50
|
-
url = "http://#{
|
51
|
+
url = "http://#{s3.bucket}.s3.amazonaws.com/#{path}"
|
51
52
|
request(verb, url, headers, body)
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
def uri=(uri)
|
57
|
+
# Reset the http connection if the host/port change
|
58
|
+
if !@uri.nil? && !(uri.host == @uri.host && uri.port == @uri.port)
|
59
|
+
self.http = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
@uri = uri
|
63
|
+
end
|
64
|
+
|
55
65
|
def request(verb, url, headers={}, body=nil)
|
56
66
|
raise "Abstract method"
|
57
67
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'net/http'
|
2
|
-
require 'net/http/persistent'
|
3
2
|
|
4
3
|
module UberS3::Connection
|
5
4
|
class NetHttp < Adapter
|
@@ -10,27 +9,31 @@ module UberS3::Connection
|
|
10
9
|
headers['Accept-Encoding'] = 'gzip, deflate'
|
11
10
|
end
|
12
11
|
|
13
|
-
uri = URI.parse(url)
|
12
|
+
self.uri = URI.parse(url)
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
http
|
14
|
+
# Init and open a HTTP connection
|
15
|
+
self.http ||= Net::HTTP.new(uri.host, uri.port)
|
16
|
+
if !http.started? || !http.active?
|
17
|
+
http.start
|
18
|
+
|
19
|
+
if Socket.const_defined?(:TCP_NODELAY)
|
20
|
+
socket = http.instance_variable_get(:@socket)
|
21
|
+
socket.io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
|
22
|
+
end
|
19
23
|
end
|
20
|
-
|
24
|
+
|
21
25
|
req_klass = instance_eval("Net::HTTP::"+verb.to_s.capitalize)
|
22
26
|
req = req_klass.new(uri.to_s, headers)
|
23
27
|
|
24
28
|
req.body = body if !body.nil? && !body.empty?
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
|
30
|
+
# Make HTTP request
|
31
|
+
r = http.request(req)
|
32
|
+
|
33
|
+
# $stderr.puts "active? " + http.active?.to_s
|
34
|
+
|
32
35
|
# Auto-decode any gzipped objects
|
33
|
-
if verb == :get && r.header['
|
36
|
+
if verb == :get && r.header['Content-Encoding'] == 'gzip'
|
34
37
|
gz = Zlib::GzipReader.new(StringIO.new(r.body))
|
35
38
|
response_body = gz.read
|
36
39
|
else
|
data/lib/uber-s3/object.rb
CHANGED
@@ -131,9 +131,10 @@ class UberS3
|
|
131
131
|
def parse_response_header!
|
132
132
|
# Meta..
|
133
133
|
self.meta ||= {}
|
134
|
-
response.header.keys.sort.select {|k| k =~ /^x
|
134
|
+
response.header.keys.sort.select {|k| k =~ /^x.amz.meta./i }.each do |amz_key|
|
135
|
+
|
135
136
|
# TODO.. value is an array.. meaning a meta attribute can have multiple values
|
136
|
-
meta[amz_key.gsub(/^x
|
137
|
+
meta[amz_key.gsub(/^x.amz.meta./i, '')] = [response.header[amz_key]].flatten.first
|
137
138
|
|
138
139
|
# TODO.. em-http adapters return headers that look like X_AMZ_META_ .. very annoying.
|
139
140
|
end
|
data/lib/uber-s3/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uber-s3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mime-types
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,21 +21,15 @@ dependencies:
|
|
21
21
|
version: '1.17'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: net-http-persistent
|
27
|
-
requirement: &70281335650160 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
25
|
none: false
|
29
26
|
requirements:
|
30
27
|
- - ~>
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70281335650160
|
29
|
+
version: '1.17'
|
36
30
|
- !ruby/object:Gem::Dependency
|
37
31
|
name: rake
|
38
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
39
33
|
none: false
|
40
34
|
requirements:
|
41
35
|
- - ! '>='
|
@@ -43,10 +37,15 @@ dependencies:
|
|
43
37
|
version: '0'
|
44
38
|
type: :development
|
45
39
|
prerelease: false
|
46
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
47
46
|
- !ruby/object:Gem::Dependency
|
48
47
|
name: rspec
|
49
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
50
49
|
none: false
|
51
50
|
requirements:
|
52
51
|
- - ~>
|
@@ -54,7 +53,12 @@ dependencies:
|
|
54
53
|
version: 2.7.0
|
55
54
|
type: :development
|
56
55
|
prerelease: false
|
57
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.7.0
|
58
62
|
description: A simple & very fast S3 client supporting sync / async HTTP adapters
|
59
63
|
email:
|
60
64
|
- peter@nulayer.com
|
@@ -104,8 +108,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
108
|
version: 1.3.6
|
105
109
|
requirements: []
|
106
110
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
111
|
+
rubygems_version: 1.8.23
|
108
112
|
signing_key:
|
109
113
|
specification_version: 3
|
110
114
|
summary: A simple & very fast S3 client supporting sync / async HTTP adapters
|
111
115
|
test_files: []
|
116
|
+
has_rdoc:
|