uppy-s3_multipart 0.2.0 → 0.3.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 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