shrine 2.19.3 → 3.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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +523 -41
  3. data/LICENSE.txt +1 -1
  4. data/README.md +83 -979
  5. data/doc/advantages.md +231 -204
  6. data/doc/attacher.md +304 -153
  7. data/doc/carrierwave.md +297 -226
  8. data/doc/changing_derivatives.md +308 -0
  9. data/doc/changing_location.md +103 -21
  10. data/doc/changing_storage.md +110 -0
  11. data/doc/creating_persistence_plugins.md +132 -0
  12. data/doc/creating_plugins.md +43 -23
  13. data/doc/creating_storages.md +19 -5
  14. data/doc/design.md +147 -97
  15. data/doc/direct_s3.md +38 -28
  16. data/doc/external/articles.md +63 -0
  17. data/doc/external/extensions.md +53 -0
  18. data/doc/external/misc.md +32 -0
  19. data/doc/getting_started.md +1156 -0
  20. data/doc/metadata.md +190 -109
  21. data/doc/multiple_files.md +93 -30
  22. data/doc/paperclip.md +384 -262
  23. data/doc/plugins/activerecord.md +177 -46
  24. data/doc/plugins/add_metadata.md +139 -38
  25. data/doc/plugins/atomic_helpers.md +217 -0
  26. data/doc/plugins/backgrounding.md +156 -98
  27. data/doc/plugins/cached_attachment_data.md +7 -5
  28. data/doc/plugins/column.md +121 -0
  29. data/doc/plugins/data_uri.md +23 -22
  30. data/doc/plugins/default_storage.md +36 -10
  31. data/doc/plugins/default_url.md +30 -13
  32. data/doc/plugins/delete_raw.md +4 -2
  33. data/doc/plugins/derivation_endpoint.md +186 -101
  34. data/doc/plugins/derivatives.md +839 -0
  35. data/doc/plugins/determine_mime_type.md +4 -2
  36. data/doc/plugins/download_endpoint.md +64 -8
  37. data/doc/plugins/dynamic_storage.md +5 -3
  38. data/doc/plugins/entity.md +263 -0
  39. data/doc/plugins/form_assign.md +55 -0
  40. data/doc/plugins/included.md +31 -8
  41. data/doc/plugins/infer_extension.md +21 -10
  42. data/doc/plugins/instrumentation.md +38 -16
  43. data/doc/plugins/keep_files.md +16 -17
  44. data/doc/plugins/metadata_attributes.md +42 -13
  45. data/doc/plugins/mirroring.md +118 -0
  46. data/doc/plugins/model.md +210 -0
  47. data/doc/plugins/module_include.md +4 -2
  48. data/doc/plugins/multi_cache.md +24 -0
  49. data/doc/plugins/persistence.md +101 -0
  50. data/doc/plugins/presign_endpoint.md +9 -4
  51. data/doc/plugins/pretty_location.md +16 -3
  52. data/doc/plugins/processing.md +4 -2
  53. data/doc/plugins/rack_file.md +8 -2
  54. data/doc/plugins/rack_response.md +6 -2
  55. data/doc/plugins/recache.md +4 -2
  56. data/doc/plugins/refresh_metadata.md +49 -9
  57. data/doc/plugins/remote_url.md +84 -47
  58. data/doc/plugins/remove_attachment.md +27 -6
  59. data/doc/plugins/remove_invalid.md +21 -6
  60. data/doc/plugins/restore_cached_data.md +11 -3
  61. data/doc/plugins/sequel.md +159 -35
  62. data/doc/plugins/signature.md +16 -5
  63. data/doc/plugins/store_dimensions.md +14 -2
  64. data/doc/plugins/tempfile.md +4 -2
  65. data/doc/plugins/type_predicates.md +96 -0
  66. data/doc/plugins/upload_endpoint.md +13 -13
  67. data/doc/plugins/upload_options.md +6 -4
  68. data/doc/plugins/{default_url_options.md → url_options.md} +9 -7
  69. data/doc/plugins/validation.md +97 -0
  70. data/doc/plugins/validation_helpers.md +16 -13
  71. data/doc/plugins/versions.md +15 -19
  72. data/doc/processing.md +438 -221
  73. data/doc/refile.md +188 -170
  74. data/doc/release_notes/1.0.0.md +4 -0
  75. data/doc/release_notes/1.1.0.md +6 -2
  76. data/doc/release_notes/1.2.0.md +4 -0
  77. data/doc/release_notes/1.3.0.md +4 -0
  78. data/doc/release_notes/1.4.0.md +4 -0
  79. data/doc/release_notes/1.4.1.md +4 -0
  80. data/doc/release_notes/1.4.2.md +4 -0
  81. data/doc/release_notes/2.0.0.md +4 -0
  82. data/doc/release_notes/2.0.1.md +4 -0
  83. data/doc/release_notes/2.1.0.md +5 -1
  84. data/doc/release_notes/2.1.1.md +4 -0
  85. data/doc/release_notes/2.10.0.md +4 -0
  86. data/doc/release_notes/2.10.1.md +4 -0
  87. data/doc/release_notes/2.11.0.md +4 -0
  88. data/doc/release_notes/2.12.0.md +4 -0
  89. data/doc/release_notes/2.13.0.md +4 -0
  90. data/doc/release_notes/2.14.0.md +5 -1
  91. data/doc/release_notes/2.15.0.md +11 -7
  92. data/doc/release_notes/2.16.0.md +4 -0
  93. data/doc/release_notes/2.17.0.md +4 -0
  94. data/doc/release_notes/2.18.0.md +4 -0
  95. data/doc/release_notes/2.19.0.md +6 -3
  96. data/doc/release_notes/2.2.0.md +4 -0
  97. data/doc/release_notes/2.3.0.md +4 -0
  98. data/doc/release_notes/2.3.1.md +4 -0
  99. data/doc/release_notes/2.4.0.md +4 -0
  100. data/doc/release_notes/2.4.1.md +4 -0
  101. data/doc/release_notes/2.5.0.md +4 -0
  102. data/doc/release_notes/2.6.0.md +4 -0
  103. data/doc/release_notes/2.6.1.md +4 -0
  104. data/doc/release_notes/2.7.0.md +4 -0
  105. data/doc/release_notes/2.8.0.md +4 -0
  106. data/doc/release_notes/2.9.0.md +4 -0
  107. data/doc/release_notes/3.0.0.md +981 -0
  108. data/doc/release_notes/3.0.1.md +22 -0
  109. data/doc/release_notes/3.1.0.md +73 -0
  110. data/doc/release_notes/3.2.0.md +96 -0
  111. data/doc/release_notes/3.2.1.md +31 -0
  112. data/doc/release_notes/3.2.2.md +14 -0
  113. data/doc/release_notes/3.3.0.md +105 -0
  114. data/doc/release_notes/3.4.0.md +35 -0
  115. data/doc/release_notes/3.5.0.md +63 -0
  116. data/doc/release_notes/3.6.0.md +23 -0
  117. data/doc/retrieving_uploads.md +5 -2
  118. data/doc/securing_uploads.md +60 -37
  119. data/doc/storage/file_system.md +20 -3
  120. data/doc/storage/memory.md +19 -0
  121. data/doc/storage/s3.md +122 -78
  122. data/doc/testing.md +141 -133
  123. data/doc/upgrading_to_3.md +708 -0
  124. data/doc/validation.md +54 -90
  125. data/lib/shrine/attacher.rb +292 -169
  126. data/lib/shrine/attachment.rb +13 -46
  127. data/lib/shrine/plugins/_persistence.rb +93 -0
  128. data/lib/shrine/plugins/activerecord.rb +77 -34
  129. data/lib/shrine/plugins/add_metadata.rb +25 -17
  130. data/lib/shrine/plugins/atomic_helpers.rb +119 -0
  131. data/lib/shrine/plugins/backgrounding.rb +77 -113
  132. data/lib/shrine/plugins/cached_attachment_data.rb +6 -15
  133. data/lib/shrine/plugins/column.rb +102 -0
  134. data/lib/shrine/plugins/data_uri.rb +38 -36
  135. data/lib/shrine/plugins/default_storage.rb +45 -15
  136. data/lib/shrine/plugins/default_url.rb +12 -24
  137. data/lib/shrine/plugins/default_url_options.rb +3 -30
  138. data/lib/shrine/plugins/delete_raw.rb +10 -16
  139. data/lib/shrine/plugins/derivation_endpoint.rb +130 -171
  140. data/lib/shrine/plugins/derivatives.rb +645 -0
  141. data/lib/shrine/plugins/determine_mime_type.rb +9 -21
  142. data/lib/shrine/plugins/download_endpoint.rb +118 -133
  143. data/lib/shrine/plugins/dynamic_storage.rb +5 -11
  144. data/lib/shrine/plugins/entity.rb +158 -0
  145. data/lib/shrine/plugins/form_assign.rb +108 -0
  146. data/lib/shrine/plugins/included.rb +6 -6
  147. data/lib/shrine/plugins/infer_extension.rb +17 -20
  148. data/lib/shrine/plugins/instrumentation.rb +59 -43
  149. data/lib/shrine/plugins/keep_files.rb +3 -15
  150. data/lib/shrine/plugins/metadata_attributes.rb +28 -19
  151. data/lib/shrine/plugins/mirroring.rb +142 -0
  152. data/lib/shrine/plugins/model.rb +160 -0
  153. data/lib/shrine/plugins/module_include.rb +3 -3
  154. data/lib/shrine/plugins/multi_cache.rb +27 -0
  155. data/lib/shrine/plugins/presign_endpoint.rb +27 -28
  156. data/lib/shrine/plugins/pretty_location.rb +15 -9
  157. data/lib/shrine/plugins/processing.rb +22 -9
  158. data/lib/shrine/plugins/rack_file.rb +2 -42
  159. data/lib/shrine/plugins/rack_response.rb +21 -10
  160. data/lib/shrine/plugins/recache.rb +6 -5
  161. data/lib/shrine/plugins/refresh_metadata.rb +13 -11
  162. data/lib/shrine/plugins/remote_url.rb +49 -49
  163. data/lib/shrine/plugins/remove_attachment.rb +12 -6
  164. data/lib/shrine/plugins/remove_invalid.rb +19 -8
  165. data/lib/shrine/plugins/restore_cached_data.rb +13 -7
  166. data/lib/shrine/plugins/sequel.rb +86 -36
  167. data/lib/shrine/plugins/signature.rb +10 -16
  168. data/lib/shrine/plugins/store_dimensions.rb +35 -40
  169. data/lib/shrine/plugins/tempfile.rb +1 -3
  170. data/lib/shrine/plugins/type_predicates.rb +113 -0
  171. data/lib/shrine/plugins/upload_endpoint.rb +28 -24
  172. data/lib/shrine/plugins/upload_options.rb +14 -15
  173. data/lib/shrine/plugins/url_options.rb +31 -0
  174. data/lib/shrine/plugins/validation.rb +80 -0
  175. data/lib/shrine/plugins/validation_helpers.rb +35 -58
  176. data/lib/shrine/plugins/versions.rb +107 -87
  177. data/lib/shrine/plugins.rb +22 -0
  178. data/lib/shrine/storage/file_system.rb +46 -64
  179. data/lib/shrine/storage/linter.rb +42 -7
  180. data/lib/shrine/storage/memory.rb +49 -0
  181. data/lib/shrine/storage/s3.rb +173 -160
  182. data/lib/shrine/uploaded_file.rb +32 -32
  183. data/lib/shrine/version.rb +3 -3
  184. data/lib/shrine.rb +87 -150
  185. data/shrine.gemspec +11 -12
  186. metadata +92 -82
  187. data/doc/migrating_storage.md +0 -76
  188. data/doc/plugins/backup.md +0 -31
  189. data/doc/plugins/copy.md +0 -24
  190. data/doc/plugins/delete_promoted.md +0 -12
  191. data/doc/plugins/direct_upload.md +0 -172
  192. data/doc/plugins/hooks.md +0 -58
  193. data/doc/plugins/logging.md +0 -42
  194. data/doc/plugins/migration_helpers.md +0 -60
  195. data/doc/plugins/moving.md +0 -19
  196. data/doc/plugins/multi_delete.md +0 -20
  197. data/doc/plugins/parallelize.md +0 -16
  198. data/doc/plugins/parsed_json.md +0 -23
  199. data/doc/regenerating_versions.md +0 -143
  200. data/lib/shrine/plugins/background_helpers.rb +0 -5
  201. data/lib/shrine/plugins/backup.rb +0 -90
  202. data/lib/shrine/plugins/copy.rb +0 -50
  203. data/lib/shrine/plugins/delete_promoted.rb +0 -20
  204. data/lib/shrine/plugins/direct_upload.rb +0 -217
  205. data/lib/shrine/plugins/hooks.rb +0 -90
  206. data/lib/shrine/plugins/logging.rb +0 -142
  207. data/lib/shrine/plugins/migration_helpers.rb +0 -70
  208. data/lib/shrine/plugins/moving.rb +0 -57
  209. data/lib/shrine/plugins/multi_delete.rb +0 -32
  210. data/lib/shrine/plugins/parallelize.rb +0 -78
  211. data/lib/shrine/plugins/parsed_json.rb +0 -29
