carrierwave-aws 0.4.1 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.env.sample +1 -0
- data/CHANGELOG.md +8 -0
- data/README.md +20 -3
- data/carrierwave-aws.gemspec +3 -3
- data/lib/carrierwave-aws.rb +1 -0
- data/lib/carrierwave/aws/version.rb +1 -1
- data/lib/carrierwave/storage/aws.rb +5 -99
- data/lib/carrierwave/storage/aws_file.rb +116 -0
- data/spec/carrierwave-aws_spec.rb +2 -2
- data/spec/carrierwave/storage/aws_file_spec.rb +135 -0
- data/spec/carrierwave/storage/aws_spec.rb +7 -106
- data/spec/features/copying_files_spec.rb +33 -0
- data/spec/features/querying_files_spec.rb +48 -0
- data/spec/features/storing_files_spec.rb +12 -24
- data/spec/spec_helper.rb +27 -4
- metadata +18 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbc243216be54ab5f7e5ab0adeda6c6d61beea1e
|
4
|
+
data.tar.gz: ce824a3dbf900b615bfc58c1bb0ebbc6b92d9b6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bc524f441434927eeed0303ddc4001afbe9d347c25e92fb319ad67545810b62d6e5c4efd4a6782d55253f97c3bfaf85ac43a5e7e7cf30f0382e54357b8dc1da
|
7
|
+
data.tar.gz: d23855a85418360efe6cfcfd837c0cd1668c2bd7299ba65b68885f7099c873fd6c2e11054b5f303f9f5fa602aa09f45302953c6776b838a9369b4fb68865daed
|
data/.env.sample
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## Version 0.5.0 2015-01-31
|
2
|
+
|
3
|
+
* Change: Nudge the expected AWS-SDK version.
|
4
|
+
* Fix `exists?` method of AWS::File (previously it always returned true)
|
5
|
+
[Felix Bünemann]
|
6
|
+
* Fix `filename` method of AWS::File for private files and remove url encoding.
|
7
|
+
[Felix Bünemann]
|
8
|
+
|
1
9
|
## Version 0.4.1 2014-03-28
|
2
10
|
|
3
11
|
* Fix regression in `aws_read_options` defaulting to `nil` rather than an empty
|
data/README.md
CHANGED
@@ -37,14 +37,14 @@ the use of `aws_bucket` instead of `fog_directory`, and `aws_acl` instead of
|
|
37
37
|
```ruby
|
38
38
|
CarrierWave.configure do |config|
|
39
39
|
config.storage = :aws
|
40
|
-
config.aws_bucket = ENV
|
40
|
+
config.aws_bucket = ENV.fetch('S3_BUCKET_NAME')
|
41
41
|
config.aws_acl = :public_read
|
42
42
|
config.asset_host = 'http://example.com'
|
43
43
|
config.aws_authenticated_url_expiration = 60 * 60 * 24 * 365
|
44
44
|
|
45
45
|
config.aws_credentials = {
|
46
|
-
access_key_id: ENV
|
47
|
-
secret_access_key: ENV
|
46
|
+
access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
|
47
|
+
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')
|
48
48
|
}
|
49
49
|
end
|
50
50
|
```
|
@@ -65,6 +65,23 @@ through `aws-sdk` gem. Browse [Amazon docs](http://docs.aws.amazon.com/AWSRubySD
|
|
65
65
|
for additional info. For example, if you want to turn off SSL for your asset
|
66
66
|
URLs, you could simply set `AWS.config(use_ssl: false)`.
|
67
67
|
|
68
|
+
### Custom options for AWS URLs
|
69
|
+
|
70
|
+
If you have a custom uploader that specifies additional headers for each URL, please try the following example:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class MyUploader < Carrierwave::Uploader::Base
|
74
|
+
# You can find full list of custom headers in AWS SDK documentation on
|
75
|
+
# AWS::S3::S3Object
|
76
|
+
def download_url(filename)
|
77
|
+
url(response_content_disposition: %Q{attachment; filename="#{filename}"})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
If you migrate from `fog` you probably have something like `url(query: {'my-header': 'my-value'})`.
|
83
|
+
With `carrierwave-aws` the `query` part becomes obsolete, just use a hash of headers.
|
84
|
+
|
68
85
|
## Contributing
|
69
86
|
|
70
87
|
In order to run the integration specs you will need to configure some
|
data/carrierwave-aws.gemspec
CHANGED
@@ -16,8 +16,8 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.test_files = gem.files.grep(%r{^(spec)/})
|
17
17
|
gem.require_paths = ['lib']
|
18
18
|
|
19
|
-
gem.add_dependency 'carrierwave', '
|
20
|
-
gem.add_dependency 'aws-sdk', '
|
19
|
+
gem.add_dependency 'carrierwave', '~> 0.7'
|
20
|
+
gem.add_dependency 'aws-sdk', '~> 1.58'
|
21
21
|
|
22
|
-
gem.add_development_dependency 'rspec', '~>
|
22
|
+
gem.add_development_dependency 'rspec', '~> 3'
|
23
23
|
end
|
data/lib/carrierwave-aws.rb
CHANGED
@@ -12,117 +12,23 @@ module CarrierWave
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def store!(file)
|
15
|
-
|
15
|
+
AWSFile.new(uploader, connection, uploader.store_path).tap do |aws_file|
|
16
16
|
aws_file.store(file)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def retrieve!(identifier)
|
21
|
-
|
21
|
+
AWSFile.new(uploader, connection, uploader.store_path(identifier))
|
22
22
|
end
|
23
23
|
|
24
24
|
def connection
|
25
25
|
@connection ||= begin
|
26
|
-
credentials
|
27
|
-
self.class.connection_cache[credentials] ||= ::AWS::S3.new(credentials)
|
26
|
+
self.class.connection_cache[credentials] ||= ::AWS::S3.new(*credentials)
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
attr_reader :uploader, :connection, :path
|
34
|
-
|
35
|
-
def initialize(uploader, connection, path)
|
36
|
-
@uploader = uploader
|
37
|
-
@connection = connection
|
38
|
-
@path = path
|
39
|
-
end
|
40
|
-
|
41
|
-
def attributes
|
42
|
-
file.attributes
|
43
|
-
end
|
44
|
-
|
45
|
-
def content_type
|
46
|
-
@content_type || file.content_type
|
47
|
-
end
|
48
|
-
|
49
|
-
def delete
|
50
|
-
file.delete
|
51
|
-
end
|
52
|
-
|
53
|
-
def extension
|
54
|
-
path.split('.').last
|
55
|
-
end
|
56
|
-
|
57
|
-
def exists?
|
58
|
-
!!file
|
59
|
-
end
|
60
|
-
|
61
|
-
def filename(options = {})
|
62
|
-
if file_url = url(options)
|
63
|
-
file_url.gsub(/.*\/(.*?$)/, '\1')
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def read
|
68
|
-
file.read(uploader_read_options)
|
69
|
-
end
|
70
|
-
|
71
|
-
def size
|
72
|
-
file.content_length
|
73
|
-
end
|
74
|
-
|
75
|
-
def store(new_file)
|
76
|
-
@file = bucket.objects[path].write(uploader_write_options(new_file))
|
77
|
-
|
78
|
-
true
|
79
|
-
end
|
80
|
-
|
81
|
-
def to_file
|
82
|
-
file
|
83
|
-
end
|
84
|
-
|
85
|
-
def url(options = {})
|
86
|
-
if uploader.aws_acl != :public_read
|
87
|
-
authenticated_url(options)
|
88
|
-
else
|
89
|
-
public_url
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def authenticated_url(options = {})
|
94
|
-
file.url_for(:read, { expires: uploader.aws_authenticated_url_expiration }.merge(options)).to_s
|
95
|
-
end
|
96
|
-
|
97
|
-
def public_url
|
98
|
-
if uploader.asset_host
|
99
|
-
"#{uploader.asset_host}/#{path}"
|
100
|
-
else
|
101
|
-
file.public_url.to_s
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def uploader_read_options
|
106
|
-
uploader.aws_read_options || {}
|
107
|
-
end
|
108
|
-
|
109
|
-
def uploader_write_options(new_file)
|
110
|
-
{
|
111
|
-
acl: uploader.aws_acl,
|
112
|
-
content_type: new_file.content_type,
|
113
|
-
file: new_file.path
|
114
|
-
}.merge(uploader.aws_attributes || {}).merge(uploader.aws_write_options || {})
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def bucket
|
120
|
-
@bucket ||= connection.buckets[uploader.aws_bucket]
|
121
|
-
end
|
122
|
-
|
123
|
-
def file
|
124
|
-
@file ||= bucket.objects[path]
|
125
|
-
end
|
30
|
+
def credentials
|
31
|
+
[uploader.aws_credentials].compact
|
126
32
|
end
|
127
33
|
end
|
128
34
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Storage
|
3
|
+
class AWSFile
|
4
|
+
attr_writer :content_type
|
5
|
+
attr_reader :uploader, :connection, :path
|
6
|
+
|
7
|
+
def initialize(uploader, connection, path)
|
8
|
+
@uploader = uploader
|
9
|
+
@connection = connection
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes
|
14
|
+
file.head.data
|
15
|
+
end
|
16
|
+
|
17
|
+
def content_type
|
18
|
+
@content_type || file.content_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete
|
22
|
+
file.delete
|
23
|
+
end
|
24
|
+
|
25
|
+
def extension
|
26
|
+
path.split('.').last
|
27
|
+
end
|
28
|
+
|
29
|
+
def exists?
|
30
|
+
file.exists?
|
31
|
+
end
|
32
|
+
|
33
|
+
def filename(options = {})
|
34
|
+
if file_url = url(options)
|
35
|
+
URI.decode(file_url.split('?').first).gsub(/.*\/(.*?$)/, '\1')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def read
|
40
|
+
file.read(uploader_read_options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def size
|
44
|
+
file.content_length
|
45
|
+
end
|
46
|
+
|
47
|
+
def store(new_file)
|
48
|
+
@file = bucket.objects[path].write(uploader_write_options(new_file))
|
49
|
+
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_file
|
54
|
+
file
|
55
|
+
end
|
56
|
+
|
57
|
+
def url(options = {})
|
58
|
+
if uploader.aws_acl != :public_read
|
59
|
+
authenticated_url(options)
|
60
|
+
else
|
61
|
+
public_url
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def authenticated_url(options = {})
|
66
|
+
file.url_for(:read, { expires: uploader.aws_authenticated_url_expiration }.merge(options)).to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
def public_url
|
70
|
+
if uploader.asset_host
|
71
|
+
"#{uploader.asset_host}/#{path}"
|
72
|
+
else
|
73
|
+
file.public_url.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def copy_to(new_path)
|
78
|
+
file.copy_to(bucket.objects[new_path], uploader_copy_options)
|
79
|
+
end
|
80
|
+
|
81
|
+
def uploader_read_options
|
82
|
+
uploader.aws_read_options || {}
|
83
|
+
end
|
84
|
+
|
85
|
+
def uploader_write_options(new_file)
|
86
|
+
aws_attributes = uploader.aws_attributes || {}
|
87
|
+
aws_write_options = uploader.aws_write_options || {}
|
88
|
+
|
89
|
+
{ acl: uploader.aws_acl,
|
90
|
+
content_type: new_file.content_type,
|
91
|
+
file: new_file.path
|
92
|
+
}.merge(aws_attributes).merge(aws_write_options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def uploader_copy_options
|
96
|
+
aws_write_options = uploader.aws_write_options || {}
|
97
|
+
|
98
|
+
storage_options = aws_write_options.select do |key,_|
|
99
|
+
[:reduced_redundancy, :storage_class, :server_side_encryption].include?(key)
|
100
|
+
end
|
101
|
+
|
102
|
+
{ acl: uploader.aws_acl }.merge(storage_options)
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def bucket
|
108
|
+
@bucket ||= connection.buckets[uploader.aws_bucket]
|
109
|
+
end
|
110
|
+
|
111
|
+
def file
|
112
|
+
@file ||= bucket.objects[path]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -2,12 +2,12 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe CarrierWave::Uploader::Base do
|
4
4
|
it 'defines aws specific storage options' do
|
5
|
-
described_class.
|
5
|
+
expect(described_class).to respond_to(:aws_attributes)
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'inserts aws as a known storage engine' do
|
9
9
|
described_class.configure do |config|
|
10
|
-
config.storage_engines.
|
10
|
+
expect(config.storage_engines).to have_key(:aws)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CarrierWave::Storage::AWSFile do
|
4
|
+
let(:objects) { { 'files/1/file.txt' => file } }
|
5
|
+
let(:path) { 'files/1/file.txt' }
|
6
|
+
let(:bucket) { double(:bucket, objects: objects) }
|
7
|
+
let(:connection) { double(:connection, buckets: { 'example-com' => bucket }) }
|
8
|
+
let(:file) { double(:file, read: '0101010', content_type: 'content/type', path: '/file/path') }
|
9
|
+
|
10
|
+
let(:uploader) do
|
11
|
+
double(:uploader,
|
12
|
+
aws_bucket: 'example-com',
|
13
|
+
aws_acl: :public_read,
|
14
|
+
aws_attributes: {},
|
15
|
+
asset_host: nil,
|
16
|
+
aws_read_options: { encryption_key: 'abc' },
|
17
|
+
aws_write_options: { encryption_key: 'def' }
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
subject(:aws_file) do
|
22
|
+
CarrierWave::Storage::AWSFile.new(uploader, connection, path)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#exists?' do
|
26
|
+
it 'checks if the remote file object exists' do
|
27
|
+
expect(file).to receive(:exists?).and_return(true)
|
28
|
+
|
29
|
+
aws_file.exists?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#read' do
|
34
|
+
it 'reads from the remote file object' do
|
35
|
+
expect(aws_file.read).to eq('0101010')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#uploader_write_options' do
|
40
|
+
it 'includes acl, content_type, file, aws_attributes, and aws_write_options' do
|
41
|
+
expect(aws_file.uploader_write_options(file)).to eq(
|
42
|
+
acl: :public_read,
|
43
|
+
content_type: 'content/type',
|
44
|
+
file: '/file/path',
|
45
|
+
encryption_key: 'def'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'works if aws_attributes is nil' do
|
50
|
+
allow(uploader).to receive(:aws_attributes) { nil }
|
51
|
+
|
52
|
+
expect {
|
53
|
+
aws_file.uploader_write_options(file)
|
54
|
+
}.to_not raise_error
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'works if aws_write_options is nil' do
|
58
|
+
allow(uploader).to receive(:aws_write_options) { nil }
|
59
|
+
|
60
|
+
expect {
|
61
|
+
aws_file.uploader_write_options(file)
|
62
|
+
}.to_not raise_error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#uploader_read_options' do
|
67
|
+
it 'includes aws_read_options' do
|
68
|
+
expect(aws_file.uploader_read_options).to eq(encryption_key: 'abc')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'ensures that read options are a hash' do
|
72
|
+
allow(uploader).to receive(:aws_read_options) { nil }
|
73
|
+
|
74
|
+
expect(aws_file.uploader_read_options).to eq({})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#to_file' do
|
79
|
+
it 'returns the internal file instance' do
|
80
|
+
expect(aws_file.to_file).to be(file)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#authenticated_url' do
|
85
|
+
it 'requests a url for reading with the configured expiration' do
|
86
|
+
allow(uploader).to receive(:aws_authenticated_url_expiration) { 60 }
|
87
|
+
|
88
|
+
expect(file).to receive(:url_for).with(:read, expires: 60)
|
89
|
+
|
90
|
+
aws_file.authenticated_url
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'requests a url for reading with custom options' do
|
94
|
+
allow(uploader).to receive(:aws_authenticated_url_expiration) { 60 }
|
95
|
+
|
96
|
+
expect(file).to receive(:url_for).with(:read, hash_including(response_content_disposition: 'attachment'))
|
97
|
+
|
98
|
+
aws_file.authenticated_url(response_content_disposition: 'attachment')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#url' do
|
103
|
+
it 'requests a public url if acl is public readable' do
|
104
|
+
allow(uploader).to receive(:aws_acl) { :public_read }
|
105
|
+
|
106
|
+
expect(file).to receive(:public_url)
|
107
|
+
|
108
|
+
aws_file.url
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'requests an authenticated url if acl is not public readable' do
|
112
|
+
allow(uploader).to receive(:aws_acl) { :private }
|
113
|
+
allow(uploader).to receive(:aws_authenticated_url_expiration) { 60 }
|
114
|
+
|
115
|
+
expect(file).to receive(:url_for)
|
116
|
+
|
117
|
+
aws_file.url
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'uses the asset_host and file path if asset_host is set' do
|
121
|
+
allow(uploader).to receive(:aws_acl) { :public_read }
|
122
|
+
allow(uploader).to receive(:asset_host) { 'http://example.com' }
|
123
|
+
|
124
|
+
expect(aws_file.url).to eq('http://example.com/files/1/file.txt')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#filename' do
|
129
|
+
it 'returns the filename from the url' do
|
130
|
+
expect(aws_file).to receive(:url).and_return('http://example.com/files/1/file%201.txt?foo=bar/baz.txt')
|
131
|
+
|
132
|
+
expect(aws_file.filename).to eq('file 1.txt')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -13,119 +13,20 @@ describe CarrierWave::Storage::AWS do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#connection' do
|
16
|
-
it 'instantiates a new connection' do
|
17
|
-
AWS::S3.
|
16
|
+
it 'instantiates a new connection with credentials' do
|
17
|
+
expect(AWS::S3).to receive(:new).with(credentials)
|
18
18
|
|
19
19
|
storage.connection
|
20
20
|
end
|
21
21
|
|
22
|
-
it '
|
23
|
-
|
24
|
-
|
25
|
-
storage.connection.should === storage.connection
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe CarrierWave::Storage::AWS::File do
|
31
|
-
let(:objects) { { 'files/1/file.txt' => file } }
|
32
|
-
let(:bucket) { double(:bucket, objects: objects) }
|
33
|
-
let(:connection) { double(:connection, buckets: { 'example-com' => bucket }) }
|
34
|
-
let(:file) { double(:file, read: '0101010', content_type: 'content/type', path: '/file/path') }
|
35
|
-
let(:uploader) { double(:uploader, aws_bucket: 'example-com', aws_acl: :public_read, aws_attributes: {}, asset_host: nil, aws_read_options: { encryption_key: 'abc' }, aws_write_options: { encryption_key: 'def' }) }
|
36
|
-
let(:path) { 'files/1/file.txt' }
|
37
|
-
|
38
|
-
subject(:aws_file) do
|
39
|
-
CarrierWave::Storage::AWS::File.new(uploader, connection, path)
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#read' do
|
43
|
-
it 'reads from the remote file object' do
|
44
|
-
aws_file.read.should == '0101010'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#uploader_write_options' do
|
49
|
-
it 'includes acl, content_type, file, aws_attributes, and aws_write_options' do
|
50
|
-
aws_file.uploader_write_options(file).should == {
|
51
|
-
acl: :public_read,
|
52
|
-
content_type: 'content/type',
|
53
|
-
file: '/file/path',
|
54
|
-
encryption_key: 'def'
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'works if aws_attributes is nil' do
|
59
|
-
uploader.stub(:aws_attributes) { nil }
|
60
|
-
expect {
|
61
|
-
aws_file.uploader_write_options(file)
|
62
|
-
}.to_not raise_error
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'works if aws_write_options is nil' do
|
66
|
-
uploader.stub(:aws_write_options) { nil }
|
67
|
-
expect {
|
68
|
-
aws_file.uploader_write_options(file)
|
69
|
-
}.to_not raise_error
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#uploader_read_options' do
|
74
|
-
it 'includes aws_read_options' do
|
75
|
-
aws_file.uploader_read_options.should == { encryption_key: 'abc' }
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'ensures that read options are a hash' do
|
79
|
-
uploader.stub(:aws_read_options) { nil }
|
80
|
-
aws_file.uploader_read_options.should == {}
|
81
|
-
end
|
82
|
-
end
|
22
|
+
it 'instantiates a new connection without any credentials' do
|
23
|
+
allow(uploader).to receive(:aws_credentials) { nil }
|
83
24
|
|
84
|
-
|
85
|
-
it 'returns the internal file instance' do
|
86
|
-
aws_file.to_file.should be(file)
|
25
|
+
expect { storage.connection }.not_to raise_exception
|
87
26
|
end
|
88
|
-
end
|
89
27
|
|
90
|
-
|
91
|
-
|
92
|
-
uploader.stub(aws_authenticated_url_expiration: 60)
|
93
|
-
|
94
|
-
file.should_receive(:url_for).with(:read, expires: 60)
|
95
|
-
|
96
|
-
aws_file.authenticated_url
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'requests a url for reading with custom options' do
|
100
|
-
uploader.stub(aws_authenticated_url_expiration: 60)
|
101
|
-
|
102
|
-
file.should_receive(:url_for).with(:read, hash_including(response_content_disposition: 'attachment'))
|
103
|
-
|
104
|
-
aws_file.authenticated_url(response_content_disposition: 'attachment')
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe '#url' do
|
109
|
-
it 'requests a public url if acl is public readable' do
|
110
|
-
uploader.stub(aws_acl: :public_read)
|
111
|
-
file.should_receive(:public_url)
|
112
|
-
|
113
|
-
aws_file.url
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'requests an authenticated url if acl is not public readable' do
|
117
|
-
uploader.stub(aws_acl: :private, aws_authenticated_url_expiration: 60)
|
118
|
-
|
119
|
-
file.should_receive(:url_for)
|
120
|
-
|
121
|
-
aws_file.url
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'uses the asset_host and file path if asset_host is set' do
|
125
|
-
uploader.stub(aws_acl: :public_read)
|
126
|
-
uploader.stub(asset_host: 'http://example.com')
|
127
|
-
|
128
|
-
aws_file.url.should eql 'http://example.com/files/1/file.txt'
|
28
|
+
it 'caches connections by credentials' do
|
29
|
+
expect(storage.connection).to eq(storage.connection)
|
129
30
|
end
|
130
31
|
end
|
131
32
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Copying Files', type: :feature do
|
4
|
+
it 'copies an existing file to the specified path' do
|
5
|
+
uploader = Class.new(CarrierWave::Uploader::Base) do
|
6
|
+
def filename; 'image.png'; end
|
7
|
+
end
|
8
|
+
|
9
|
+
image = File.open('spec/fixtures/image.png', 'r')
|
10
|
+
original = uploader.new
|
11
|
+
|
12
|
+
original.store!(image)
|
13
|
+
original.retrieve_from_store!('image.png')
|
14
|
+
|
15
|
+
original.file.copy_to('uploads/image2.png')
|
16
|
+
|
17
|
+
copy = uploader.new
|
18
|
+
copy.retrieve_from_store!('image2.png')
|
19
|
+
|
20
|
+
original_attributes = original.file.attributes
|
21
|
+
original_attributes.reject! { |k,v| k == :last_modified }
|
22
|
+
|
23
|
+
copy_attributes = copy.file.attributes
|
24
|
+
copy_attributes.reject! { |k,v| k == :last_modified }
|
25
|
+
|
26
|
+
expect(copy_attributes).to eq(original_attributes)
|
27
|
+
|
28
|
+
image.close
|
29
|
+
original.file.delete
|
30
|
+
copy.file.delete
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Querying Files', type: :feature do
|
4
|
+
it 'retrieves the attributes for a stored file' do
|
5
|
+
uploader = Class.new(CarrierWave::Uploader::Base) do
|
6
|
+
def filename; 'image.png'; end
|
7
|
+
end
|
8
|
+
|
9
|
+
image = File.open('spec/fixtures/image.png', 'r')
|
10
|
+
instance = uploader.new
|
11
|
+
|
12
|
+
instance.store!(image)
|
13
|
+
instance.retrieve_from_store!('image.png')
|
14
|
+
|
15
|
+
expect(instance.file.attributes).to include(
|
16
|
+
:meta,
|
17
|
+
:restore_in_progress,
|
18
|
+
:content_type,
|
19
|
+
:etag,
|
20
|
+
:accept_ranges,
|
21
|
+
:last_modified,
|
22
|
+
:content_length
|
23
|
+
)
|
24
|
+
|
25
|
+
image.close
|
26
|
+
instance.file.delete
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'checks if a remote file exists' do
|
30
|
+
uploader = Class.new(CarrierWave::Uploader::Base) do
|
31
|
+
def filename; 'image.png'; end
|
32
|
+
end
|
33
|
+
|
34
|
+
image = File.open('spec/fixtures/image.png', 'r')
|
35
|
+
instance = uploader.new
|
36
|
+
|
37
|
+
instance.store!(image)
|
38
|
+
instance.retrieve_from_store!('image.png')
|
39
|
+
|
40
|
+
expect(instance.file.exists?).to be true
|
41
|
+
|
42
|
+
instance.file.delete
|
43
|
+
|
44
|
+
expect(instance.file.exists?).to be false
|
45
|
+
|
46
|
+
image.close
|
47
|
+
end
|
48
|
+
end
|
@@ -1,33 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
config.storage = :aws
|
8
|
-
config.aws_bucket = ENV['S3_BUCKET_NAME']
|
9
|
-
config.aws_acl = :public_read
|
10
|
-
|
11
|
-
config.aws_credentials = {
|
12
|
-
access_key_id: ENV['S3_ACCESS_KEY'],
|
13
|
-
secret_access_key: ENV['S3_SECRET_ACCESS_KEY']
|
14
|
-
}
|
15
|
-
end
|
3
|
+
describe 'Storing Files', type: :feature do
|
4
|
+
it 'uploads the file to the configured bucket' do
|
5
|
+
uploader = Class.new(CarrierWave::Uploader::Base) do
|
6
|
+
def filename; 'image.png'; end
|
16
7
|
end
|
17
8
|
|
18
|
-
|
19
|
-
|
20
|
-
def filename; 'image.png'; end
|
21
|
-
end
|
9
|
+
image = File.open('spec/fixtures/image.png', 'r')
|
10
|
+
instance = uploader.new
|
22
11
|
|
23
|
-
|
24
|
-
|
12
|
+
instance.store!(image)
|
13
|
+
instance.retrieve_from_store!('image.png')
|
25
14
|
|
26
|
-
|
27
|
-
|
15
|
+
expect(instance.file.size).to be_nonzero
|
16
|
+
expect(image.size).to eq(instance.file.size)
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
18
|
+
image.close
|
19
|
+
instance.file.delete
|
32
20
|
end
|
33
21
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rspec'
|
2
1
|
require 'carrierwave'
|
3
2
|
require 'carrierwave-aws'
|
4
3
|
|
@@ -12,10 +11,34 @@ def source_environment_file!
|
|
12
11
|
end
|
13
12
|
|
14
13
|
RSpec.configure do |config|
|
15
|
-
|
14
|
+
source_environment_file!
|
15
|
+
|
16
|
+
config.mock_with :rspec do |mocks|
|
17
|
+
mocks.verify_partial_doubles = true
|
18
|
+
end
|
19
|
+
|
16
20
|
config.filter_run :focus
|
17
|
-
config.
|
21
|
+
config.filter_run_excluding type: :feature unless ENV.key?('S3_BUCKET_NAME')
|
18
22
|
config.run_all_when_everything_filtered = true
|
23
|
+
config.order = :random
|
19
24
|
|
20
|
-
|
25
|
+
if config.files_to_run.one?
|
26
|
+
config.default_formatter = 'doc'
|
27
|
+
end
|
28
|
+
|
29
|
+
Kernel.srand config.seed
|
30
|
+
|
31
|
+
config.before(:all, type: :feature) do
|
32
|
+
CarrierWave.configure do |config|
|
33
|
+
config.storage = :aws
|
34
|
+
config.aws_bucket = ENV['S3_BUCKET_NAME']
|
35
|
+
config.aws_acl = :public_read
|
36
|
+
|
37
|
+
config.aws_credentials = {
|
38
|
+
access_key_id: ENV['S3_ACCESS_KEY'],
|
39
|
+
secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
|
40
|
+
region: ENV['S3_REGION']
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
21
44
|
end
|
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Parker Selbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: carrierwave
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: aws-sdk
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.58'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.58'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '3'
|
55
55
|
description: Use aws-sdk for S3 support in CarrierWave
|
56
56
|
email:
|
57
57
|
- parker@sorentwo.com
|
@@ -72,8 +72,12 @@ files:
|
|
72
72
|
- lib/carrierwave-aws.rb
|
73
73
|
- lib/carrierwave/aws/version.rb
|
74
74
|
- lib/carrierwave/storage/aws.rb
|
75
|
+
- lib/carrierwave/storage/aws_file.rb
|
75
76
|
- spec/carrierwave-aws_spec.rb
|
77
|
+
- spec/carrierwave/storage/aws_file_spec.rb
|
76
78
|
- spec/carrierwave/storage/aws_spec.rb
|
79
|
+
- spec/features/copying_files_spec.rb
|
80
|
+
- spec/features/querying_files_spec.rb
|
77
81
|
- spec/features/storing_files_spec.rb
|
78
82
|
- spec/fixtures/image.png
|
79
83
|
- spec/spec_helper.rb
|
@@ -96,13 +100,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
100
|
version: '0'
|
97
101
|
requirements: []
|
98
102
|
rubyforge_project:
|
99
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.4.5
|
100
104
|
signing_key:
|
101
105
|
specification_version: 4
|
102
106
|
summary: A slimmer alternative to using Fog for S3 support in CarrierWave
|
103
107
|
test_files:
|
104
108
|
- spec/carrierwave-aws_spec.rb
|
109
|
+
- spec/carrierwave/storage/aws_file_spec.rb
|
105
110
|
- spec/carrierwave/storage/aws_spec.rb
|
111
|
+
- spec/features/copying_files_spec.rb
|
112
|
+
- spec/features/querying_files_spec.rb
|
106
113
|
- spec/features/storing_files_spec.rb
|
107
114
|
- spec/fixtures/image.png
|
108
115
|
- spec/spec_helper.rb
|