Module: InstagramConnect::Media::Attaching
- Defined in:
- lib/instagram_connect/media/attaching.rb
Overview
Turns fetched bytes into a stored file, or into an honest reason why not.
The rule that matters here: when the declared Content-Type and the actual
magic bytes disagree, the magic bytes win. A Content-Type header is
metadata anyone can set; the first few bytes of the file are what the file
actually is. Trusting the header is how a host ends up serving an HTML
document from an tag.
Defined Under Namespace
Classes: Result
Class Method Summary collapse
- .allowed?(mime, config) ⇒ Boolean
- .evaluate(body:, declared_mime:, filename: nil, config: InstagramConnect.configuration) ⇒ Object
- .failure(reason) ⇒ Object
- .sniff(bytes, filename: nil, declared: nil) ⇒ Object
-
.within_size?(mime, bytes, config) ⇒ Boolean
Both Meta's per-type ceiling and the host's own cap have to hold.
Class Method Details
.allowed?(mime, config) ⇒ Boolean
41 42 43 44 |
# File 'lib/instagram_connect/media/attaching.rb', line 41 def allowed?(mime, config) allowed = config.allowed_media_types allowed.blank? || allowed.include?(mime) end |
.evaluate(body:, declared_mime:, filename: nil, config: InstagramConnect.configuration) ⇒ Object
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/instagram_connect/media/attaching.rb', line 20 def evaluate(body:, declared_mime:, filename: nil, config: InstagramConnect.configuration) bytes = body.to_s return failure("empty") if bytes.empty? mime = sniff(bytes, filename: filename, declared: declared_mime) return failure("type_not_allowed:#{mime}") unless allowed?(mime, config) return failure("too_large:#{bytes.bytesize}") unless within_size?(mime, bytes.bytesize, config) Result.new(ok: true, mime: mime, size: bytes.bytesize) end |
.failure(reason) ⇒ Object
52 53 54 |
# File 'lib/instagram_connect/media/attaching.rb', line 52 def failure(reason) Result.new(ok: false, error: reason) end |
.sniff(bytes, filename: nil, declared: nil) ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/instagram_connect/media/attaching.rb', line 31 def sniff(bytes, filename: nil, declared: nil) sniffed = ::Marcel::MimeType.for(StringIO.new(bytes), name: filename) # Marcel falls back to this when it recognises nothing, in which case the # declared type is the only information available and is better than # nothing. return declared.to_s.split(";").first.to_s.strip if sniffed == "application/octet-stream" && declared.present? sniffed end |
.within_size?(mime, bytes, config) ⇒ Boolean
Both Meta's per-type ceiling and the host's own cap have to hold. The host's exists so an adopter can be stricter than Meta, never looser.
48 49 50 |
# File 'lib/instagram_connect/media/attaching.rb', line 48 def within_size?(mime, bytes, config) Limits.within_size?(mime, bytes) && bytes <= config.media_max_bytes.to_i end |