@@ -1,4 +1,7 @@
1
- # Shrine::Storage::FileSystem
1
+ ---
2
+ id: file-system
3
+ title: File System
4
+ ---
2
5
 
3
6
  The FileSystem storage handles uploads to the filesystem, and it is most
4
7
  commonly initialized with a "base" folder and a "prefix":
@@ -64,7 +67,12 @@ File.exist?(file.path) #=> false
64
67
  ```
65
68
 
66
69
  If you want to make this option default, you can use the
67
- [`upload_options`][upload_options] plugin.
70
+ [`upload_options`][upload_options] plugin, provided that both `:cache` and
71
+ `:store` storages are `FileSystem`):
72
+
73
+ ```rb
74
+ plugin :upload_options, cache: { move: true }, store: { move: true }
75
+ ```
68
76
 
69
77
  ## Path
70
78
 
@@ -74,6 +82,15 @@ You can retrieve path to the file using `#path`:
74
82
  storage.path("image.jpg") #=> #<Pathname:public/image.jpg>
75
83
  ```
76
84
 
85
+ ## Deleting prefixed
86
+
87
+ If you want to delete all files in some directory, you can use
88
+ `FileSystem#delete_prefixed`:
89
+
90
+ ```rb
91
+ storage.delete_prefixed("some_directory/") # deletes all files in "some_directory/"
92
+ ```
93
+
77
94
  ## Clearing cache
78
95
 
79
96
  If you're using FileSystem as cache, you will probably want to periodically
@@ -111,4 +128,4 @@ also means that deploying the app can cancel someone's uploading if you're
111
128
  using backgrounding. Also, by default you cannot generate URLs to files in the
112
129
  "tmp" directory, but you can with the `download_endpoint` plugin.
113
130
 
114
- [upload_options]: /doc/plugins/upload_options.md#readme
131
+ [upload_options]: https://shrinerb.com/docs/plugins/upload_options
@@ -0,0 +1,19 @@
1
+ ---
2
+ title: Memory
3
+ ---
4
+
5
+ The Memory storage stores uploaded files in memory, which is suitable for
6
+ testing.
7
+
8
+ ```rb
9
+ Shrine.storages[:store] = Shrine::Storage::Memory.new
10
+ ```
11
+
12
+ By default, each storage instance uses a new Hash object for storing files,
13
+ but you can pass your own:
14
+
15
+ ```rb
16
+ my_store = Hash.new
17
+
18
+ Shrine.storages[:store] = Shrine::Storage::Memory.new(my_store)
19
+ ```
data/doc/storage/s3.md CHANGED
@@ -1,29 +1,41 @@
1
- # Shrine::Storage::S3
1
+ ---
2
+ title: AWS S3
3
+ ---
2
4
 
