carrierwave-aws 0.5.0 → 0.6.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/.travis.yml +3 -3
- data/CHANGELOG.md +10 -0
- data/README.md +17 -25
- data/carrierwave-aws.gemspec +1 -1
- data/lib/carrierwave-aws.rb +2 -0
- data/lib/carrierwave/aws/version.rb +1 -1
- data/lib/carrierwave/storage/aws.rb +2 -2
- data/lib/carrierwave/storage/aws_file.rb +31 -57
- data/lib/carrierwave/storage/aws_options.rb +42 -0
- data/lib/carrierwave/support/uri_filename.rb +11 -0
- data/spec/carrierwave/storage/aws_file_spec.rb +17 -80
- data/spec/carrierwave/storage/aws_options_spec.rb +79 -0
- data/spec/carrierwave/storage/aws_spec.rb +2 -8
- data/spec/carrierwave/support/uri_filename_spec.rb +18 -0
- data/spec/features/copying_files_spec.rb +4 -8
- data/spec/features/storing_files_spec.rb +47 -7
- data/spec/spec_helper.rb +6 -2
- metadata +10 -6
- data/spec/features/querying_files_spec.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cfb613038a1d6671516ddc5f04d4c6a78024a7d
|
4
|
+
data.tar.gz: 85ed3134b7b2ffb7b2e5b6fab8a825a26b0258c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58cf39368f66fafde4dfcde883d2a19314012a4b3604ca3160caf067dbb42905a727eb8d985c4d9e3f85251c1cd6961caa9aadd4d06c60431a314b5b710d50c8
|
7
|
+
data.tar.gz: 7efb7a4b9c857749c55b420946bfa8eafc2d7bd4ee9217046ee610ada3e098f6447c5820b79f68c6ee5a52377a41b4f8cf2d453a605b3655d1db3be57f948757
|
data/.travis.yml
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
---
|
2
1
|
language: ruby
|
3
2
|
rvm:
|
4
|
-
- 2.
|
5
|
-
- 2.
|
3
|
+
- 2.1.5
|
4
|
+
- 2.2.2
|
6
5
|
script: bundle exec rspec spec
|
7
6
|
env:
|
8
7
|
global:
|
@@ -18,3 +17,4 @@ env:
|
|
18
17
|
B75vnSCFTnQgCP4dmz78VN/WWj88Tpnh4cjUCU0cQjQ5M7oQ0KTbM0d7WDyf
|
19
18
|
rf0F+B9OihBtLNQWqjocRvNH0dU5OzBLCC9DVolUgNwOdNTHW2I7CwlxJ5t7
|
20
19
|
ljQTxzPP+tFASwzBHjywbo7n0EX3efT5UOZhbD9LZL93X4SOlyU=
|
20
|
+
- secure: Uv276ljIrpfYNE34zKnawA6rxchmMymTzMs3LRcmsCDawDhNmtEuoqeHLiZctFU0k40YDylwcDXDWJayVDSW97+ytMqFfQ6e7HkL06iNZPcAW8V0LJt4SrVzRGIm6ER9Xib57lXhOnfS0jcVxT/UuD0pegvYdZb0VhUedmqInP0=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## Version 0.6.0 2015-06-26
|
2
|
+
|
3
|
+
* Breaking Change: Updated to use AWS-SDK v2 [Mark Oleson]
|
4
|
+
* You must specify a region in your `aws_credentials` configuration
|
5
|
+
* You must use hyphens in ACLs instead of underscores (`:public_read` becomes
|
6
|
+
`:'public-read'` or `'public-read'`)
|
7
|
+
* Authenticated URL's are now longer than 255 characters. If you are caching
|
8
|
+
url values you'll need to ensure columns allow 255+ characters.
|
9
|
+
* Authenticated URL expiration has been limited to 7 days.
|
10
|
+
|
1
11
|
## Version 0.5.0 2015-01-31
|
2
12
|
|
3
13
|
* Change: Nudge the expected AWS-SDK version.
|
data/README.md
CHANGED
@@ -38,45 +38,37 @@ the use of `aws_bucket` instead of `fog_directory`, and `aws_acl` instead of
|
|
38
38
|
CarrierWave.configure do |config|
|
39
39
|
config.storage = :aws
|
40
40
|
config.aws_bucket = ENV.fetch('S3_BUCKET_NAME')
|
41
|
-
config.aws_acl =
|
41
|
+
config.aws_acl = 'public-read'
|
42
42
|
config.asset_host = 'http://example.com'
|
43
|
-
|
43
|
+
|
44
|
+
# The maximum period for authenticated_urls is only 7 days.
|
45
|
+
config.aws_authenticated_url_expiration = 60 * 60 * 24 * 7
|
44
46
|
|
45
47
|
config.aws_credentials = {
|
46
48
|
access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
|
47
|
-
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')
|
49
|
+
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
|
50
|
+
region: ENV.fetch('AWS_REGION') # Required
|
48
51
|
}
|
49
52
|
end
|
50
53
|
```
|
51
54
|
|
52
|
-
If you want to supply your own AWS configuration, put it inside
|
53
|
-
`config.aws_credentials` like this:
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
config.aws_credentials = {
|
57
|
-
access_key_id: ENV['AWS_ACCESS_KEY_ID'],
|
58
|
-
secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
|
59
|
-
config: AWS.config(my_aws_options)
|
60
|
-
}
|
61
|
-
```
|
62
|
-
|
63
|
-
`AWS.config` will return `AWS::Core::Configuration` object which is used
|
64
|
-
through `aws-sdk` gem. Browse [Amazon docs](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html)
|
65
|
-
for additional info. For example, if you want to turn off SSL for your asset
|
66
|
-
URLs, you could simply set `AWS.config(use_ssl: false)`.
|
67
|
-
|
68
55
|
### Custom options for AWS URLs
|
69
56
|
|
70
57
|
If you have a custom uploader that specifies additional headers for each URL, please try the following example:
|
71
58
|
|
72
59
|
```ruby
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
60
|
+
class MyUploader < Carrierwave::Uploader::Base
|
61
|
+
# Storage configuration within the uploader supercedes the global CarrierWave
|
62
|
+
# config, so be sure that your uploader does not contain `storage :file`, or
|
63
|
+
# AWS will not be used.
|
64
|
+
storage :aws
|
65
|
+
|
66
|
+
# You can find full list of custom headers in AWS SDK documentation on
|
67
|
+
# AWS::S3::S3Object
|
68
|
+
def download_url(filename)
|
69
|
+
url(response_content_disposition: %Q{attachment; filename="#{filename}"})
|
79
70
|
end
|
71
|
+
end
|
80
72
|
```
|
81
73
|
|
82
74
|
If you migrate from `fog` you probably have something like `url(query: {'my-header': 'my-value'})`.
|
data/carrierwave-aws.gemspec
CHANGED
data/lib/carrierwave-aws.rb
CHANGED
@@ -2,6 +2,8 @@ require 'carrierwave'
|
|
2
2
|
require 'carrierwave/aws/version'
|
3
3
|
require 'carrierwave/storage/aws'
|
4
4
|
require 'carrierwave/storage/aws_file'
|
5
|
+
require 'carrierwave/storage/aws_options'
|
6
|
+
require 'carrierwave/support/uri_filename'
|
5
7
|
|
6
8
|
class CarrierWave::Uploader::Base
|
7
9
|
add_config :aws_attributes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'aws
|
1
|
+
require 'aws-sdk-resources'
|
2
2
|
|
3
3
|
module CarrierWave
|
4
4
|
module Storage
|
@@ -23,7 +23,7 @@ module CarrierWave
|
|
23
23
|
|
24
24
|
def connection
|
25
25
|
@connection ||= begin
|
26
|
-
self.class.connection_cache[credentials] ||= ::
|
26
|
+
self.class.connection_cache[credentials] ||= ::Aws::S3::Resource.new(*credentials)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -1,43 +1,51 @@
|
|
1
1
|
module CarrierWave
|
2
2
|
module Storage
|
3
3
|
class AWSFile
|
4
|
-
attr_writer :
|
5
|
-
|
4
|
+
attr_writer :file
|
5
|
+
attr_accessor :uploader, :connection, :path, :aws_options
|
6
6
|
|
7
7
|
def initialize(uploader, connection, path)
|
8
|
-
@uploader
|
9
|
-
@connection
|
10
|
-
@path
|
8
|
+
@uploader = uploader
|
9
|
+
@connection = connection
|
10
|
+
@path = path
|
11
|
+
@aws_options = AWSOptions.new(uploader)
|
11
12
|
end
|
12
13
|
|
14
|
+
def file
|
15
|
+
@file ||= bucket.object(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :to_file, :file
|
19
|
+
|
13
20
|
def attributes
|
14
|
-
file.
|
21
|
+
file.data.to_h
|
15
22
|
end
|
16
23
|
|
17
24
|
def content_type
|
18
|
-
|
25
|
+
file.content_type
|
19
26
|
end
|
20
27
|
|
21
28
|
def delete
|
22
29
|
file.delete
|
23
30
|
end
|
24
31
|
|
25
|
-
def extension
|
26
|
-
path.split('.').last
|
27
|
-
end
|
28
|
-
|
29
32
|
def exists?
|
30
33
|
file.exists?
|
31
34
|
end
|
32
35
|
|
36
|
+
def extension
|
37
|
+
elements = path.split('.')
|
38
|
+
elements.last if elements.size > 1
|
39
|
+
end
|
40
|
+
|
33
41
|
def filename(options = {})
|
34
42
|
if file_url = url(options)
|
35
|
-
|
43
|
+
CarrierWave::Support::UriFilename.filename(file_url)
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
39
47
|
def read
|
40
|
-
file.
|
48
|
+
file.get(aws_options.read_options).body.read
|
41
49
|
end
|
42
50
|
|
43
51
|
def size
|
@@ -45,25 +53,15 @@ module CarrierWave
|
|
45
53
|
end
|
46
54
|
|
47
55
|
def store(new_file)
|
48
|
-
|
49
|
-
|
50
|
-
true
|
56
|
+
!!file.put(aws_options.write_options(new_file))
|
51
57
|
end
|
52
58
|
|
53
|
-
def
|
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
|
59
|
+
def copy_to(new_path)
|
60
|
+
bucket.object(new_path).copy_from(copy_source: "#{bucket.name}/#{file.key}")
|
63
61
|
end
|
64
62
|
|
65
63
|
def authenticated_url(options = {})
|
66
|
-
file.
|
64
|
+
file.presigned_url(:get, aws_options.expiration_options(options))
|
67
65
|
end
|
68
66
|
|
69
67
|
def public_url
|
@@ -74,42 +72,18 @@ module CarrierWave
|
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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)
|
75
|
+
def url(options = {})
|
76
|
+
if uploader.aws_acl.to_s != 'public-read'
|
77
|
+
authenticated_url(options)
|
78
|
+
else
|
79
|
+
public_url
|
100
80
|
end
|
101
|
-
|
102
|
-
{ acl: uploader.aws_acl }.merge(storage_options)
|
103
81
|
end
|
104
82
|
|
105
83
|
private
|
106
84
|
|
107
85
|
def bucket
|
108
|
-
@bucket ||= connection.
|
109
|
-
end
|
110
|
-
|
111
|
-
def file
|
112
|
-
@file ||= bucket.objects[path]
|
86
|
+
@bucket ||= connection.bucket(uploader.aws_bucket)
|
113
87
|
end
|
114
88
|
end
|
115
89
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CarrierWave
|
2
|
+
module Storage
|
3
|
+
class AWSOptions
|
4
|
+
attr_reader :uploader
|
5
|
+
|
6
|
+
def initialize(uploader)
|
7
|
+
@uploader = uploader
|
8
|
+
end
|
9
|
+
|
10
|
+
def read_options
|
11
|
+
aws_read_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_options(new_file)
|
15
|
+
{ acl: uploader.aws_acl,
|
16
|
+
body: new_file.to_file,
|
17
|
+
content_type: new_file.content_type,
|
18
|
+
}.merge(aws_attributes).merge(aws_write_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def expiration_options(options = {})
|
22
|
+
uploader_expiration = uploader.aws_authenticated_url_expiration
|
23
|
+
|
24
|
+
{ expires_in: uploader_expiration }.merge(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def aws_attributes
|
30
|
+
uploader.aws_attributes || {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def aws_read_options
|
34
|
+
uploader.aws_read_options || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def aws_write_options
|
38
|
+
uploader.aws_write_options || {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CarrierWave::Storage::AWSFile do
|
4
|
-
let(:objects) { { 'files/1/file.txt' => file } }
|
5
4
|
let(:path) { 'files/1/file.txt' }
|
6
|
-
let(:
|
7
|
-
let(:
|
8
|
-
let(:
|
5
|
+
let(:file) { double(:file, content_type: 'content/type', path: '/file/path') }
|
6
|
+
let(:bucket) { double(:bucket, object: file) }
|
7
|
+
let(:connection) { double(:connection, bucket: bucket) }
|
9
8
|
|
10
9
|
let(:uploader) do
|
11
10
|
double(:uploader,
|
12
11
|
aws_bucket: 'example-com',
|
13
|
-
aws_acl: :
|
12
|
+
aws_acl: :'public-read',
|
14
13
|
aws_attributes: {},
|
15
14
|
asset_host: nil,
|
16
15
|
aws_read_options: { encryption_key: 'abc' },
|
@@ -22,86 +21,32 @@ describe CarrierWave::Storage::AWSFile do
|
|
22
21
|
CarrierWave::Storage::AWSFile.new(uploader, connection, path)
|
23
22
|
end
|
24
23
|
|
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
24
|
describe '#to_file' do
|
79
25
|
it 'returns the internal file instance' do
|
26
|
+
file = Object.new
|
27
|
+
aws_file.file = file
|
28
|
+
|
80
29
|
expect(aws_file.to_file).to be(file)
|
81
30
|
end
|
82
31
|
end
|
83
32
|
|
84
|
-
describe '#
|
85
|
-
it '
|
86
|
-
|
33
|
+
describe '#extension' do
|
34
|
+
it 'extracts the file extension from the path' do
|
35
|
+
aws_file.path = 'file.txt'
|
87
36
|
|
88
|
-
expect(
|
89
|
-
|
90
|
-
aws_file.authenticated_url
|
37
|
+
expect(aws_file.extension).to eq('txt')
|
91
38
|
end
|
92
39
|
|
93
|
-
it '
|
94
|
-
|
95
|
-
|
96
|
-
expect(file).to receive(:url_for).with(:read, hash_including(response_content_disposition: 'attachment'))
|
40
|
+
it 'is nil if the file has no extension' do
|
41
|
+
aws_file.path = 'filetxt'
|
97
42
|
|
98
|
-
aws_file.
|
43
|
+
expect(aws_file.extension).to be_nil
|
99
44
|
end
|
100
45
|
end
|
101
46
|
|
102
47
|
describe '#url' do
|
103
48
|
it 'requests a public url if acl is public readable' do
|
104
|
-
allow(uploader).to receive(:aws_acl) { :
|
49
|
+
allow(uploader).to receive(:aws_acl) { :'public-read' }
|
105
50
|
|
106
51
|
expect(file).to receive(:public_url)
|
107
52
|
|
@@ -112,24 +57,16 @@ describe CarrierWave::Storage::AWSFile do
|
|
112
57
|
allow(uploader).to receive(:aws_acl) { :private }
|
113
58
|
allow(uploader).to receive(:aws_authenticated_url_expiration) { 60 }
|
114
59
|
|
115
|
-
expect(file).to receive(:
|
60
|
+
expect(file).to receive(:presigned_url).with(:get, { expires_in: 60 })
|
116
61
|
|
117
62
|
aws_file.url
|
118
63
|
end
|
119
64
|
|
120
65
|
it 'uses the asset_host and file path if asset_host is set' do
|
121
|
-
allow(uploader).to receive(:aws_acl) { :
|
66
|
+
allow(uploader).to receive(:aws_acl) { :'public-read' }
|
122
67
|
allow(uploader).to receive(:asset_host) { 'http://example.com' }
|
123
68
|
|
124
69
|
expect(aws_file.url).to eq('http://example.com/files/1/file.txt')
|
125
70
|
end
|
126
71
|
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
72
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CarrierWave::Storage::AWSOptions do
|
4
|
+
uploader_klass = Class.new do
|
5
|
+
attr_accessor :aws_attributes, :aws_read_options, :aws_write_options
|
6
|
+
|
7
|
+
def aws_acl
|
8
|
+
'public-read'
|
9
|
+
end
|
10
|
+
|
11
|
+
def aws_authenticated_url_expiration
|
12
|
+
'60'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:uploader) { uploader_klass.new }
|
17
|
+
let(:options) { CarrierWave::Storage::AWSOptions.new(uploader) }
|
18
|
+
|
19
|
+
describe '#read_options' do
|
20
|
+
it 'uses the uploader aws_read_options' do
|
21
|
+
uploader.aws_read_options = { encryption_key: 'abc' }
|
22
|
+
|
23
|
+
expect(options.read_options).to eq(uploader.aws_read_options)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'ensures that read_options are a hash' do
|
27
|
+
uploader.aws_read_options = nil
|
28
|
+
|
29
|
+
expect(options.read_options).to eq({})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#write_options' do
|
34
|
+
let(:file) { CarrierWave::SanitizedFile.new('spec/fixtures/image.png') }
|
35
|
+
|
36
|
+
it 'includes acl, content_type, body (file), aws_attributes, and aws_write_options' do
|
37
|
+
uploader.aws_write_options = { encryption_key: 'def' }
|
38
|
+
|
39
|
+
write_options = options.write_options(file)
|
40
|
+
|
41
|
+
expect(write_options).to include(
|
42
|
+
acl: 'public-read',
|
43
|
+
content_type: 'image/png',
|
44
|
+
encryption_key: 'def'
|
45
|
+
)
|
46
|
+
expect(write_options[:body].path).to eq(file.path)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'works if aws_attributes is nil' do
|
50
|
+
expect(uploader).to receive(:aws_attributes) { nil }
|
51
|
+
|
52
|
+
expect {
|
53
|
+
options.write_options(file)
|
54
|
+
}.to_not raise_error
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'works if aws_write_options is nil' do
|
58
|
+
expect(uploader).to receive(:aws_write_options) { nil }
|
59
|
+
|
60
|
+
expect {
|
61
|
+
options.write_options(file)
|
62
|
+
}.to_not raise_error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#expiration_options' do
|
67
|
+
it 'extracts the expiration value' do
|
68
|
+
expect(options.expiration_options).to eq(
|
69
|
+
expires_in: uploader.aws_authenticated_url_expiration
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'allows expiration to be overridden' do
|
74
|
+
expect(options.expiration_options(expires_in: 10)).to eq(
|
75
|
+
expires_in: 10
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CarrierWave::Storage::AWS do
|
4
|
-
let(:credentials) { { access_key_id: 'abc', secret_access_key: '123' } }
|
4
|
+
let(:credentials) { { access_key_id: 'abc', secret_access_key: '123', region: 'us-east-1' } }
|
5
5
|
let(:uploader) { double(:uploader, aws_credentials: credentials) }
|
6
6
|
|
7
7
|
subject(:storage) do
|
@@ -14,17 +14,11 @@ describe CarrierWave::Storage::AWS do
|
|
14
14
|
|
15
15
|
describe '#connection' do
|
16
16
|
it 'instantiates a new connection with credentials' do
|
17
|
-
expect(
|
17
|
+
expect(Aws::S3::Resource).to receive(:new).with(credentials)
|
18
18
|
|
19
19
|
storage.connection
|
20
20
|
end
|
21
21
|
|
22
|
-
it 'instantiates a new connection without any credentials' do
|
23
|
-
allow(uploader).to receive(:aws_credentials) { nil }
|
24
|
-
|
25
|
-
expect { storage.connection }.not_to raise_exception
|
26
|
-
end
|
27
|
-
|
28
22
|
it 'caches connections by credentials' do
|
29
23
|
expect(storage.connection).to eq(storage.connection)
|
30
24
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CarrierWave::Support::UriFilename do
|
4
|
+
UriFilename = CarrierWave::Support::UriFilename
|
5
|
+
|
6
|
+
describe '.filename' do
|
7
|
+
it 'extracts a decoded filename from file uri' do
|
8
|
+
samples = {
|
9
|
+
'http://example.com/file.txt' => 'file.txt',
|
10
|
+
'http://example.com/files/1/file%201.txt?foo=bar/baz.txt' => 'file 1.txt',
|
11
|
+
}
|
12
|
+
|
13
|
+
samples.each do |uri, name|
|
14
|
+
expect(UriFilename.filename(uri)).to eq(name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,20 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Copying Files', type: :feature do
|
4
|
-
|
5
|
-
|
6
|
-
def filename; 'image.png'; end
|
7
|
-
end
|
8
|
-
|
9
|
-
image = File.open('spec/fixtures/image.png', 'r')
|
10
|
-
original = uploader.new
|
4
|
+
let(:image) { File.open('spec/fixtures/image.png', 'r') }
|
5
|
+
let(:original) { FeatureUploader.new }
|
11
6
|
|
7
|
+
it 'copies an existing file to the specified path' do
|
12
8
|
original.store!(image)
|
13
9
|
original.retrieve_from_store!('image.png')
|
14
10
|
|
15
11
|
original.file.copy_to('uploads/image2.png')
|
16
12
|
|
17
|
-
copy =
|
13
|
+
copy = FeatureUploader.new
|
18
14
|
copy.retrieve_from_store!('image2.png')
|
19
15
|
|
20
16
|
original_attributes = original.file.attributes
|
@@ -1,19 +1,59 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Storing Files', type: :feature do
|
4
|
+
let(:image) { File.open('spec/fixtures/image.png', 'r') }
|
5
|
+
let(:instance) { FeatureUploader.new }
|
6
|
+
|
4
7
|
it 'uploads the file to the configured bucket' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
+
instance.store!(image)
|
9
|
+
instance.retrieve_from_store!('image.png')
|
10
|
+
|
11
|
+
expect(instance.file.size).to eq(image.size)
|
12
|
+
expect(instance.file.read).to eq(image.read)
|
13
|
+
expect(instance.file.read).to eq(instance.file.read)
|
14
|
+
|
15
|
+
image.close
|
16
|
+
instance.file.delete
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'retrieves the attributes for a stored file' do
|
20
|
+
instance.store!(image)
|
21
|
+
instance.retrieve_from_store!('image.png')
|
22
|
+
|
23
|
+
expect(instance.file.attributes).to include(
|
24
|
+
:metadata,
|
25
|
+
:content_type,
|
26
|
+
:etag,
|
27
|
+
:accept_ranges,
|
28
|
+
:last_modified,
|
29
|
+
:content_length
|
30
|
+
)
|
31
|
+
|
32
|
+
expect(instance.file.content_type).to eq('image/png')
|
33
|
+
expect(instance.file.filename).to eq('image.png')
|
8
34
|
|
9
|
-
image
|
10
|
-
instance
|
35
|
+
image.close
|
36
|
+
instance.file.delete
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'checks if a remote file exists' do
|
40
|
+
instance.store!(image)
|
41
|
+
instance.retrieve_from_store!('image.png')
|
42
|
+
|
43
|
+
expect(instance.file.exists?).to be_truthy
|
44
|
+
|
45
|
+
instance.file.delete
|
46
|
+
|
47
|
+
expect(instance.file.exists?).to be_falsy
|
48
|
+
|
49
|
+
image.close
|
50
|
+
end
|
11
51
|
|
52
|
+
it 'gets a url for remote files' do
|
12
53
|
instance.store!(image)
|
13
54
|
instance.retrieve_from_store!('image.png')
|
14
55
|
|
15
|
-
expect(instance.
|
16
|
-
expect(image.size).to eq(instance.file.size)
|
56
|
+
expect(instance.url).to eq("https://#{ENV['S3_BUCKET_NAME']}.s3.amazonaws.com/#{instance.path}")
|
17
57
|
|
18
58
|
image.close
|
19
59
|
instance.file.delete
|
data/spec/spec_helper.rb
CHANGED
@@ -10,6 +10,10 @@ def source_environment_file!
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
FeatureUploader = Class.new(CarrierWave::Uploader::Base) do
|
14
|
+
def filename; 'image.png'; end
|
15
|
+
end
|
16
|
+
|
13
17
|
RSpec.configure do |config|
|
14
18
|
source_environment_file!
|
15
19
|
|
@@ -32,12 +36,12 @@ RSpec.configure do |config|
|
|
32
36
|
CarrierWave.configure do |config|
|
33
37
|
config.storage = :aws
|
34
38
|
config.aws_bucket = ENV['S3_BUCKET_NAME']
|
35
|
-
config.aws_acl = :
|
39
|
+
config.aws_acl = :'public-read'
|
36
40
|
|
37
41
|
config.aws_credentials = {
|
38
42
|
access_key_id: ENV['S3_ACCESS_KEY'],
|
39
43
|
secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
|
40
|
-
region: ENV['
|
44
|
+
region: ENV['AWS_REGION']
|
41
45
|
}
|
42
46
|
end
|
43
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.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: 2015-
|
11
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: carrierwave
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 2.0.47
|
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:
|
40
|
+
version: 2.0.47
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,11 +73,14 @@ files:
|
|
73
73
|
- lib/carrierwave/aws/version.rb
|
74
74
|
- lib/carrierwave/storage/aws.rb
|
75
75
|
- lib/carrierwave/storage/aws_file.rb
|
76
|
+
- lib/carrierwave/storage/aws_options.rb
|
77
|
+
- lib/carrierwave/support/uri_filename.rb
|
76
78
|
- spec/carrierwave-aws_spec.rb
|
77
79
|
- spec/carrierwave/storage/aws_file_spec.rb
|
80
|
+
- spec/carrierwave/storage/aws_options_spec.rb
|
78
81
|
- spec/carrierwave/storage/aws_spec.rb
|
82
|
+
- spec/carrierwave/support/uri_filename_spec.rb
|
79
83
|
- spec/features/copying_files_spec.rb
|
80
|
-
- spec/features/querying_files_spec.rb
|
81
84
|
- spec/features/storing_files_spec.rb
|
82
85
|
- spec/fixtures/image.png
|
83
86
|
- spec/spec_helper.rb
|
@@ -107,9 +110,10 @@ summary: A slimmer alternative to using Fog for S3 support in CarrierWave
|
|
107
110
|
test_files:
|
108
111
|
- spec/carrierwave-aws_spec.rb
|
109
112
|
- spec/carrierwave/storage/aws_file_spec.rb
|
113
|
+
- spec/carrierwave/storage/aws_options_spec.rb
|
110
114
|
- spec/carrierwave/storage/aws_spec.rb
|
115
|
+
- spec/carrierwave/support/uri_filename_spec.rb
|
111
116
|
- spec/features/copying_files_spec.rb
|
112
|
-
- spec/features/querying_files_spec.rb
|
113
117
|
- spec/features/storing_files_spec.rb
|
114
118
|
- spec/fixtures/image.png
|
115
119
|
- spec/spec_helper.rb
|
@@ -1,48 +0,0 @@
|
|
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
|