shrine 3.7.1 → 3.8.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 +4 -4
- data/CHANGELOG.md +13 -1
- data/doc/release_notes/3.7.1.md +18 -0
- data/doc/release_notes/3.8.0.md +37 -0
- data/lib/shrine/plugins/derivatives.rb +1 -1
- data/lib/shrine/storage/file_system.rb +11 -2
- data/lib/shrine/storage/s3.rb +5 -10
- data/lib/shrine/version.rb +2 -2
- data/shrine.gemspec +2 -2
- metadata +7 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 55c3fc9bf7eb40700d2be0ee82900986c601b1b3449d5d5ee7b246546bfe5eb3
|
|
4
|
+
data.tar.gz: 11ffe3b196b79946c931f5a0e9538bda74cc4abd74711124509c76a13a5eaddc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 19585a7a2c486d43fb9be2abc84123adced4d18beebf50919938a9c631d16c0c2ecb15e777397b5b8a1642911171d328c55bf86769b9a31a4a3957cf3d8256d9
|
|
7
|
+
data.tar.gz: 1dfbb667941b5f2bfa1b035230f0b1fb809c59855fc253f8365394624cffd4e3078a0aa41188eb27c8e57be8d4243e45d5dcf56a83b4d9ea1900bf02fa340dc6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
## 3.8.0 (2026-06-24)
|
|
2
|
+
|
|
3
|
+
* `s3` – Use single-request uploads for smaller files again instead of always using multipart uploads (@janko)
|
|
4
|
+
|
|
5
|
+
* `derivatives` – Forward `Attacher#promote` options to `Attacher#upload_derivatives` (@milkcocoa)
|
|
6
|
+
|
|
7
|
+
* `file_system` – Prevent path traversal outside of the storage directory (@janko)
|
|
8
|
+
|
|
1
9
|
## 3.7.1 (2026-06-03)
|
|
2
10
|
|
|
3
|
-
* Update method signatures of some plugins to work around a Bootsnap bug causing a `wrong number of arguments` error
|
|
11
|
+
* Update method signatures of some plugins to work around a Bootsnap bug causing a `wrong number of arguments` error (@janko)
|
|
12
|
+
|
|
13
|
+
* `derivation_endpoint` – Add `:format` argument to `UploadedFile#derivation_url` for path extension (@janko)
|
|
14
|
+
|
|
15
|
+
* `rack_response` – Add `:etag` argument for setting a custom `ETag` (@camilohollanda)
|
|
4
16
|
|
|
5
17
|
## 3.7.0 (2026-05-27)
|
|
6
18
|
|
data/doc/release_notes/3.7.1.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
title: Shrine 3.7.1
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## New features
|
|
6
|
+
|
|
7
|
+
* The `derivation_endpoint` plugin now supports adding a file extension to the derivation URL path via the `:format` option on `UploadedFile#derivation_url`. Some HTTP clients and CDNs use the URL path extension to determine the content type of the response.
|
|
8
|
+
|
|
9
|
+
```rb
|
|
10
|
+
uploaded_file.derivation_url(:thumbnail, format: "jpg")
|
|
11
|
+
#=> ".../thumbnail/eyJpZCI6ImZvbyIsInN.jpg?signature=..."
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The extension is included in the URL signature, so it cannot be tampered with.
|
|
15
|
+
|
|
16
|
+
* The `rack_response` plugin now accepts an `:etag` option for setting a custom `ETag` header, overriding the default one Shrine generates.
|
|
17
|
+
|
|
18
|
+
```rb
|
|
19
|
+
response = uploaded_file.to_rack_response(etag: "my-custom-etag")
|
|
20
|
+
response[1]["ETag"] #=> "my-custom-etag"
|
|
21
|
+
```
|
|
22
|
+
|
|
5
23
|
## Bug fixes
|
|
6
24
|
|
|
7
25
|
* When initializing Shrine with the `activerecord` plugin, under Bootsnap 1.24.5 and Ruby 3.4.5 this would raise an error:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Shrine 3.8.0
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Security
|
|
6
|
+
|
|
7
|
+
* The `file_system` storage now prevents path traversal outside of the storage
|
|
8
|
+
directory. Previously, an id containing `../` sequences (e.g. coming from
|
|
9
|
+
attacker-controlled data) could resolve to a location outside of the
|
|
10
|
+
configured storage directory. Now `Shrine::Error` is raised whenever an id
|
|
11
|
+
would resolve outside of the storage directory:
|
|
12
|
+
|
|
13
|
+
```rb
|
|
14
|
+
storage = Shrine::Storage::FileSystem.new("uploads")
|
|
15
|
+
storage.open("../../etc/passwd") #~> Shrine::Error
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## New features
|
|
19
|
+
|
|
20
|
+
* The `derivatives` plugin now forwards options passed to `Attacher#promote`
|
|
21
|
+
into `Attacher#upload_derivatives`. This means options such as upload options
|
|
22
|
+
reach the derivatives upload as well, not just the main file.
|
|
23
|
+
|
|
24
|
+
```rb
|
|
25
|
+
attacher.promote(upload_options: { acl: "public-read" })
|
|
26
|
+
# the same options are now forwarded when uploading derivatives
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Other improvements
|
|
30
|
+
|
|
31
|
+
* The `s3` storage again uses single-request uploads for smaller files, instead
|
|
32
|
+
of always using multipart uploads. In Shrine 3.7.0, when a `TransferManager`
|
|
33
|
+
was available, it was used for uploads of any size, but `TransferManager`
|
|
34
|
+
uploads via multipart unconditionally, which is inefficient for smaller files.
|
|
35
|
+
Now files at or below the multipart threshold (`:upload`, 15MB by default) are
|
|
36
|
+
uploaded in a single request, and only larger files use multipart upload via
|
|
37
|
+
the `TransferManager` (falling back to the older API when it's not available).
|
|
@@ -113,9 +113,18 @@ class Shrine
|
|
|
113
113
|
end
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
# Returns the full path to the file.
|
|
116
|
+
# Returns the full path to the file. Raises Shrine::Error if the id would
|
|
117
|
+
# resolve to a location outside of the storage #directory (e.g. an id
|
|
118
|
+
# containing `../` path traversal sequences in attacker-controlled data).
|
|
117
119
|
def path(id)
|
|
118
|
-
directory.join(id.gsub("/", File::SEPARATOR))
|
|
120
|
+
path = directory.join(id.gsub("/", File::SEPARATOR))
|
|
121
|
+
expanded = path.expand_path
|
|
122
|
+
|
|
123
|
+
unless expanded == directory || expanded.to_s.start_with?("#{directory}#{File::SEPARATOR}")
|
|
124
|
+
raise Shrine::Error, "path #{id.inspect} resolves outside of the storage directory"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
path
|
|
119
128
|
end
|
|
120
129
|
|
|
121
130
|
protected
|
data/lib/shrine/storage/s3.rb
CHANGED
|
@@ -230,20 +230,15 @@ class Shrine
|
|
|
230
230
|
|
|
231
231
|
private
|
|
232
232
|
|
|
233
|
-
#
|
|
234
|
-
# Uses @transfer_manager, if defined, for any size upload.
|
|
235
|
-
# Falls back to the original code using the older, now depricated
|
|
236
|
-
# AWS APIs for users of older version of the AWS Gem.
|
|
237
|
-
# for multipart uploads of large files.
|
|
233
|
+
# Uploads the file to S3. Uses multipart upload for large files.
|
|
238
234
|
def put(io, id, **)
|
|
239
|
-
if @
|
|
235
|
+
if io.respond_to?(:size) && io.size && io.size <= @multipart_threshold[:upload]
|
|
236
|
+
object(id).put(body: io, **)
|
|
237
|
+
elsif @transfer_manager # multipart upload - transfer manager
|
|
240
238
|
@transfer_manager.upload_stream(bucket: bucket.name, key: object_key(id), part_size: part_size(io), **) do |write_stream|
|
|
241
239
|
IO.copy_stream(io, write_stream)
|
|
242
240
|
end
|
|
243
|
-
|
|
244
|
-
object(id).put(body: io, **)
|
|
245
|
-
else
|
|
246
|
-
# multipart upload old API
|
|
241
|
+
else # multipart upload - before transfer manager
|
|
247
242
|
object(id).upload_stream(part_size: part_size(io), **) do |write_stream|
|
|
248
243
|
IO.copy_stream(io, write_stream)
|
|
249
244
|
end
|
data/lib/shrine/version.rb
CHANGED
data/shrine.gemspec
CHANGED
|
@@ -67,10 +67,10 @@ direct uploads for fully asynchronous user experience.
|
|
|
67
67
|
|
|
68
68
|
# for instrumentation plugin
|
|
69
69
|
gem.add_development_dependency "dry-monitor"
|
|
70
|
-
gem.add_development_dependency "activesupport", RUBY_ENGINE == "jruby" ? "~>
|
|
70
|
+
gem.add_development_dependency "activesupport", RUBY_ENGINE == "jruby" ? "~> 8.0.0" : "~> 8.1"
|
|
71
71
|
|
|
72
72
|
# for ORM plugins
|
|
73
73
|
gem.add_development_dependency "sequel"
|
|
74
|
-
gem.add_development_dependency "activerecord", RUBY_ENGINE == "jruby" ? "~>
|
|
74
|
+
gem.add_development_dependency "activerecord", RUBY_ENGINE == "jruby" ? "~> 8.0.0" : "~> 8.1"
|
|
75
75
|
gem.add_development_dependency "sqlite3", "~> 2.1" unless RUBY_ENGINE == "jruby"
|
|
76
76
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shrine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Janko Marohnić
|
|
@@ -155,20 +155,6 @@ dependencies:
|
|
|
155
155
|
- - ">="
|
|
156
156
|
- !ruby/object:Gem::Version
|
|
157
157
|
version: '0'
|
|
158
|
-
- !ruby/object:Gem::Dependency
|
|
159
|
-
name: ruby-filemagic
|
|
160
|
-
requirement: !ruby/object:Gem::Requirement
|
|
161
|
-
requirements:
|
|
162
|
-
- - "~>"
|
|
163
|
-
- !ruby/object:Gem::Version
|
|
164
|
-
version: '0.7'
|
|
165
|
-
type: :development
|
|
166
|
-
prerelease: false
|
|
167
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
168
|
-
requirements:
|
|
169
|
-
- - "~>"
|
|
170
|
-
- !ruby/object:Gem::Version
|
|
171
|
-
version: '0.7'
|
|
172
158
|
- !ruby/object:Gem::Dependency
|
|
173
159
|
name: mime-types
|
|
174
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -301,14 +287,14 @@ dependencies:
|
|
|
301
287
|
requirements:
|
|
302
288
|
- - "~>"
|
|
303
289
|
- !ruby/object:Gem::Version
|
|
304
|
-
version:
|
|
290
|
+
version: 8.0.0
|
|
305
291
|
type: :development
|
|
306
292
|
prerelease: false
|
|
307
293
|
version_requirements: !ruby/object:Gem::Requirement
|
|
308
294
|
requirements:
|
|
309
295
|
- - "~>"
|
|
310
296
|
- !ruby/object:Gem::Version
|
|
311
|
-
version:
|
|
297
|
+
version: 8.0.0
|
|
312
298
|
- !ruby/object:Gem::Dependency
|
|
313
299
|
name: sequel
|
|
314
300
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -329,28 +315,14 @@ dependencies:
|
|
|
329
315
|
requirements:
|
|
330
316
|
- - "~>"
|
|
331
317
|
- !ruby/object:Gem::Version
|
|
332
|
-
version:
|
|
333
|
-
type: :development
|
|
334
|
-
prerelease: false
|
|
335
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
336
|
-
requirements:
|
|
337
|
-
- - "~>"
|
|
338
|
-
- !ruby/object:Gem::Version
|
|
339
|
-
version: '8.1'
|
|
340
|
-
- !ruby/object:Gem::Dependency
|
|
341
|
-
name: sqlite3
|
|
342
|
-
requirement: !ruby/object:Gem::Requirement
|
|
343
|
-
requirements:
|
|
344
|
-
- - "~>"
|
|
345
|
-
- !ruby/object:Gem::Version
|
|
346
|
-
version: '2.1'
|
|
318
|
+
version: 8.0.0
|
|
347
319
|
type: :development
|
|
348
320
|
prerelease: false
|
|
349
321
|
version_requirements: !ruby/object:Gem::Requirement
|
|
350
322
|
requirements:
|
|
351
323
|
- - "~>"
|
|
352
324
|
- !ruby/object:Gem::Version
|
|
353
|
-
version:
|
|
325
|
+
version: 8.0.0
|
|
354
326
|
description: |
|
|
355
327
|
Shrine is a toolkit for file attachments in Ruby applications. It supports
|
|
356
328
|
uploading, downloading, processing and deleting IO objects, backed by various
|
|
@@ -483,6 +455,7 @@ files:
|
|
|
483
455
|
- doc/release_notes/3.6.0.md
|
|
484
456
|
- doc/release_notes/3.7.0.md
|
|
485
457
|
- doc/release_notes/3.7.1.md
|
|
458
|
+
- doc/release_notes/3.8.0.md
|
|
486
459
|
- doc/retrieving_uploads.md
|
|
487
460
|
- doc/securing_uploads.md
|
|
488
461
|
- doc/storage/file_system.md
|
|
@@ -576,7 +549,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
576
549
|
- !ruby/object:Gem::Version
|
|
577
550
|
version: '0'
|
|
578
551
|
requirements: []
|
|
579
|
-
rubygems_version:
|
|
552
|
+
rubygems_version: 4.0.3
|
|
580
553
|
specification_version: 4
|
|
581
554
|
summary: Toolkit for file attachments in Ruby applications
|
|
582
555
|
test_files: []
|