3
- The S3 storage handles uploads to Amazon S3 service, using the [aws-sdk-s3]
5
+ The S3 storage handles uploads to [AWS S3] service (or any s3-compatible
6
+ service such as [DigitalOcean Spaces] or [MinIO]). It requires the [aws-sdk-s3]
4
7
  gem:
5
8
 
6
9
  ```rb
10
+ # Gemfile
7
11
  gem "aws-sdk-s3", "~> 1.14"
8
12
  ```
9
13
 
10
- It can be initialized by providing the bucket name and credentials:
14
+ ## Initialization
15
+
16
+ The storage is initialized by providing your bucket name, region and
17
+ credentials:
11
18
 
12
19
  ```rb
13
20
  require "shrine/storage/s3"
14
21
 
15
22
  s3 = Shrine::Storage::S3.new(
16
23
  bucket: "my-app", # required
24
+ region: "eu-west-1", # required
17
25
  access_key_id: "abc",
18
26
  secret_access_key: "xyz",
19
- region: "eu-west-1",
20
27
  )
21
28
  ```
22
29
 
23
- The core features of this storage require the following AWS permissions:
24
- `s3:ListBucket`, `s3:PutObject`, `s3:GetObject`, and `s3:DeleteObject`. If you
25
- have additional upload options configured such as setting object ACLs, then
26
- additional permissions may be required.
30
+ > The storage requires the following AWS S3 permissions:
31
+ >
32
+ > * `s3:ListBucket` for the bucket resource
33
+ > * `s3:GetObject`, `s3:PutObject`, `s3:PutObjectAcl`, `s3:DeleteObject`,
34
+ > `s3:ListMultipartUploadParts` and `s3:AbortMultipartUpload` for the object
35
+ > resources
36
+
37
+ > The `:access_key_id` and `:secret_access_key` options is just one form of
38
+ > authentication, see the [AWS SDK docs][credentials] for more options.
27
39
 
