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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e799b2dfe2ad03929e1e6477382b85c4d721313708abe699673c2c3e496e98e8
4
- data.tar.gz: 05d354cff6f1f5a9ae807faffdd91b29d5f16c62fba9abbec82038b7713a1a3a
3
+ metadata.gz: c3d7712b2f5d9b2dd18d9bf4292905a2d2e75acf33b59088162313b762b870fc
4
+ data.tar.gz: 2677578c6ca2c73fe65c64ba779bfd9a7d00501e7f93da85576ce9364800cdef
5
5
  SHA512:
6
- metadata.gz: 336d352eeeb31ac132c074ddb4febd73d75f47b5fe41ed69caafb90eecf1d43494f37542d06a1df2859210fe9907207456695c0a3c965131384564f93b0abaa9
7
- data.tar.gz: 2ae94a045d3b19e1eabc99dce49ffcaadc1d806caf77cbc87b6edf5b771e1509d58c56a3510f5e1a44b15adfdbe5d93f19fc6acf5322d66bb22791aa5d80d043
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, which returns an
75
- instance of `Uppy::S3Multipart::App`, which is a Rack app that you can mount
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 by default **Shrine won't extract metadata from directly upload
133
- files**, instead it will just copy metadata that was extracted on the client
134
- side. See [this section][metadata direct uploads] for the rationale and
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
- In your Uppy configuration point `serverUrl` to your app's URL:
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
- If you want to make uploads public and have public URLs without query
206
- parameters returned, you can pass `public: true` to the app.
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
- Uppy::S3Multipart::App.new(bucket: bucket, public: true)
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
- You can also pass `:options` for specifying additional options to the S3 client
213
- operations (see the [Client](#client) section for list of operations and
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
- Uppy::S3Multipart::App.new(bucket: bucket, options: {
218
- create_multipart_upload: { acl: "public-read" } # static
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
- # OR
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: -> (request) { { acl: "public-read" } } # dynamic
312
+ create_multipart_upload: { acl: "public-read" },
313
+ object_url: { public: true },
225
314
  })
226
315
  ```
227
316
 
228
- In the dynamic version the yielded object is an instance of [`Rack::Request`].
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
- # CGI-escape the filename because aws-sdk's signature calculator trips on special characters
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]
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
- gem.name = "uppy-s3_multipart"
3
- gem.version = "0.2.0"
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.2.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-08 00:00:00.000000000 Z
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