uppy-s3_multipart 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +156 -55
- data/lib/uppy/s3_multipart/app.rb +2 -3
- data/uppy-s3_multipart.gemspec +3 -2
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3d7712b2f5d9b2dd18d9bf4292905a2d2e75acf33b59088162313b762b870fc
|
4
|
+
data.tar.gz: 2677578c6ca2c73fe65c64ba779bfd9a7d00501e7f93da85576ce9364800cdef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af9554216d54735f7ee792bdd08194b950fa3f43730b085898a8b447bb51648be03f1bae126beb2f0ff3234186b422ba7dc363c5eba051aa9bc3df88e412b2a8
|
7
|
+
data.tar.gz: 12ea6a1d7a75b90c6b30a001c4215ef4ed5b6026b9e2f8e4b41dfe94041351b539f6680851b18361682d5ad1f61345b76081a3d907940e1aa4dcffbb6f969cda
|
data/README.md
CHANGED
@@ -71,8 +71,8 @@ Shrine.storages = {
|
|
71
71
|
Shrine.plugin :uppy_s3_multipart # load the plugin
|
72
72
|
```
|
73
73
|
|
74
|
-
The plugin will provide a `Shrine.uppy_s3_multipart` method
|
75
|
-
|
74
|
+
The plugin will provide a `Shrine.uppy_s3_multipart` method that creates a new
|
75
|
+
`Uppy::S3Multipart::App` instance, which is a Rack app that you can mount
|
76
76
|
inside your main application:
|
77
77
|
|
78
78
|
```rb
|
@@ -87,16 +87,6 @@ map "/s3/multipart" do
|
|
87
87
|
end
|
88
88
|
```
|
89
89
|
|
90
|
-
This will add the routes that the `AwsS3Multipart` Uppy plugin expects:
|
91
|
-
|
92
|
-
```
|
93
|
-
POST /s3/multipart
|
94
|
-
GET /s3/multipart/:uploadId
|
95
|
-
GET /s3/multipart/:uploadId/:partNumber
|
96
|
-
POST /s3/multipart/:uploadId/complete
|
97
|
-
DELETE /s3/multipart/:uploadId
|
98
|
-
```
|
99
|
-
|
100
90
|
Now in your Uppy configuration point `serverUrl` to your app's URL:
|
101
91
|
|
102
92
|
```js
|
@@ -129,36 +119,10 @@ uppy.on('upload-success', function (file, data, uploadURL) {
|
|
129
119
|
Shrine. From there you can swap the `presign_endpoint` + `AwsS3` code with the
|
130
120
|
`uppy_s3_multipart` + `AwsS3Multipart` setup.**
|
131
121
|
|
132
|
-
Note that
|
133
|
-
|
134
|
-
side. See [this section][metadata direct uploads] for the
|
135
|
-
instructions on how to opt in.
|
136
|
-
|
137
|
-
If you want to make uploads public and have public URLs without query
|
138
|
-
parameters returned, you can pass `public: true` to the Shrine storage (note
|
139
|
-
that this is supported starting from Shrine 2.13).
|
140
|
-
|
141
|
-
```rb
|
142
|
-
Shrine::Storage::S3.new(public: true, **options)
|
143
|
-
```
|
144
|
-
|
145
|
-
Both the plugin and method accept `:options` for specifying additional options
|
146
|
-
to the S3 client operations (see the [Client](#client) section for list of
|
147
|
-
operations and options they accept):
|
148
|
-
|
149
|
-
```rb
|
150
|
-
Shrine.plugin :uppy_s3_multipart, options: {
|
151
|
-
create_multipart_upload: { acl: "public-read" } # static
|
152
|
-
}
|
153
|
-
|
154
|
-
# OR
|
155
|
-
|
156
|
-
Shrine.uppy_s3_multipart(:cache, options: {
|
157
|
-
create_multipart_upload: -> (request) { { acl: "public-read" } } # dynamic
|
158
|
-
})
|
159
|
-
```
|
160
|
-
|
161
|
-
In the dynamic version the yielded object is an instance of [`Rack::Request`].
|
122
|
+
Note that **Shrine won't extract metadata from directly upload files on
|
123
|
+
assignment** by default. Instead, it will just copy metadata that was extracted
|
124
|
+
on the client side. See [this section][metadata direct uploads] for the
|
125
|
+
rationale and instructions on how to opt in.
|
162
126
|
|
163
127
|
### App
|
164
128
|
|
@@ -193,7 +157,17 @@ map "/s3/multipart" do
|
|
193
157
|
end
|
194
158
|
```
|
195
159
|
|
196
|
-
|
160
|
+
This will add the routes that the `AwsS3Multipart` Uppy plugin expects:
|
161
|
+
|
162
|
+
```
|
163
|
+
POST /s3/multipart
|
164
|
+
GET /s3/multipart/:uploadId
|
165
|
+
GET /s3/multipart/:uploadId/:partNumber
|
166
|
+
POST /s3/multipart/:uploadId/complete
|
167
|
+
DELETE /s3/multipart/:uploadId
|
168
|
+
```
|
169
|
+
|
170
|
+
Now in your Uppy configuration point `serverUrl` to your app's URL:
|
197
171
|
|
198
172
|
```js
|
199
173
|
// ...
|
@@ -202,30 +176,153 @@ uppy.use(Uppy.AwsS3Multipart, {
|
|
202
176
|
})
|
203
177
|
```
|
204
178
|
|
205
|
-
|
206
|
-
|
179
|
+
### Configuration
|
180
|
+
|
181
|
+
This section describe various configuration options that you can pass to
|
182
|
+
`Uppy::S3Multipart::App`.
|
183
|
+
|
184
|
+
#### `:bucket`
|
185
|
+
|
186
|
+
The `:bucket` option is mandatory and accepts an instance of `Aws::S3::Bucket`.
|
187
|
+
It's easiest to create an `Aws::S3::Resource`, and call `#bucket` on it.
|
207
188
|
|
208
189
|
```rb
|
209
|
-
|
190
|
+
require "uppy/s3_multipart"
|
191
|
+
|
192
|
+
resource = Aws::S3::Resource.new(
|
193
|
+
access_key_id: "<ACCESS_KEY_ID>",
|
194
|
+
secret_access_key: "<SECRET_ACCESS_KEY>",
|
195
|
+
region: "<REGION>",
|
196
|
+
)
|
197
|
+
|
198
|
+
bucket = resource.bucket("<BUCKET>")
|
199
|
+
|
200
|
+
Uppy::S3MUltipart::App.new(bucket: bucket)
|
210
201
|
```
|
211
202
|
|
212
|
-
|
213
|
-
|
214
|
-
options they accept):
|
203
|
+
If you want to use [Minio], you can easily configure your `Aws::S3::Bucket` to
|
204
|
+
point to your Minio server:
|
215
205
|
|
216
206
|
```rb
|
217
|
-
|
218
|
-
|
219
|
-
|
207
|
+
resource = Aws::S3::Resource.new(
|
208
|
+
access_key_id: "<MINIO_ACCESS_KEY>", # "AccessKey" value
|
209
|
+
secret_access_key: "<MINIO_SECRET_KEY>", # "SecretKey" value
|
210
|
+
endpoint: "<MINIO_ENDPOINT>", # "Endpoint" value
|
211
|
+
region: "us-east-1",
|
212
|
+
force_path_style: true,
|
213
|
+
)
|
214
|
+
|
215
|
+
bucket = resource.bucket("<MINIO_BUCKET>") # name of the bucket you created
|
216
|
+
```
|
217
|
+
|
218
|
+
See the [`Aws::S3::Client#initialize`] docs for all supported configuration
|
219
|
+
options. In the Shrine plugin this option is inferred from the S3 storage.
|
220
|
+
|
221
|
+
#### `:prefix`
|
220
222
|
|
221
|
-
|
223
|
+
The `:prefix` option allows you to specify a directory which you want the files
|
224
|
+
to be uploaded to.
|
222
225
|
|
226
|
+
```rb
|
227
|
+
Uppy::S3Multipart::App.new(bucket: bucket, prefix: "cache")
|
228
|
+
```
|
229
|
+
|
230
|
+
In the Shrine plugin this option is inferred from the S3 storage:
|
231
|
+
|
232
|
+
```rb
|
233
|
+
Shrine.storages = {
|
234
|
+
cache: Shrine::Storage::S3.new(prefix: "cache", **options),
|
235
|
+
store: Shrine::Storage::S3.new(**options),
|
236
|
+
}
|
237
|
+
```
|
238
|
+
|
239
|
+
#### `:options`
|
240
|
+
|
241
|
+
The `:options` option allows you to pass additional parameters to [Client]
|
242
|
+
operations. With the Shrine plugin they can be passed when initializing the
|
243
|
+
plugin:
|
244
|
+
|
245
|
+
```rb
|
246
|
+
Shrine.plugin :uppy_s3_multipart, options: { ... }
|
247
|
+
```
|
248
|
+
|
249
|
+
or when creating the app:
|
250
|
+
|
251
|
+
```rb
|
252
|
+
Shrine.uppy_s3_multipart(:cache, options: { ... })
|
253
|
+
```
|
254
|
+
|
255
|
+
In the end they are just forwarded to `Uppy::S3Multipart::App#initialize`:
|
256
|
+
|
257
|
+
```rb
|
258
|
+
Uppy::S3Multipart::App.new(bucket: bucket, options: { ... })
|
259
|
+
```
|
260
|
+
|
261
|
+
In the `:options` hash keys are [Client] operation names, and values are the
|
262
|
+
parameters. The parameters can be provided statically:
|
263
|
+
|
264
|
+
```rb
|
265
|
+
options: {
|
266
|
+
create_multipart_upload: { cache_control: "max-age=#{365*24*60*60}" },
|
267
|
+
}
|
268
|
+
```
|
269
|
+
|
270
|
+
or generated dynamically for each request:
|
271
|
+
|
272
|
+
```rb
|
273
|
+
options: {
|
274
|
+
create_multipart_upload: -> (request) do
|
275
|
+
{ key: SecureRandom.uuid }
|
276
|
+
end
|
277
|
+
}
|
278
|
+
```
|
279
|
+
|
280
|
+
In that case a [`Rack::Request`] object is also passed to the block. The
|
281
|
+
initial request to `POST /s3/multipart` will contain `type` and `filename`
|
282
|
+
query parameters, so for example you could use that to make requesting the URL
|
283
|
+
later force a download with the original filename (using the
|
284
|
+
[content_disposition] gem):
|
285
|
+
|
286
|
+
```rb
|
287
|
+
options: {
|
288
|
+
create_multipart_upload: -> (request) do
|
289
|
+
filename = request.params["filename"]
|
290
|
+
|
291
|
+
{ content_disposition: ContentDisposition.attachment(filename) }
|
292
|
+
end
|
293
|
+
}
|
294
|
+
```
|
295
|
+
|
296
|
+
See the [Client] section for list of operations and parameters they accept.
|
297
|
+
|
298
|
+
#### `:public`
|
299
|
+
|
300
|
+
The `:public` option sets the ACL of uploaded objects to `public-read`, and
|
301
|
+
makes sure the object URL returned at the end is a public non-expiring URL
|
302
|
+
without query parameters.
|
303
|
+
|
304
|
+
```rb
|
305
|
+
Uppy::S3Multipart::App.new(bucket: bucket, public: true)
|
306
|
+
```
|
307
|
+
|
308
|
+
It's really just a shorthand for:
|
309
|
+
|
310
|
+
```rb
|
223
311
|
Uppy::S3Multipart::App.new(bucket: bucket, options: {
|
224
|
-
create_multipart_upload:
|
312
|
+
create_multipart_upload: { acl: "public-read" },
|
313
|
+
object_url: { public: true },
|
225
314
|
})
|
226
315
|
```
|
227
316
|
|
228
|
-
In the
|
317
|
+
In the Shrine plugin this option is inferred from the S3 storage (available
|
318
|
+
from Shrine 2.13):
|
319
|
+
|
320
|
+
```rb
|
321
|
+
Shrine.storages = {
|
322
|
+
cache: Shrine::Storage::S3.new(prefix: "cache", public: true, **options),
|
323
|
+
store: Shrine::Storage::S3.new(**options),
|
324
|
+
}
|
325
|
+
```
|
229
326
|
|
230
327
|
### Client
|
231
328
|
|
@@ -379,7 +476,11 @@ License](https://opensource.org/licenses/MIT).
|
|
379
476
|
[AwsS3Multipart]: https://uppy.io/docs/aws-s3-multipart/
|
380
477
|
[Shrine]: https://shrinerb.com
|
381
478
|
[Adding Direct S3 Uploads]: https://github.com/shrinerb/shrine/wiki/Adding-Direct-S3-Uploads
|
479
|
+
[Minio]: https://minio.io/
|
480
|
+
[Client]: #client
|
481
|
+
[content_disposition]: https://github.com/shrinerb/content_disposition
|
382
482
|
[`Rack::Request`]: https://www.rubydoc.info/github/rack/rack/master/Rack/Request
|
483
|
+
[`Aws::S3::Client#initialize`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#initialize-instance_method
|
383
484
|
[`Aws::S3::Client#create_multipart_upload`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#create_multipart_upload-instance_method
|
384
485
|
[`Aws::S3::Client#list_parts`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#list_parts-instance_method
|
385
486
|
[`Aws::S3::Client#upload_part`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#upload_part-instance_method
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require "uppy/s3_multipart/client"
|
2
2
|
|
3
3
|
require "roda"
|
4
|
+
require "content_disposition"
|
4
5
|
|
5
6
|
require "securerandom"
|
6
|
-
require "cgi"
|
7
7
|
|
8
8
|
module Uppy
|
9
9
|
module S3Multipart
|
@@ -40,8 +40,7 @@ module Uppy
|
|
40
40
|
key = SecureRandom.hex + extension
|
41
41
|
key = "#{opts[:prefix]}/#{key}" if opts[:prefix]
|
42
42
|
|
43
|
-
|
44
|
-
content_disposition = "inline; filename=\"#{CGI.escape(filename)}\"" if filename
|
43
|
+
content_disposition = ContentDisposition.inline(filename) if filename
|
45
44
|
|
46
45
|
options = { content_type: content_type, content_disposition: content_disposition }
|
47
46
|
options[:acl] = "public-read" if opts[:public]
|
data/uppy-s3_multipart.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
|
-
gem.name
|
3
|
-
gem.version
|
2
|
+
gem.name = "uppy-s3_multipart"
|
3
|
+
gem.version = "0.3.0"
|
4
4
|
|
5
5
|
gem.required_ruby_version = ">= 2.2"
|
6
6
|
|
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
|
16
16
|
gem.add_dependency "roda", ">= 2.27", "< 4"
|
17
17
|
gem.add_dependency "aws-sdk-s3", "~> 1.0"
|
18
|
+
gem.add_dependency "content_disposition", "~> 1.0"
|
18
19
|
|
19
20
|
gem.add_development_dependency "rake"
|
20
21
|
gem.add_development_dependency "minitest"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uppy-s3_multipart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janko Marohnić
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: roda
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: content_disposition
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: rake
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|