28
40
  The storage exposes the underlying Aws objects:
29
41
 
@@ -43,14 +55,29 @@ s3.object("key") #=> #<Aws::S3::Object>
43
55
 
44
56
  By default, uploaded S3 objects will have private visibility, meaning they can
45
57
  only be accessed via signed expiring URLs generated using your private S3
46
- credentials. If you would like to generate public URLs, you can tell S3 storage
47
- to make uploads public:
58
+ credentials.
48
59
 
49
60
  ```rb
50
- s3 = Shrine::Storage::S3.new(public: true, **s3_options)
61
+ s3 = Shrine::Storage::S3.new(**s3_options)
62
+ s3.upload(io, "key") # uploads with default "private" ACL
63
+ s3.url("key") # https://my-bucket.s3.amazonaws.com/key?X-Amz-Expires=900&X-Amz-Signature=b22d37c37d...
64
+ ```
51
65
 
66
+ If you would like to generate public URLs, you can tell S3 storage to make
67
+ uploads public:
68
+
69
+ ```rb
70
+ s3 = Shrine::Storage::S3.new(public: true, **s3_options)
52
71
  s3.upload(io, "key") # uploads with "public-read" ACL
53
- s3.url("key") # returns public (unsigned) object URL
72
+ s3.url("key") # https://my-bucket.s3.amazonaws.com/key
73
+ ```
74
+
75
+ If you want to make only *some* uploads public, you can conditionally apply the
76
+ `:acl` upload option and `:public` URL option:
77
+
78
+ ```rb
79
+ Shrine.plugin :upload_options, store: -> (io, **) { { acl: "public-read" } }
80
+ Shrine.plugin :url_options, store: -> (io, **) { { public: true } }
54
81
  ```
