uber-s3 0.1.9 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Uber-S3
2
2
 
3
- A simple, but very fast, S3 client written in Ruby supporting
4
- synchronous and asynchronous HTTP communication.
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) -- recommended
107
- * Ruby 1.8.7 works for net/http clients, em_http_fibered adapter requires fibers (duh)
108
- * JRuby in 1.9 mode + em_http_fibered adapter should work, but held back because of issues with EM
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 use it instead of REXML
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) 2011 Nulayer Inc.
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?(Bucket) ? bucket : Bucket.new(self, bucket)
27
+ @bucket = bucket.is_a?(String) ? Bucket.new(self, bucket) : bucket
28
28
  end
29
29
  end
30
30
 
@@ -1,10 +1,10 @@
1
1
  class UberS3
2
2
  class Bucket
3
- attr_accessor :client, :name
3
+ attr_accessor :s3, :name
4
4
 
5
- def initialize(client, name)
6
- self.client = client
7
- self.name = 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
- client.connection
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
@@ -1,7 +1,7 @@
1
1
  class UberS3
2
2
  module Connection
3
3
 
4
- def self.open(client, options={})
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(client, options)
14
+ klass.new(s3, options)
15
15
  end
16
16
 
17
17
 
18
18
  class Adapter
19
19
 
20
- attr_accessor :client, :access_key, :secret_access_key, :persistent, :defaults
20
+ attr_accessor :s3, :http, :uri, :access_key, :secret_access_key, :defaults
21
21
 
22
- def initialize(client, options={})
23
- self.client = client
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'] = (persistent ? 'keep-alive' : 'close')
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(client, verb, path, headers)
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://#{client.bucket}.s3.amazonaws.com/#{path}"
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
- if persistent
16
- http = Net::HTTP::Persistent.new("#{access_key}:#{client.bucket}")
17
- else
18
- http = Net::HTTP.new(uri.host, uri.port)
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
- if persistent
27
- r = http.request(uri, req)
28
- else
29
- r = http.request(req)
30
- end
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['content-encoding'] == 'gzip'
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
@@ -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-amz-meta-/ }.each do |amz_key|
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-amz-meta-/, '')] = response.header[amz_key].first
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
@@ -1,3 +1,3 @@
1
1
  class UberS3
2
- VERSION = '0.1.9'
2
+ VERSION = '0.2.1'
3
3
  end
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.9
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-03-21 00:00:00.000000000 Z
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: &70281335651220 !ruby/object:Gem::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: *70281335651220
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: '2.5'
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: &70281335649600 !ruby/object:Gem::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: *70281335649600
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: &70281335648100 !ruby/object:Gem::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: *70281335648100
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.17
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: