shrine 2.17.1 → 2.18.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of shrine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -1
- data/README.md +527 -502
- data/doc/advantages.md +1 -3
- data/doc/attacher.md +22 -11
- data/doc/carrierwave.md +7 -8
- data/doc/design.md +1 -1
- data/doc/direct_s3.md +10 -15
- data/doc/metadata.md +11 -3
- data/doc/paperclip.md +1 -2
- data/doc/plugins/default_url_options.md +1 -1
- data/doc/plugins/derivation_endpoint.md +2 -1
- data/doc/plugins/download_endpoint.md +5 -13
- data/doc/plugins/parsed_json.md +12 -0
- data/doc/plugins/presign_endpoint.md +37 -8
- data/doc/plugins/upload_endpoint.md +72 -19
- data/doc/plugins/versions.md +1 -1
- data/doc/refile.md +6 -9
- data/doc/release_notes/2.17.0.md +2 -2
- data/doc/release_notes/2.18.0.md +155 -0
- data/doc/retrieving_uploads.md +45 -6
- data/doc/storage/s3.md +11 -12
- data/lib/shrine.rb +19 -5
- data/lib/shrine/attacher.rb +1 -1
- data/lib/shrine/plugins/data_uri.rb +1 -3
- data/lib/shrine/plugins/presign_endpoint.rb +21 -0
- data/lib/shrine/plugins/remote_url.rb +1 -3
- data/lib/shrine/plugins/remove_attachment.rb +1 -3
- data/lib/shrine/plugins/signature.rb +1 -2
- data/lib/shrine/plugins/upload_endpoint.rb +63 -10
- data/lib/shrine/storage/s3.rb +13 -18
- data/lib/shrine/version.rb +2 -2
- metadata +3 -2
data/doc/advantages.md
CHANGED
@@ -84,9 +84,7 @@ Storage provides, you can ditch the Shrine's attachment implementation and use
|
|
84
84
|
uploaders and uploaded files that are decoupled from attachment:
|
85
85
|
|
86
86
|
```rb
|
87
|
-
|
88
|
-
uploaded_file = uploader.upload(image) # metadata extraction, upload location generation
|
89
|
-
|
87
|
+
uploaded_file = ImageUploader.upload(image, :store) # metadata extraction, upload location generation
|
90
88
|
uploaded_file.id #=> "44ccafc10ce6a4ff22829e8f579ee6b9.jpg"
|
91
89
|
uplaoded_file.metadata #=> { ... extracted metadata ... }
|
92
90
|
|
data/doc/attacher.md
CHANGED
@@ -11,7 +11,7 @@ class Photo < Sequel::Model
|
|
11
11
|
end
|
12
12
|
```
|
13
13
|
|
14
|
-
However, you don't want to add additional methods on the model and prefer
|
14
|
+
However, if you don't want to add additional methods on the model and prefer
|
15
15
|
explicitness, or you need more control, you can achieve the same behaviour
|
16
16
|
using the `Shrine::Attacher` object, which is what the attachment interface
|
17
17
|
uses under the hood.
|
@@ -22,7 +22,14 @@ attacher.assign(file) # equivalent to `photo.ima
|
|
22
22
|
attacher.get # equivalent to `photo.image`
|
23
23
|
```
|
24
24
|
|
25
|
-
|
25
|
+
The attacher will use the `<attachment>_data` attribute for storing information
|
26
|
+
about the attachment.
|
27
|
+
|
28
|
+
```rb
|
29
|
+
attacher.data_attribute #=> :image_data
|
30
|
+
```
|
31
|
+
|
32
|
+
## Initializing
|
26
33
|
|
27
34
|
The attacher object exposes the objects it uses:
|
28
35
|
|
@@ -38,9 +45,15 @@ also tell it to use different temporary and permanent storage:
|
|
38
45
|
|
39
46
|
```rb
|
40
47
|
ImageUploader::Attacher.new(photo, :image, cache: :other_cache, store: :other_store)
|
48
|
+
|
49
|
+
# OR
|
50
|
+
|
51
|
+
photo.image_attacher(cache: :other_cache, store: :other_store)
|
52
|
+
photo.image = file # uploads to :other_cache storage
|
53
|
+
photo.save # promotes to :other_store storage
|
41
54
|
```
|
42
55
|
|
43
|
-
|
56
|
+
You can pass the `:cache` and `:store` options via `Attachment.new` too:
|
44
57
|
|
45
58
|
```rb
|
46
59
|
class Photo < Sequel::Model
|
@@ -48,12 +61,8 @@ class Photo < Sequel::Model
|
|
48
61
|
end
|
49
62
|
```
|
50
63
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
```rb
|
55
|
-
attacher.data_attribute #=> :image_data
|
56
|
-
```
|
64
|
+
Note that it's not necessary to use the temporary storage, see the next section
|
65
|
+
for more details.
|
57
66
|
|
58
67
|
## Assignment
|
59
68
|
|
@@ -92,10 +101,12 @@ attacher.assign(cached_file.to_json)
|
|
92
101
|
|
93
102
|
For security reasons `#assign` doesn't accept files uploaded to permanent
|
94
103
|
storage, but you can use `#set` to attach any `Shrine::UploadedFile` object.
|
104
|
+
You can use this to skip temporary storage altogether and upload files directly
|
105
|
+
to permanent storage:
|
95
106
|
|
96
107
|
```rb
|
97
|
-
uploaded_file
|
98
|
-
attacher.set(uploaded_file)
|
108
|
+
uploaded_file = attacher.store!(file) # upload a file directly to permanent storage
|
109
|
+
attacher.set(uploaded_file) # attach the uploaded file
|
99
110
|
```
|
100
111
|
|
101
112
|
## Retrieval
|
data/doc/carrierwave.md
CHANGED
@@ -62,8 +62,7 @@ deleting files, they also represent the uploaded file. Shrine has a separate
|
|
62
62
|
`Shrine::UploadedFile` class which represents the uploaded file.
|
63
63
|
|
64
64
|
```rb
|
65
|
-
|
66
|
-
uploaded_file = uploader.upload(image)
|
65
|
+
uploaded_file = ImageUploader.upload(file, :store)
|
67
66
|
uploaded_file #=> #<Shrine::UploadedFile>
|
68
67
|
uploaded_file.url #=> "https://my-bucket.s3.amazonaws.com/store/kfds0lg9rer.jpg"
|
69
68
|
uploaded_file.download #=> #<Tempfile>
|
@@ -381,12 +380,12 @@ end
|
|
381
380
|
|
382
381
|
#### `#store!`, `#cache!`
|
383
382
|
|
384
|
-
In Shrine you store and cache files by
|
385
|
-
|
383
|
+
In Shrine you store and cache files by passing the corresponding storage to
|
384
|
+
`Shrine.upload`:
|
386
385
|
|
387
386
|
```rb
|
388
|
-
ImageUploader.
|
389
|
-
ImageUploader.
|
387
|
+
ImageUploader.upload(file, :cache)
|
388
|
+
ImageUploader.upload(file, :store)
|
390
389
|
```
|
391
390
|
|
392
391
|
Note that in Shrine you cannot pass in a path to the file, you always have to
|
@@ -398,8 +397,8 @@ pass an IO-like object, which is required to respond to: `#read(*args)`,
|
|
398
397
|
In Shrine you simply call `#download` on the uploaded file:
|
399
398
|
|
400
399
|
```rb
|
401
|
-
uploaded_file = ImageUploader.
|
402
|
-
uploaded_file.download #=> #<Tempfile>
|
400
|
+
uploaded_file = ImageUploader.upload(file, :store)
|
401
|
+
uploaded_file.download #=> #<Tempfile:/path/to/file>
|
403
402
|
```
|
404
403
|
|
405
404
|
#### `#url`
|
data/doc/design.md
CHANGED
@@ -66,7 +66,7 @@ name:
|
|
66
66
|
Shrine.storages[:file_system] = Shrine::Storage::FileSystem.new("uploads")
|
67
67
|
```
|
68
68
|
|
69
|
-
Now we can instantiate an uploader with this identifier
|
69
|
+
Now we can instantiate an uploader with this identifier and upload files:
|
70
70
|
|
71
71
|
```rb
|
72
72
|
uploader = Shrine.new(:file_system)
|
data/doc/direct_s3.md
CHANGED
@@ -29,7 +29,7 @@ temporary storage uploading to the `cache/` prefix:
|
|
29
29
|
```rb
|
30
30
|
# Gemfile
|
31
31
|
gem "shrine", "~> 2.11"
|
32
|
-
gem "aws-sdk-s3", "~> 1.
|
32
|
+
gem "aws-sdk-s3", "~> 1.14"
|
33
33
|
```
|
34
34
|
```rb
|
35
35
|
require "shrine/storage/s3"
|
@@ -55,7 +55,7 @@ default. You can do that from the AWS S3 Console by going to your bucket,
|
|
55
55
|
clicking on the "Permissions" tab and then on "CORS Configuration".
|
56
56
|
|
57
57
|
If you're using [Uppy], this is the recommended CORS configuration for the
|
58
|
-
[
|
58
|
+
[AWS S3 plugin][uppy aws-s3] that should work for both POST and PUT uploads:
|
59
59
|
|
60
60
|
```xml
|
61
61
|
<?xml version="1.0" encoding="UTF-8"?>
|
@@ -70,6 +70,7 @@ If you're using [Uppy], this is the recommended CORS configuration for the
|
|
70
70
|
<AllowedHeader>x-amz-date</AllowedHeader>
|
71
71
|
<AllowedHeader>x-amz-content-sha256</AllowedHeader>
|
72
72
|
<AllowedHeader>content-type</AllowedHeader>
|
73
|
+
<AllowedHeader>content-disposition</AllowedHeader>
|
73
74
|
</CORSRule>
|
74
75
|
<CORSRule>
|
75
76
|
<AllowedOrigin>*</AllowedOrigin>
|
@@ -114,13 +115,6 @@ Shrine.plugin :presign_endpoint, presign_options: -> (request) {
|
|
114
115
|
}
|
115
116
|
```
|
116
117
|
```rb
|
117
|
-
# config.ru (Rack)
|
118
|
-
map "/s3/params" do
|
119
|
-
run Shrine.presign_endpoint(:cache)
|
120
|
-
end
|
121
|
-
|
122
|
-
# OR
|
123
|
-
|
124
118
|
# config/routes.rb (Rails)
|
125
119
|
Rails.application.routes.draw do
|
126
120
|
mount Shrine.presign_endpoint(:cache) => "/s3/params"
|
@@ -149,7 +143,7 @@ and request headers.
|
|
149
143
|
}
|
150
144
|
```
|
151
145
|
|
152
|
-
Uppy's [AWS S3][uppy aws
|
146
|
+
Uppy's [AWS S3][uppy aws-s3] plugin would then make a request to this endpoint
|
153
147
|
and use these parameters to upload the file directly to S3. Once the file has
|
154
148
|
been uploaded, you can generate a JSON representation of the uploaded file on
|
155
149
|
the client side, and write it to the hidden attachment field (or send it
|
@@ -178,11 +172,11 @@ as the [Roda][roda demo] / [Rails][rails demo] demo app for a complete example
|
|
178
172
|
of multiple direct S3 uploads.
|
179
173
|
|
180
174
|
Also, if you're dealing with larger files, you may want to make the uploads
|
181
|
-
resumable by using the [
|
175
|
+
resumable by using the [AWS S3 Multipart][uppy aws-s3-multipart] Uppy plugin
|
182
176
|
instead, with the [uppy-s3_multipart] gem on the backend. Your back-end
|
183
177
|
implementation is similar, just using `Shrine.uppy_s3_multipart` in place of
|
184
|
-
`Shrine.presign_endpoint`. Instructions can be found in
|
185
|
-
|
178
|
+
`Shrine.presign_endpoint`. Instructions can be found in the [gem
|
179
|
+
docs][uppy-s3_multipart shrine].
|
186
180
|
|
187
181
|
## Strategy B (static)
|
188
182
|
|
@@ -391,10 +385,11 @@ setup] guide.
|
|
391
385
|
[roda demo]: https://github.com/shrinerb/shrine/tree/master/demo
|
392
386
|
[rails demo]: https://github.com/erikdahlstrand/shrine-rails-example
|
393
387
|
[Uppy]: https://uppy.io
|
394
|
-
[uppy aws
|
388
|
+
[uppy aws-s3]: https://uppy.io/docs/aws-s3/
|
395
389
|
[uppy aws-s3 cors]: https://uppy.io/docs/aws-s3/#S3-Bucket-configuration
|
396
|
-
[uppy aws
|
390
|
+
[uppy aws-s3-multipart]: https://uppy.io/docs/aws-s3/
|
397
391
|
[uppy-s3_multipart]: https://github.com/janko/uppy-s3_multipart
|
392
|
+
[uppy-s3_multipart shrine]: https://github.com/janko/uppy-s3_multipart#shrine
|
398
393
|
[Amazon S3 Data Consistency Model]: http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyMode
|
399
394
|
[CORS guide]: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html
|
400
395
|
[CORS API]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_bucket_cors-instance_method
|
data/doc/metadata.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Extracting Metadata
|
2
2
|
|
3
3
|
Before a file is uploaded, Shrine automatically extracts metadata from it, and
|
4
|
-
stores them in the `Shrine::UploadedFile` object.
|
5
|
-
`size`, `filename` and `mime_type`.
|
4
|
+
stores them in the `Shrine::UploadedFile` object.
|
6
5
|
|
7
6
|
```rb
|
8
7
|
uploaded_file = uploader.upload(file)
|
@@ -14,6 +13,15 @@ uploaded_file.metadata #=>
|
|
14
13
|
# }
|
15
14
|
```
|
16
15
|
|
16
|
+
The following metadata is extracted by default:
|
17
|
+
|
18
|
+
| Key | Default source |
|
19
|
+
| :----- | :------ |
|
20
|
+
| `filename` | extracted from `io.original_filename` or `io.path` |
|
21
|
+
| `mime_type` | extracted from `io.content_type` |
|
22
|
+
| `size` | extracted from `io.size` |
|
23
|
+
|
24
|
+
|
17
25
|
Under the hood `Shrine#extract_metadata` is called, which you can also use
|
18
26
|
directly to extract metadata from any IO object.
|
19
27
|
|
@@ -107,7 +115,7 @@ require "mini_magick"
|
|
107
115
|
class ImageUploader < Shrine
|
108
116
|
plugin :add_metadata
|
109
117
|
|
110
|
-
add_metadata :exif do |io|
|
118
|
+
add_metadata :exif do |io, context|
|
111
119
|
Shrine.with_file(io) do |file|
|
112
120
|
begin
|
113
121
|
MiniMagick::Image.new(file.path).exif
|
data/doc/paperclip.md
CHANGED
@@ -73,8 +73,7 @@ Among other things, this allows you to use uploader classes standalone, which
|
|
73
73
|
gives you more power:
|
74
74
|
|
75
75
|
```rb
|
76
|
-
|
77
|
-
uploaded_file = uploader.upload(File.open("nature.jpg"))
|
76
|
+
uploaded_file = ImageUploader.upload(File.open("nature.jpg"), :store)
|
78
77
|
uploaded_file #=> #<Shrine::UploadedFile>
|
79
78
|
uploaded_file.url #=> "https://my-bucket.s3.amazonaws.com/store/kfds0lg9rer.jpg"
|
80
79
|
```
|
@@ -5,7 +5,7 @@ URL options that will be applied by default for uploaded files of specified
|
|
5
5
|
storages.
|
6
6
|
|
7
7
|
```rb
|
8
|
-
plugin :default_url_options, store: {
|
8
|
+
plugin :default_url_options, store: { expires_in: 24*60*60 }
|
9
9
|
```
|
10
10
|
|
11
11
|
You can also generate the default URL options dynamically by using a block,
|
@@ -163,7 +163,8 @@ end
|
|
163
163
|
# app/controllers/derivations_controller.rb
|
164
164
|
class DerivationsController < ApplicationController
|
165
165
|
def image
|
166
|
-
# we can perform authentication here
|
166
|
+
# ... we can perform authentication here ...
|
167
|
+
|
167
168
|
set_rack_response ImageUploader.derivation_response(request.env)
|
168
169
|
end
|
169
170
|
|
@@ -12,26 +12,18 @@ mounted on.
|
|
12
12
|
plugin :download_endpoint, prefix: "attachments"
|
13
13
|
```
|
14
14
|
|
15
|
-
The
|
15
|
+
The plugin adds a `Shrine.download_endpoint` method which returns a Rack
|
16
|
+
application that handles downloads using the `rack_response` plugin. You can
|
17
|
+
run this Rack app inside your app on the prefix that you specified:
|
16
18
|
|
17
19
|
```rb
|
18
|
-
# config.ru (Rack)
|
19
|
-
map "/attachments" do
|
20
|
-
run Shrine.download_endpoint
|
21
|
-
end
|
22
|
-
|
23
|
-
# OR
|
24
|
-
|
25
20
|
# config/routes.rb (Rails)
|
26
21
|
Rails.application.routes.draw do
|
22
|
+
# ...
|
27
23
|
mount Shrine.download_endpoint => "/attachments"
|
28
24
|
end
|
29
25
|
```
|
30
26
|
|
31
|
-
Any uploaded file can be downloaded through this endpoint. When a file is
|
32
|
-
requested, its content will be efficiently streamed from the storage into the
|
33
|
-
response body.
|
34
|
-
|
35
27
|
Links to the download endpoint are generated by calling
|
36
28
|
`UploadedFile#download_url` instead of the usual `UploadedFile#url`.
|
37
29
|
|
@@ -70,7 +62,7 @@ plugin :download_endpoint, download_options: {
|
|
70
62
|
You can also specify a proc to generate download options dynamically:
|
71
63
|
|
72
64
|
```rb
|
73
|
-
plugin :
|
65
|
+
plugin :download_endpoint, download_options: -> (uploaded_file, request) {
|
74
66
|
{
|
75
67
|
sse_customer_algorithm: "AES256",
|
76
68
|
sse_customer_key: "secret_key",
|
data/doc/plugins/parsed_json.md
CHANGED
@@ -8,4 +8,16 @@ assign cached files with hashes/arrays.
|
|
8
8
|
plugin :parsed_json
|
9
9
|
```
|
10
10
|
|
11
|
+
```rb
|
12
|
+
photo.image = {
|
13
|
+
"id" => "sdf90s2443.jpg",
|
14
|
+
"storage" => "cache",
|
15
|
+
"metadata" => {
|
16
|
+
"filename" => "nature.jpg",
|
17
|
+
"size" => 29475,
|
18
|
+
"mime_type" => "image/jpeg",
|
19
|
+
}
|
20
|
+
}
|
21
|
+
```
|
22
|
+
|
11
23
|
[parsed_json]: /lib/shrine/plugins/parsed_json.rb
|
@@ -17,15 +17,9 @@ a presign for the specified storage. You can run this Rack application inside
|
|
17
17
|
your app:
|
18
18
|
|
19
19
|
```rb
|
20
|
-
# config.ru (Rack)
|
21
|
-
map "/images/presign" do
|
22
|
-
run ImageUploader.presign_endpoint(:cache)
|
23
|
-
end
|
24
|
-
|
25
|
-
# OR
|
26
|
-
|
27
20
|
# config/routes.rb (Rails)
|
28
21
|
Rails.application.routes.draw do
|
22
|
+
# ...
|
29
23
|
mount ImageUploader.presign_endpoint(:cache) => "/images/presign"
|
30
24
|
end
|
31
25
|
```
|
@@ -55,6 +49,39 @@ single upload directly to the storage service, in JSON format.
|
|
55
49
|
}
|
56
50
|
```
|
57
51
|
|
52
|
+
## Calling from a controller
|
53
|
+
|
54
|
+
If you want to run additional code around the presign (such as authentication),
|
55
|
+
mounting the presign endpoint in your router might be limiting. You can instead
|
56
|
+
create a custom controller action and handle presign requests there using
|
57
|
+
`Shrine.presign_response`:
|
58
|
+
|
59
|
+
```rb
|
60
|
+
# config/routes.rb (Rails)
|
61
|
+
Rails.application.routes.draw do
|
62
|
+
# ...
|
63
|
+
post "/images/presign", to: "presigns#image"
|
64
|
+
end
|
65
|
+
```
|
66
|
+
```rb
|
67
|
+
# app/controllers/presigns_controller.rb (Rails)
|
68
|
+
class PresignsController < ApplicationController
|
69
|
+
def image
|
70
|
+
# ... we can perform authentication here ...
|
71
|
+
|
72
|
+
set_rack_response ImageUploader.presign_response(:cache, env)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def set_rack_response((status, headers, body))
|
78
|
+
self.status = status
|
79
|
+
self.headers.merge!(headers)
|
80
|
+
self.response_body = body
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
58
85
|
## Location
|
59
86
|
|
60
87
|
By default the generated location won't have any file extension, but you can
|
@@ -121,10 +148,12 @@ end
|
|
121
148
|
|
122
149
|
## Ad-hoc options
|
123
150
|
|
124
|
-
You can override any of the options above when creating the endpoint:
|
151
|
+
You can override any of the options above when creating the endpoint/response:
|
125
152
|
|
126
153
|
```rb
|
127
154
|
Shrine.presign_endpoint(:cache, presign_location: "${filename}")
|
155
|
+
# or
|
156
|
+
Shrine.presign_response(:cache, env, presign_location: "${filename}")
|
128
157
|
```
|
129
158
|
|
130
159
|
[presign_endpoint]: /lib/shrine/plugins/presign_endpoint.rb
|
@@ -11,18 +11,12 @@ plugin :upload_endpoint
|
|
11
11
|
The plugin adds a `Shrine.upload_endpoint` method which, given a storage
|
12
12
|
identifier, returns a Rack application that accepts multipart POST requests,
|
13
13
|
and uploads received files to the specified storage. You can run this Rack
|
14
|
-
|
14
|
+
application inside your app:
|
15
15
|
|
16
16
|
```rb
|
17
|
-
# config.ru (Rack)
|
18
|
-
map "/images/upload" do
|
19
|
-
run ImageUploader.upload_endpoint(:cache)
|
20
|
-
end
|
21
|
-
|
22
|
-
# OR
|
23
|
-
|
24
17
|
# config/routes.rb (Rails)
|
25
18
|
Rails.application.routes.draw do
|
19
|
+
# ...
|
26
20
|
mount ImageUploader.upload_endpoint(:cache) => "/images/upload"
|
27
21
|
end
|
28
22
|
```
|
@@ -52,6 +46,39 @@ This JSON string can now be assigned to an attachment attribute instead of a
|
|
52
46
|
raw file. In a form it can be written to a hidden attachment field, and then it
|
53
47
|
can be assigned as the attachment.
|
54
48
|
|
49
|
+
## Calling from a controller
|
50
|
+
|
51
|
+
If you want to run additional code around the upload (such as authentication),
|
52
|
+
mounting the upload endpoint in your router might be limiting. You can instead
|
53
|
+
create a custom controller action and handle upload requests there using
|
54
|
+
`Shrine.upload_response`:
|
55
|
+
|
56
|
+
```rb
|
57
|
+
# config/routes.rb (Rails)
|
58
|
+
Rails.application.routes.draw do
|
59
|
+
# ...
|
60
|
+
post "/images/upload", to: "uploads#image"
|
61
|
+
end
|
62
|
+
```
|
63
|
+
```rb
|
64
|
+
# app/controllers/uploads_controller.rb (Rails)
|
65
|
+
class UploadsController < ApplicationController
|
66
|
+
def image
|
67
|
+
# ... we can perform authentication here ...
|
68
|
+
|
69
|
+
set_rack_response ImageUploader.upload_response(:cache, env)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def set_rack_response((status, headers, body))
|
75
|
+
self.status = status
|
76
|
+
self.headers.merge!(headers)
|
77
|
+
self.response_body = body
|
78
|
+
end
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
55
82
|
## Limiting filesize
|
56
83
|
|
57
84
|
It's good practice to limit the accepted filesize of uploaded files. You can do
|
@@ -64,15 +91,6 @@ plugin :upload_endpoint, max_size: 20*1024*1024 # 20 MB
|
|
64
91
|
If the uploaded file is larger than the specified value, a `413 Payload Too
|
65
92
|
Large` response will be returned.
|
66
93
|
|
67
|
-
## Checksum
|
68
|
-
|
69
|
-
If you want the upload endpoint to verify the integrity of the uploaded file,
|
70
|
-
you can include the `Content-MD5` header in the request filled with the
|
71
|
-
base64-encoded MD5 hash of the file that was calculated prior to the upload,
|
72
|
-
and the endpoint will automatically use it to verify the uploaded data.
|
73
|
-
|
74
|
-
If the checksums don't match, a `460 Checksum Mismatch` response is returned.
|
75
|
-
|
76
94
|
## Context
|
77
95
|
|
78
96
|
The upload context will *not* contain `:record` and `:name` values, as the
|
@@ -96,10 +114,34 @@ You can also customize the upload itself via the `:upload` option:
|
|
96
114
|
|
97
115
|
```rb
|
98
116
|
plugin :upload_endpoint, upload: -> (io, context, request) do
|
99
|
-
Shrine.
|
117
|
+
Shrine.upload(io, :cache, context)
|
100
118
|
end
|
101
119
|
```
|
102
120
|
|
121
|
+
## URL
|
122
|
+
|
123
|
+
You can have the endpoint include the uploaded file URL in the response body
|
124
|
+
by specifying the `:url` option:
|
125
|
+
|
126
|
+
```rb
|
127
|
+
plugin :upload_endpoint, url: true
|
128
|
+
# or
|
129
|
+
plugin :upload_endpoint, url: { public: true }
|
130
|
+
# or
|
131
|
+
plugin :upload_endpoint, url: -> (uploaded_file, request) {
|
132
|
+
uploaded_file.url(**options)
|
133
|
+
}
|
134
|
+
```
|
135
|
+
|
136
|
+
In this case the response body will be:
|
137
|
+
|
138
|
+
```rb
|
139
|
+
{
|
140
|
+
"data": { "id": "...", "storage": "...", "metadata": {...} },
|
141
|
+
"url": "https://example.com/path/to/file"
|
142
|
+
}
|
143
|
+
```
|
144
|
+
|
103
145
|
## Response
|
104
146
|
|
105
147
|
The response returned by the endpoint can be customized via the
|
@@ -114,11 +156,22 @@ end
|
|
114
156
|
|
115
157
|
## Ad-hoc options
|
116
158
|
|
117
|
-
You can override any of the options above when creating the endpoint:
|
159
|
+
You can override any of the options above when creating the endpoint/response:
|
118
160
|
|
119
161
|
```rb
|
120
162
|
Shrine.upload_endpoint(:cache, max_size: 20*1024*1024)
|
163
|
+
# or
|
164
|
+
Shrine.upload_response(:cache, env, max_size: 20*1024*1024)
|
121
165
|
```
|
122
166
|
|
167
|
+
## Checksum
|
168
|
+
|
169
|
+
If you want the upload endpoint to verify the integrity of the uploaded file,
|
170
|
+
you can include the `Content-MD5` header in the request filled with the
|
171
|
+
base64-encoded MD5 hash of the file that was calculated prior to the upload,
|
172
|
+
and the endpoint will automatically use it to verify the uploaded data.
|
173
|
+
|
174
|
+
If the checksums don't match, a `460 Checksum Mismatch` response is returned.
|
175
|
+
|
123
176
|
[upload_endpoint]: /lib/shrine/plugins/upload_endpoint.rb
|
124
177
|
[Uppy]: https://uppy.io
|