55
82
 
56
83
  ## Prefix
@@ -78,13 +105,11 @@ You can also generate upload options per upload with the `upload_options`
78
105
  plugin
79
106
 
80
107
  ```rb
81
- class MyUploader < Shrine
82
- plugin :upload_options, store: -> (io, context) do
83
- if context[:version] == :thumb
84
- { acl: "public-read" }
85
- else
86
- { acl: "private" }
87
- end
108
+ Shrine.plugin :upload_options, store: -> (io, derivative: nil, **) do
109
+ if derivative == :thumb
110
+ { acl: "public-read" }
111
+ else
112
+ { acl: "private" }
88
113
  end
89
114
  end
90
115
  ```
@@ -95,22 +120,18 @@ or when using the uploader directly
95
120
  uploader.upload(file, upload_options: { acl: "private" })
96
121
  ```
97
122
 
98
- Note that, unlike the `:upload_options` storage option, upload options given on
99
- the uploader level won't be forwarded for generating presigns, since presigns
100
- are generated using the storage directly.
123
+ > Unlike the `:upload_options` storage option, upload options given on
124
+ the uploader level won't be forwarded for generating presigns, since presigns
125
+ are generated using the storage directly.
101
126
 
102
- ## URL options
127
+ ## Copy options
103
128
 
104
- Other than [`:host`](#url-host) and [`:public`](#public-uploads) URL options,
105
- all additional options are forwarded to [`Aws::S3::Object#presigned_url`].
129
+ If you wish to override options that are passed when copying objects from
130
+ temporary to permanent storage, you can pass `:copy_options`:
106
131
 
107
132
  ```rb
108
- s3.url(
109
- expires_in: 15,
110
- response_content_disposition: ContentDisposition.attachment("my-filename"),
111
- response_content_type: "foo/bar",
112
- # ...
113
- )
133
+ # Removes default :tagging_directive, which isn't supported by Cloudflare R2
134
+ Shrine::Storage::S3.new(copy_options: {}, **s3_options)
114
135
  ```
115
136
 
116
137
  ## URL Host
@@ -131,12 +152,14 @@ s3.url("image.jpg", host: "https://your-s3-host.com/prefix/") # needs to end wit
131
152
  ```
132
153
 
133
154
  To have the `:host` option passed automatically for every URL, use the
134
- `default_url_options` plugin.
155
+ `url_options` plugin:
135
156
 
136
157
  ```rb
137
- plugin :default_url_options, store: { host: "http://abc123.cloudfront.net" }
158
+ plugin :url_options, store: { host: "http://abc123.cloudfront.net" }
138
159
  ```
139
160
 
161
+ ### Signer
162
+
140
163
  If you would like to [serve private content via CloudFront], you need to sign
141
164
  the object URLs with a special signer, such as [`Aws::CloudFront::UrlSigner`]
142
165
  provided by the `aws-sdk-cloudfront` gem. The S3 storage initializer accepts a
@@ -155,13 +178,27 @@ Shrine::Storage::S3.new(signer: signer.method(:signed_url))
155
178
  Shrine::Storage::S3.new(signer: -> (url, **options) { signer.signed_url(url, **options) })
156
179
  ```
157
180
 
181
+ ## URL options
182
+
183
+ Other than `:host` and `:public` URL options, all additional `S3#url` options
184
+ are forwarded to [`Aws::S3::Object#presigned_url`].
185
+
186
+ ```rb
187
+ s3.url(
188
+ expires_in: 15,
189
+ response_content_disposition: ContentDisposition.attachment("my-filename"),
190
+ response_content_type: "foo/bar",
191
+ # ...
192
+ )
193
+ ```
194
+
158
195
  ## Presigns
159
196
 
160
- The `#presign` method can be used for generating paramters for direct uploads
161
- to Amazon S3:
197
+ The `S3#presign` method can be used for generating parameters for direct upload
198
+ to S3:
162
199
 
163
200
  ```rb
164
- s3.presign("/path/to/file") #=>
201
+ s3.presign("key") #=>
165
202
  # {
166
203
  # url: "https://my-bucket.s3.amazonaws.com/...",
167
204
  # fields: { ... }, # blank for PUT presigns
@@ -170,11 +207,25 @@ s3.presign("/path/to/file") #=>
170
207
  # }
171
208
  ```
172
209
 
173
- Additional presign options can be given in three places:
210
+ By default, parameters for a POST upload is generated, but you can also
211
+ generate PUT upload parameters:
212
+
213
+ ```rb
214
+ s3.presign("key", method: :put)
215
+ ```
216
+
217
+ Any additional options are forwarded to [`Aws::S3::Object#presigned_post`]
218
+ (for POST uploads) and [`Aws::S3::Object#presigned_url`] (for PUT uploads).
174
219
 
175
- * in `Storage::S3#presign` by forwarding options
176
- * in `:upload_options` option on this storage
177
- * in `presign_endpoint` plugin through `:presign_options`
220
+ ```rb
221
+ s3.presign("key", method: :put, content_disposition: "attachment; filename=my-file.txt") #=>
222
+ # {
223
+ # url: "https://my-bucket.s3.amazonaws.com/...",
224
+ # fields: {},
225
+ # headers: { "Content-Disposition" => "attachment; filename=my-file.txt" },
226
+ # method :put,
227
+ # }
228
+ ```
178
229
 
179
230
  ## Large files
180
231
 
@@ -182,33 +233,24 @@ The aws-sdk-s3 gem has the ability to automatically use multipart upload/copy
182
233
  for larger files, splitting the file into multiple chunks and uploading/copying
183
234
  them in parallel.
184
235
 
185
- By default any files that are uploaded will use the multipart upload if they're
186
- larger than 15MB, and any files that are copied will use the multipart copy if
187
- they're larger than 150MB, but you can change the thresholds via
188
- `:multipart_threshold`.
189
-
190
- ```rb
191
- thresholds = { upload: 30*1024*1024, copy: 200*1024*1024 }
192
- Shrine::Storage::S3.new(multipart_threshold: thresholds, **s3_options)
193
- ```
194
-
195
- If you want to change how many threads aws-sdk-s3 will use for multipart
196
- upload/copy, you can use the `upload_options` plugin to specify
197
- `:thread_count`.
236
+ By default, multipart upload will be used for files larger than 15MB, and
237
+ multipart copy for files larger than 100MB, but you can change the thresholds
238
+ via `:multipart_threshold`:
198
239
 
199
240
  ```rb
200
- plugin :upload_options, store: -> (io, context) do
201
- { thread_count: 5 }
202
- end
241
+ Shrine::Storage::S3.new(
242
+ multipart_threshold: { upload: 30*1024*1024, copy: 200*1024*1024 },
243
+ **s3_options,
244
+ )
203
245
  ```
204
246
 
205
247
  ## Encryption
206
248
 
207
- The easiest way to use server-side encryption for uploaded S3 objects is to
249
+ The easiest way to use **server-side** encryption for uploaded S3 objects is to
208
250
  configure default encryption for your S3 bucket. Alternatively, you can pass
209
251
  server-side encryption parameters to the API calls.
210
252
 
211
- The `#upload` method accepts `:sse_*` options:
253
+ The `S3#upload` method accepts `:sse_*` options:
212
254
 
213
255
  ```rb
214
256
  s3.upload(io, "key", sse_customer_algorithm: "AES256",
@@ -217,7 +259,7 @@ s3.upload(io, "key", sse_customer_algorithm: "AES256",
217
259
  ssekms_key_id: "key_id")
218
260
  ```
219
261
 
220
- The `#presign` method accepts `:server_side_encryption_*` options for POST
262
+ The `S3#presign` method accepts `:server_side_encryption_*` options for POST
221
263
  presigns, and the same `:sse_*` options as above for PUT presigns.
222
264
 
223
265
  ```rb
@@ -230,24 +272,19 @@ When downloading encrypted S3 objects, the same server-side encryption
230
272
  parameters need to be passed in.
231
273
 
232
274
  ```rb
233
- s3.download("key", sse_customer_algorithm: "AES256",
234
- sse_customer_key: "secret_key",
235
- sse_customer_key_md5: "secret_key_md5")
236
-
237
275
  s3.open("key", sse_customer_algorithm: "AES256",
238
276
  sse_customer_key: "secret_key",
239
277
  sse_customer_key_md5: "secret_key_md5")
240
278
  ```
241
279
 
242
- If you want to use client-side encryption instead, you can instantiate the
243
- storage with an `Aws::S3::Encryption::Client` instance.
280
+ **Client-side** encryption is supported as well:
244
281
 
245
282
  ```rb
246
- client = Aws::S3::Encryption::Client.new(
247
- kms_key_id: "alias/my-key"
248
- )
283
+ encryption_client = Aws::S3::EncryptionV2::Client.new(...)
284
+ s3 = Shrine::Storage::S3.new(client: encryption_client, **other_options)
249
285
 
250
- Shrine::Storage::S3(client: client, bucket: "my-bucket")
286
+ s3.upload(io, "key") # encrypts on upload
287
+ s3.open("key") # decrypts on download
251
288
  ```
252
289
 
253
290
  ## Accelerate endpoint
@@ -259,6 +296,15 @@ To use Amazon S3's [Transfer Acceleration] feature, set
259
296
  Shrine::Storage::S3.new(use_accelerate_endpoint: true, **other_options)
260
297
  ```
261
298
 
299
+ ## Deleting prefixed
300
+
301
+ If you want to delete all objects in some prefix, you can use
302
+ `S3#delete_prefixed`:
303
+
304
+ ```rb
305
+ s3.delete_prefixed("some_prefix/") # deletes all objects in "some_prefix/"
306
+ ```
307
+
262
308
  ## Clearing cache
263
309
 
264
310
  If you're using S3 as a cache, you will probably want to periodically delete
@@ -272,20 +318,18 @@ Alternatively you can periodically call the `#clear!` method:
272
318
  s3.clear! { |object| object.last_modified < Time.now - 7*24*60*60 }
273
319
  ```
274
320
 
275
- ## Request Rate and Performance Guidelines
276
-
277
- Amazon S3 automatically scales to high request rates. For example, your
278
- application can achieve at least 3,500 PUT/POST/DELETE and 5,500 GET requests
279
- per second per prefix in a bucket (a prefix is a top-level "directory" in the
280
- bucket). If your app needs to support higher request rates to S3 than that, you
281
- can scale exponentially by using more prefixes.
282
-
321
+ [AWS S3]: https://aws.amazon.com/s3/
322
+ [MinIO]: https://min.io/
323
+ [DigitalOcean Spaces]: https://www.digitalocean.com/products/spaces/
324
+ [aws-sdk-s3]: https://rubygems.org/gems/aws-sdk-s3
283
325
  [uploading]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#put-instance_method
284
326
  [copying]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#copy_from-instance_method
285
327
  [presigning]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_post-instance_method
286
328
  [`Aws::S3::Object#presigned_url`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method
287
- [aws-sdk-s3]: https://github.com/aws/aws-sdk-ruby/tree/master/gems/aws-sdk-s3
288
329
  [Transfer Acceleration]: http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
289
330
  [object lifecycle]: http://docs.aws.amazon.com/AmazonS3/latest/UG/lifecycle-configuration-bucket-no-versioning.html
290
331
  [serve private content via CloudFront]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
291
332
  [`Aws::CloudFront::UrlSigner`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CloudFront/UrlSigner.html
333
+ [credentials]: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html
334
+ [`Aws::S3::Object#presigned_post`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_post-instance_method
335
+ [`Aws::S3::Object#presigned_url`]: https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method