← Extractions

Handling File Uploads for the Modern Developer — Janko Marohnić at wroclove.rb 2019

Janko Marohnić, creator of the Shrine file-attachment library, walks through best practices for file uploads in Ruby web applications: server-side metadata/MIME/dimension validation, image processing with libvips vs ImageMagick, on-the-fly vs on-upload processing, direct uploads to S3 via Uppy, and resumable uploads using S3 multipart or the tus protocol. Q&A covers signed URLs for DDoS protection, orphan-file handling with temporary storage, testing with MinIO, and the potential of imageflow.

Model
claude-opus-4-7
Ingestion
6641b3bc
Input tokens
432,182
fresh
300,149
cached
124,119
cache write
7,914
Output tokens
19,008
Duration
293.2s
Roundtrips
11
Tool calls
30
Cost
$0.00
Nodes/edges extracted
38 / 66
Read set (nodes/edges)
96 / 2

Nodes (38)

create file (Unix command) tool
kind (empty) → tool
name (empty) → file (Unix command)
slug (empty) → file-unix-command
attrs (empty) → {"category" => "tool"}
description (empty) → The most popular UNIX tool for determining a file's type from its magic-bytes signature. The Shrine MIME-type plug-in...
short_description (empty) → UNIX command that identifies file type from magic bytes.
create Persist extracted metadata takeaway
kind (empty) → takeaway
name (empty) → Persist extracted metadata
slug (empty) → persist-extracted-metadata
attrs (empty) → {"type" => "recommendation"}
description (empty) → Any metadata you extract — common fields, dimensions, or custom per-type metadata like video duration — should be per...
short_description (empty) → Persist any extracted file metadata in the database for later retrieval.
create Magic bytes MIME detection concept
kind (empty) → concept
name (empty) → Magic bytes MIME detection
slug (empty) → magic-bytes-mime-detection
attrs (empty) → {"category" => "practice"}
description (empty) → Each file type has 'magic bytes' — a specific sequence of bytes at the beginning of the file that uniquely identifies...
short_description (empty) → Determining file type from a signature of bytes at the start of the file.
create Refile tool
kind (empty) → tool
name (empty) → Refile
slug (empty) → refile
attrs (empty) → {"category" => "library"}
description (empty) → Ruby file-attachment library released by the original author of CarrierWave. Attractive for its simplicity — it solve...
short_description (empty) → Ruby file-attachment library by CarrierWave's original author.
create imageflow project
kind (empty) → project
name (empty) → imageflow
slug (empty) → imageflow
attrs (empty) → {"status" => "active", "license" => "open-source"}
description (empty) → Image-processing project designed from a security-first perspective (in contrast to ImageMagick's security history an...
short_description (empty) → Security-first image processing library without Ruby bindings yet.
update Janko Marohnic person
attrs (empty) → {"role" => "Ruby on Rails developer", "country" => "Croatia"}
description Conference speaker. → Ruby on Rails developer from Croatia. Creator of the Shrine file-attachment library, previously a core maintainer of ...
short_description Conference speaker. → Ruby/Rails developer from Croatia, creator of the Shrine file-attachment library.
update Handling file uploads for modern developer talk
description Talk at wroclove.rb 2019. → wroclove.rb 2019 talk by Janko Marohnić sharing best practices for handling file uploads in web applications. Structu...
short_description Talk at wroclove.rb 2019. → Talk at wroclove.rb 2019 on best practices for file uploads in Ruby web apps.
create Shrine tool
kind (empty) → tool
name (empty) → Shrine
slug (empty) → shrine
attrs (empty) → {"category" => "library"}
description (empty) → Ruby file-attachment library created by Janko Marohnić after he forked from Refile. Design goals: work for any Ruby a...
short_description (empty) → Modular, framework-agnostic Ruby file-attachment library built on Rack.
create Paperclip tool
kind (empty) → tool
name (empty) → Paperclip
slug (empty) → paperclip
attrs (empty) → {"category" => "library"}
description (empty) → Ruby file-attachment library; first library Janko used. Keeps all file-uploading logic inside ActiveRecord models, wh...
short_description (empty) → Legacy Ruby file attachment library tied to ActiveRecord models.
create CarrierWave tool
kind (empty) → tool
name (empty) → CarrierWave
slug (empty) → carrierwave
attrs (empty) → {"category" => "library"}
description (empty) → Ruby file-attachment library that lets users move file-uploading logic into dedicated uploader classes outside of the...
short_description (empty) → Ruby file-attachment library using external uploader classes.
create image_processing gem tool
kind (empty) → tool
name (empty) → image_processing gem
slug (empty) → image_processing-gem
attrs (empty) → {"category" => "library"}
description (empty) → Ruby gem created by Janko Marohnić offering a functional image-processing API (source image in → processed file out)....
short_description (empty) → Functional Ruby gem for image processing with ImageMagick and libvips backends.
create ImageMagick tool
kind (empty) → tool
name (empty) → ImageMagick
slug (empty) → imagemagick
attrs (empty) → {"category" => "library"}
description (empty) → De-facto command-line image processing tool. Historically the default backend for Ruby image processing via the mini_...
short_description (empty) → Widely used image-manipulation command-line tool and library.
create libvips tool
kind (empty) → tool
name (empty) → libvips
slug (empty) → libvips
attrs (empty) → {"category" => "library"}
description (empty) → Image processing library (pronounced 'vips' or 'lib vips') that is often much faster than ImageMagick — 3–5× faster i...
short_description (empty) → High-performance image processing library with a narrower format scope.
create mini_magick tool
kind (empty) → tool
name (empty) → mini_magick
slug (empty) → mini_magick
attrs (empty) → {"category" => "library"}
description (empty) → Ruby wrapper over ImageMagick used as a backend in the image_processing gem.
short_description (empty) → Ruby wrapper around the ImageMagick command-line tool.
create Uppy tool
kind (empty) → tool
name (empty) → Uppy
slug (empty) → uppy
attrs (empty) → {"category" => "library"}
description (empty) → Modern, modular JavaScript file-upload library recommended by Janko regardless of backend. Ships built-in UI componen...
short_description (empty) → Modular modern JavaScript library for browser file uploads.
create tus protocol concept
kind (empty) → concept
name (empty) → tus protocol
slug (empty) → tus-protocol
attrs (empty) → {"category" => "protocol"}
description (empty) → Open protocol (tus.io) for resumable file uploads, created by the same team as Uppy. Despite sounding intimidating, i...
short_description (empty) → Open HTTP-based protocol for resumable file uploads.
create Transloadit company
kind (empty) → company
name (empty) → Transloadit
slug (empty) → transloadit
attrs (empty) → {"industry" => "file processing / uploads"}
description (empty) → Company that created both the Uppy JavaScript file-upload library and the tus.io resumable-upload HTTP protocol.
short_description (empty) → Company behind Uppy and the tus resumable-upload protocol.
create Amazon S3 tool
kind (empty) → tool
name (empty) → Amazon S3
slug (empty) → amazon-s3
attrs (empty) → {"category" => "service"}
description (empty) → Amazon Web Services object-storage service used as the typical cloud target for user file uploads. Supports direct br...
short_description (empty) → AWS object storage service commonly used for user uploads.
create MinIO tool
kind (empty) → tool
name (empty) → MinIO
slug (empty) → minio
attrs (empty) → {"category" => "service"}
description (empty) → Open-source tool that implements the Amazon S3 API over local storage. Recommended for testing file-upload code: poin...
short_description (empty) → Open-source, S3-compatible object storage server, useful for tests.
create Rack tool
kind (empty) → tool
name (empty) → Rack
slug (empty) → rack
attrs (empty) → {"category" => "library"}
description (empty) → Low-level web-server interface that is the basis of all Ruby web frameworks. Shrine is built on Rack rather than Rail...
short_description (empty) → Common Ruby web-server interface underlying all major Ruby web frameworks.
create Image bomb concept
kind (empty) → concept
name (empty) → Image bomb
slug (empty) → image-bomb
attrs (empty) → {"category" => "security"}
description (empty) → Attack vector (introduced to Janko by Evil Martians) in which an attacker crafts an image file that is small in file ...
short_description (empty) → Small-in-bytes image with huge pixel dimensions, used to crash processors.
create Direct Upload to Cloud concept
kind (empty) → concept
name (empty) → Direct Upload to Cloud
slug (empty) → direct-upload-to-cloud
attrs (empty) → {"category" => "pattern"}
description (empty) → Upload flow in which the browser fetches upload parameters (derived from server-only credentials) from the applicatio...
short_description (empty) → Uploading files directly from the browser to a cloud storage service.
create On-the-fly Processing concept
kind (empty) → concept
name (empty) → On-the-fly Processing
slug (empty) → on-the-fly-processing
attrs (empty) → {"category" => "pattern"}
description (empty) → Pattern where processing (e.g. image resizing) happens when a derivative URL is requested for the first time, then th...
short_description (empty) → Generating processed file derivatives when a URL is first requested.
create On-Upload Processing concept
kind (empty) → concept
name (empty) → On-Upload Processing
slug (empty) → on-upload-processing
attrs (empty) → {"category" => "pattern"}
description (empty) → Pattern where processing runs when the file is uploaded/attached, producing a collection of derivative files that are...
short_description (empty) → Running processing synchronously/asynchronously when a file is attached.
create Resumable Uploads concept
kind (empty) → concept
name (empty) → Resumable Uploads
slug (empty) → resumable-uploads
attrs (empty) → {"category" => "pattern"}
description (empty) → Technique that avoids restarting large uploads from scratch when a single HTTP request fails. The file is split into ...
short_description (empty) → Uploads split into chunks so interruptions don't restart from zero.
create Orphan Files concept
kind (empty) → concept
name (empty) → Orphan Files
slug (empty) → orphan-files
attrs (empty) → {"category" => "pattern"}
description (empty) → Files that a user uploaded but that never got attached to a persistent record — e.g. because the user abandoned the f...
short_description (empty) → Uploaded files that are never attached to any record.
create Signed On-the-fly URLs takeaway
kind (empty) → takeaway
name (empty) → Signed On-the-fly URLs
slug (empty) → signed-on-the-fly-urls
attrs (empty) → {"type" => "recommendation"}
description (empty) → To defend against attackers requesting many variants of the same file to overload on-the-fly processing, the server s...
short_description (empty) → Sign processing URLs with a server-only secret to prevent DDoS.
create Validate MIME type from file content takeaway
kind (empty) → takeaway
name (empty) → Validate MIME type from file content
slug (empty) → validate-mime-type-from-file-content
attrs (empty) → {"type" => "recommendation"}
description (empty) → The Content-Type header sent by the browser is derived from the file extension and can be spoofed. Validate MIME type...
short_description (empty) → Use magic bytes, not the Content-Type header, to validate uploaded MIME types.
create Validate image dimensions to prevent image bombs takeaway
kind (empty) → takeaway
name (empty) → Validate image dimensions to prevent image bombs
slug (empty) → validate-image-dimensions-to-prevent-image-bombs
attrs (empty) → {"type" => "recommendation"}
description (empty) → Validating only file size is insufficient: an attacker can craft an image that is tiny on disk but huge in pixels (an...
short_description (empty) → Validate dimensions (not just file size) to defeat image-bomb attacks.
create Prefer libvips over ImageMagick takeaway
kind (empty) → takeaway
name (empty) → Prefer libvips over ImageMagick
slug (empty) → prefer-libvips-over-imagemagick
attrs (empty) → {"type" => "recommendation"}
description (empty) → Benchmarks of 500×500 thumbnail generation show libvips is 3–5× faster than ImageMagick depending on source size, whi...
short_description (empty) → libvips is typically 3–5× faster than ImageMagick for web image processing.
create Use Uppy regardless of backend takeaway
kind (empty) → takeaway
name (empty) → Use Uppy regardless of backend
slug (empty) → use-uppy-regardless-of-backend
attrs (empty) → {"type" => "recommendation"}
description (empty) → Recommended even if you are not using Shrine: Uppy provides built-in UI components, easy direct uploads to S3, multip...
short_description (empty) → Uppy gives you great UI and direct-to-S3 support out of the box — use it regardless of Ruby upload library.
create Use MinIO for S3 testing takeaway
kind (empty) → takeaway
name (empty) → Use MinIO for S3 testing
slug (empty) → use-minio-for-s3-testing
attrs (empty) → {"type" => "recommendation"}
description (empty) → Instead of replacing S3 with a different local storage in tests, run MinIO as a separate service and point the AWS SD...
short_description (empty) → Run MinIO locally so tests use the real S3 API against local storage.
create Use temporary storage to avoid orphan files takeaway
kind (empty) → takeaway
name (empty) → Use temporary storage to avoid orphan files
slug (empty) → use-temporary-storage-to-avoid-orphan-files
attrs (empty) → {"type" => "recommendation"}
description (empty) → Shrine requires a temporary storage (the 'cache' directory used by its upload endpoints) separate from permanent stor...
short_description (empty) → Use separate temporary + permanent storages, and auto-expire temp uploads.
create DDoS risk of on-the-fly processing question
kind (empty) → question
name (empty) → DDoS risk of on-the-fly processing
slug (empty) → ddos-risk-of-on-the-fly-processing
attrs (empty) → {"answer_summary" => "Sign derivative URLs with a server-only secret; CDN caches legitimate variants."}
description (empty) → Audience question: on-the-fly processing is nice because it doesn't load the server upfront, but seems prone to DDoS ...
short_description (empty) → How to defend on-the-fly processing from attackers requesting many variants.
create Orphan files from async uploads question
kind (empty) → question
name (empty) → Orphan files from async uploads
slug (empty) → orphan-files-from-async-uploads
attrs (empty) → {"answer_summary" => "Use temporary ('cache') storage with auto-expiration and separate permanent storage."}
description (empty) → Audience question: async uploads aren't transactional — a user can submit a huge file but never finish filling in met...
short_description (empty) → How to handle users who upload a file but never submit the form.
create Local storage for tests question
kind (empty) → question
name (empty) → Local storage for tests
slug (empty) → local-storage-for-tests
attrs (empty) → {"answer_summary" => "Run MinIO — an S3-compatible server — locally and point the SDK at it."}
description (empty) → Audience question: how to test uploads without hitting real S3 — ideally backed by local storage. Answer: run MinIO a...
short_description (empty) → How to substitute S3 for local storage during tests.
create Adding imageflow to image_processing gem question
kind (empty) → question
name (empty) → Adding imageflow to image_processing gem
slug (empty) → adding-imageflow-to-image_processing-gem
attrs (empty) → {"answer_summary" => "Yes, wants to add support but needs someone to write Ruby bindings first."}
description (empty) → Audience question: ImageMagick has a history of security vulnerabilities and libvips wasn't built with security in mi...
short_description (empty) → Will imageflow (security-first) be supported as a backend?
update Active Storage tool
description Rails 5.2 feature for managing image/file uploads. The talk recommends using it to generate multiple image output for... → Rails 5.2 feature for managing image/file uploads. The talk recommends using it to generate multiple image output for...

Edges (66)

update Janko Marohnic → authored → Handling file uploads for modern developer
context (empty) → Speaker of the wroclove.rb 2019 talk.
update Handling file uploads for modern developer → presented_at → wroclove.rb 2019
context (empty) → Delivered at wroclove.rb 2019.
create Janko Marohnic → works_on → Shrine
attrs (empty) → {"role" => "creator"}
context (empty) → Creator of the Shrine file-attachment library.
relation (empty) → works_on
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
create Janko Marohnic → works_on → image_processing gem
attrs (empty) → {"role" => "creator"}
context (empty) → Created the image_processing gem to avoid another homegrown in-gem solution.
relation (empty) → works_on
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
create Janko Marohnic → works_on → Refile
attrs (empty) → {"role" => "former core maintainer"}
context (empty) → Was accepted as a core maintainer of Refile before forking off to build Shrine.
relation (empty) → works_on
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → a6722382-f5e1-4649-b3cc-3de24fcfd760
create Janko Marohnic → uses → Paperclip
context (empty) → First file-attachment library he used before switching away.
relation (empty) → uses
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 0beca60d-2b1e-4b91-af46-62bbefeae00e
create Janko Marohnic → uses → CarrierWave
context (empty) → Switched to CarrierWave from Paperclip to move upload logic out of the model.
relation (empty) → uses
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → e67c4ddf-6686-464e-a1f7-e6eb5823e969
create Handling file uploads for modern developer → about → Shrine
context (empty) → The talk centers on file-upload best practices as implemented in Shrine.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
create Handling file uploads for modern developer → about → Paperclip
context (empty) → Discussed as part of the Ruby file-upload landscape and the speaker's history.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 0beca60d-2b1e-4b91-af46-62bbefeae00e
create Handling file uploads for modern developer → about → CarrierWave
context (empty) → Discussed as part of the Ruby file-upload landscape and its missing built-ins.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → e67c4ddf-6686-464e-a1f7-e6eb5823e969
create Handling file uploads for modern developer → about → Refile
context (empty) → Discussed as the opinionated library Shrine was forked from.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → a6722382-f5e1-4649-b3cc-3de24fcfd760
create Handling file uploads for modern developer → about → Active Storage
context (empty) → Compared with Shrine, especially regarding URL-encoded processing and bundled JavaScript.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 2834fe94-5598-4e2b-ae0f-322d38f50180
create Handling file uploads for modern developer → about → image_processing gem
context (empty) → Janko presents the gem as the recommended image-processing integration.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
create Handling file uploads for modern developer → about → ImageMagick
context (empty) → Discussed as traditional backend behind mini_magick with security concerns.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → c42e5c02-4db3-46df-a236-05dfb0b36c0e
create Handling file uploads for modern developer → about → libvips
context (empty) → Recommended as a faster alternative backend to ImageMagick.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 96f8f979-7089-4c88-81ce-3f27a469ba40
create Handling file uploads for modern developer → about → Uppy
context (empty) → Recommended JavaScript library for the upload UX.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 5e2fe007-70c5-4f6a-8a1b-f13d2de37dd2
create Handling file uploads for modern developer → about → tus protocol
context (empty) → Covered as the generic resumable-upload protocol option.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → da2b734f-353a-4ae9-846c-b04f0d45239d
create Handling file uploads for modern developer → about → Amazon S3
context (empty) → Primary cloud storage target for direct and multipart resumable uploads.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 594c0c6b-0a58-4e01-91ef-f4185be0190f
create Handling file uploads for modern developer → about → Rack
context (empty) → Shrine is built on Rack to be framework-agnostic.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → ce1ce440-06a4-4527-a39f-556a7b635334
create Handling file uploads for modern developer → about → Magic bytes MIME detection
context (empty) → Explains validating MIME from content via magic bytes.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 9a7ccddb-2317-4082-a5d4-d2cb3d3e0980
create Handling file uploads for modern developer → about → Image bomb
context (empty) → Explains why dimension validation is needed.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 1777119f-2f04-450a-9120-99d97bfb235c
create Handling file uploads for modern developer → about → Direct Upload to Cloud
context (empty) → Covers direct-to-S3 uploads via Uppy.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 15f2264a-7c46-4039-b990-d6cbfefdac6f
create Handling file uploads for modern developer → about → On-the-fly Processing
context (empty) → One of two processing strategies compared.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 7daabd3c-3fb2-4da4-a2b8-c22bbdd08b8b
create Handling file uploads for modern developer → about → On-Upload Processing
context (empty) → One of two processing strategies compared.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → c81d07bd-dae5-4aa4-90cf-b6c87a670311
create Handling file uploads for modern developer → about → Resumable Uploads
context (empty) → Covers resumable uploads via S3 multipart and tus.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → 5a40519e-aee5-4ef3-a536-4d0f7e21b3b8
create Handling file uploads for modern developer → about → Orphan Files
context (empty) → Discussed via Shrine's temporary/permanent storage separation.
relation (empty) → about
source_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
target_node_id (empty) → ce344d4f-cf01-449c-8608-80bf4084d745
create Shrine → uses → Rack
context (empty) → Shrine is built on Rack to work with any Ruby web framework.
relation (empty) → uses
source_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
target_node_id (empty) → ce1ce440-06a4-4527-a39f-556a7b635334
create image_processing gem → uses → ImageMagick
context (empty) → Ships a mini_magick wrapper backend.
relation (empty) → uses
source_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
target_node_id (empty) → c42e5c02-4db3-46df-a236-05dfb0b36c0e
create image_processing gem → uses → libvips
context (empty) → Ships a libvips wrapper backend as a faster alternative.
relation (empty) → uses
source_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
target_node_id (empty) → 96f8f979-7089-4c88-81ce-3f27a469ba40
create image_processing gem → uses → mini_magick
context (empty) → Uses mini_magick under the hood for the ImageMagick backend.
relation (empty) → uses
source_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
target_node_id (empty) → 183bd7c6-9712-4f4e-8f5a-b29ca8b7fe5c
create Active Storage → uses → image_processing gem
context (empty) → Active Storage adopted the image_processing gem as of Rails 6.0.
relation (empty) → uses
source_node_id (empty) → 2834fe94-5598-4e2b-ae0f-322d38f50180
target_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
create Shrine → related_to → Uppy
context (empty) → Shrine integrates cleanly with Uppy; Uppy plug-ins hit Shrine's upload endpoint.
relation (empty) → related_to
source_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
target_node_id (empty) → 5e2fe007-70c5-4f6a-8a1b-f13d2de37dd2
create Shrine → related_to → tus protocol
context (empty) → A Ruby tus-server gem implements the endpoints Uppy's tus client needs and is compatible with Shrine.
relation (empty) → related_to
source_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
target_node_id (empty) → da2b734f-353a-4ae9-846c-b04f0d45239d
create Uppy → uses → tus protocol
context (empty) → Uppy ships a tus plug-in; both are by Transloadit.
relation (empty) → uses
source_node_id (empty) → 5e2fe007-70c5-4f6a-8a1b-f13d2de37dd2
target_node_id (empty) → da2b734f-353a-4ae9-846c-b04f0d45239d
create Transloadit → works_on → Uppy
context (empty) → Transloadit created Uppy.
relation (empty) → works_on
source_node_id (empty) → 7605debe-cba1-4f05-85d1-1399a06a0176
target_node_id (empty) → 5e2fe007-70c5-4f6a-8a1b-f13d2de37dd2
create Transloadit → works_on → tus protocol
context (empty) → Transloadit created the tus resumable-upload protocol.
relation (empty) → works_on
source_node_id (empty) → 7605debe-cba1-4f05-85d1-1399a06a0176
target_node_id (empty) → da2b734f-353a-4ae9-846c-b04f0d45239d
create Janko Marohnic → uses → Shrine
context (empty) → Uses Shrine as the library the talk demonstrates.
relation (empty) → uses
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 5444b3f9-97b9-43d8-8b17-416d0aca2bef
create Janko Marohnic → recommends → Uppy
context (empty) → Recommends Uppy regardless of which Ruby upload library you use.
relation (empty) → recommends
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 5e2fe007-70c5-4f6a-8a1b-f13d2de37dd2
create Janko Marohnic → recommends → libvips
context (empty) → Recommends libvips as a faster, full-featured alternative to ImageMagick.
relation (empty) → recommends
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 96f8f979-7089-4c88-81ce-3f27a469ba40
create Janko Marohnic → recommends → MinIO
context (empty) → Recommends MinIO for local S3-compatible testing.
relation (empty) → recommends
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → 7cae96b0-814d-4b1c-b3e2-3876b2fb7040
create Janko Marohnic → recommends → tus protocol
context (empty) → Recommends tus for language-agnostic resumable uploads.
relation (empty) → recommends
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → da2b734f-353a-4ae9-846c-b04f0d45239d
create Janko Marohnic → recommends → imageflow
context (empty) → Has backed imageflow and wants to support it once Ruby bindings exist.
relation (empty) → recommends
source_node_id (empty) → e82a1b94-3739-416d-ac98-21837af1e1e0
target_node_id (empty) → c5e0305c-752f-48df-b225-e5f79cf7490c
create Magic bytes MIME detection → related_to → file (Unix command)
context (empty) → The UNIX `file` command is the canonical tool for detecting type from magic bytes.
relation (empty) → related_to
source_node_id (empty) → 9a7ccddb-2317-4082-a5d4-d2cb3d3e0980
target_node_id (empty) → 11d2d3e8-bf1e-4a05-a8a1-7151abfd3f39
create Signed On-the-fly URLs → from_talk → Handling file uploads for modern developer
context (empty) → Takeaway from the Q&A on DDoS protection.
relation (empty) → from_talk
source_node_id (empty) → 0725cc59-6817-4f1c-b087-3d975011e81a
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Validate MIME type from file content → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the validation section.
relation (empty) → from_talk
source_node_id (empty) → e18e1c40-0d24-4a67-8aba-6eba07eebc53
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Validate image dimensions to prevent image bombs → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the validation section.
relation (empty) → from_talk
source_node_id (empty) → bc089c32-9e24-4ea1-aee4-61c262ccc036
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Persist extracted metadata → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the metadata recap.
relation (empty) → from_talk
source_node_id (empty) → 90cfa381-f159-4092-ae5c-a27f116a0202
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Prefer libvips over ImageMagick → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the image-processing section.
relation (empty) → from_talk
source_node_id (empty) → 0e20dc3b-65e8-425d-b077-68f32777a6fa
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Use Uppy regardless of backend → from_talk → Handling file uploads for modern developer
context (empty) → Explicit recommendation from the upload UX section.
relation (empty) → from_talk
source_node_id (empty) → bfb695a0-b7f8-4888-a65a-347efb7fb39d
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Use MinIO for S3 testing → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the Q&A on testing.
relation (empty) → from_talk
source_node_id (empty) → 268fe7e4-b401-4a32-83b6-8a75012dd8ee
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Use temporary storage to avoid orphan files → from_talk → Handling file uploads for modern developer
context (empty) → Recommendation from the Q&A on async upload transactionality.
relation (empty) → from_talk
source_node_id (empty) → f4044aff-f5bc-462c-a0ed-d5ec6ddc5483
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Validate image dimensions to prevent image bombs → about → Image bomb
context (empty) → Explicitly addresses the image-bomb attack.
relation (empty) → about
source_node_id (empty) → bc089c32-9e24-4ea1-aee4-61c262ccc036
target_node_id (empty) → 1777119f-2f04-450a-9120-99d97bfb235c
create Validate MIME type from file content → about → Magic bytes MIME detection
context (empty) → Based on magic-byte detection.
relation (empty) → about
source_node_id (empty) → e18e1c40-0d24-4a67-8aba-6eba07eebc53
target_node_id (empty) → 9a7ccddb-2317-4082-a5d4-d2cb3d3e0980
create Signed On-the-fly URLs → about → On-the-fly Processing
context (empty) → Addresses DDoS risk specific to on-the-fly processing.
relation (empty) → about
source_node_id (empty) → 0725cc59-6817-4f1c-b087-3d975011e81a
target_node_id (empty) → 7daabd3c-3fb2-4da4-a2b8-c22bbdd08b8b
create Use MinIO for S3 testing → about → MinIO
context (empty) → About using MinIO for tests.
relation (empty) → about
source_node_id (empty) → 268fe7e4-b401-4a32-83b6-8a75012dd8ee
target_node_id (empty) → 7cae96b0-814d-4b1c-b3e2-3876b2fb7040
create Use temporary storage to avoid orphan files → about → Orphan Files
context (empty) → Avoiding orphan files via temp storage.
relation (empty) → about
source_node_id (empty) → f4044aff-f5bc-462c-a0ed-d5ec6ddc5483
target_node_id (empty) → ce344d4f-cf01-449c-8608-80bf4084d745
create DDoS risk of on-the-fly processing → asked_at → Handling file uploads for modern developer
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → 3664f46c-a1dc-4b3c-b12f-a19a7f99281b
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Orphan files from async uploads → asked_at → Handling file uploads for modern developer
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → d2d848a6-2ab6-43a1-8909-22e296742fcf
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Local storage for tests → asked_at → Handling file uploads for modern developer
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → a3643253-0fbd-42f5-9c5a-74c344899820
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create Adding imageflow to image_processing gem → asked_at → Handling file uploads for modern developer
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → f909b3e6-4c1b-4fb6-969a-12c82eb0669c
target_node_id (empty) → 91812ff8-0a4f-40ed-9b15-b5432c90b0f6
create DDoS risk of on-the-fly processing → about → On-the-fly Processing
context (empty) → Question is specifically about on-the-fly processing.
relation (empty) → about
source_node_id (empty) → 3664f46c-a1dc-4b3c-b12f-a19a7f99281b
target_node_id (empty) → 7daabd3c-3fb2-4da4-a2b8-c22bbdd08b8b
create Orphan files from async uploads → about → Orphan Files
context (empty) → Question is about orphan-file risk with async uploads.
relation (empty) → about
source_node_id (empty) → d2d848a6-2ab6-43a1-8909-22e296742fcf
target_node_id (empty) → ce344d4f-cf01-449c-8608-80bf4084d745
create Local storage for tests → about → MinIO
context (empty) → Answer recommends MinIO.
relation (empty) → about
source_node_id (empty) → a3643253-0fbd-42f5-9c5a-74c344899820
target_node_id (empty) → 7cae96b0-814d-4b1c-b3e2-3876b2fb7040
create Adding imageflow to image_processing gem → about → imageflow
context (empty) → Asked about adding imageflow support.
relation (empty) → about
source_node_id (empty) → f909b3e6-4c1b-4fb6-969a-12c82eb0669c
target_node_id (empty) → c5e0305c-752f-48df-b225-e5f79cf7490c
create Adding imageflow to image_processing gem → about → image_processing gem
context (empty) → Asked about extending the image_processing gem.
relation (empty) → about
source_node_id (empty) → f909b3e6-4c1b-4fb6-969a-12c82eb0669c
target_node_id (empty) → b826040d-1049-42c8-a688-1d422943537b
create Evil Martians → related_to → Image bomb
context (empty) → Introduced Janko to the image-bomb attack idea.
relation (empty) → related_to
source_node_id (empty) → 4f724c14-2ccc-4769-bd4a-0719505d1188
target_node_id (empty) → 1777119f-2f04-450a-9120-99d97bfb235c

Read set

96 nodes

tool Active Storage search_nodes talk Handling file uploads for modern developer search_nodes+get_node_edges tool Rails 5.2 search_nodes talk Orchestrating video transcoding in ruby search_nodes concept ObjectSpace heap dumps search_nodes tool Reform search_nodes person Janko Marohnic search_nodes+get_node_edges concept Real-time Web Applications search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2026 search_nodes event wroclove.rb 2025 search_nodes talk Development with axioms search_nodes talk Building LLM powered applications in Ruby search_nodes talk Spice up your life with eql search_nodes tool Babel search_nodes tool Flow search_nodes tool WebP search_nodes tool Brotli search_nodes tool webpagetest.org search_nodes tool heapy search_nodes tool gzip search_nodes takeaway Upgrade Ruby version for free speed search_nodes takeaway Sign serverlessforruby.org petition search_nodes tool HTTP/2 search_nodes concept HTTP/2 Server Push search_nodes concept JSON API search_nodes project AnyCable search_nodes resource Rocket Real-Time Benchmark search_nodes concept Zero-Disconnect Deployment search_nodes concept WebSockets search_nodes talk Multi-region data governance in Rails application search_nodes talk When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails search_nodes tool JSON API Resources search_nodes tool ThingSpeak search_nodes resource serverlessforruby.org Petition search_nodes tool GraphQL search_nodes tool Heroku search_nodes concept Function as a Service search_nodes concept Serverless search_nodes concept Event Store search_nodes takeaway Contribute to Arkency aggregates repository search_nodes tool Ruby on Rails search_nodes tool Ruby search_nodes tool ruby-contracts search_nodes talk Rubyana Gems and the Ractorous Rubetta Stones! search_nodes tool Iodine search_nodes tool Action Cable search_nodes concept Snapshotting search_nodes takeaway Per-Event Backups Via Reactors search_nodes company Evil Martians search_nodes tool RealtimeBoard search_nodes talk Events events events search_nodes tool Sync Space VR search_nodes takeaway Time Travel Superpower search_nodes takeaway Replay-Based Debugging search_nodes tool Rust search_nodes talk Setup and operation of mutation testing in agentic world search_nodes talk Methods Gem for Ruby Method References search_nodes concept Waterfall Analysis search_nodes project granite search_nodes tool aggregate_root search_nodes talk To Refine or Not to Refine search_nodes person Akira Matsuda search_nodes tool Faker search_nodes takeaway Use Refinements for Coordinated Modernization search_nodes project monolith framework search_nodes concept Refinements search_nodes concept Method References in Ruby search_nodes takeaway Use Refinements for Dependency Reduction search_nodes concept Ruby Module Customization Mechanics search_nodes talk MVCC for Ruby developers search_nodes person Julik Tarkhanov search_nodes person Adam Okoń search_nodes person DHH search_nodes person Piotr Solnica search_nodes person Emiliano Della Casa search_nodes person Kuba Suder search_nodes person Matz search_nodes person Adam Piotrowski search_nodes concept Interface Wrapper for Ruby search_nodes tool Plezi search_nodes tool Hanami search_nodes talk Building Rails SPAs in Frontend Ruby with Glimmer DSL for Web search_nodes concept Command UUID Deduplication search_nodes concept Cynefin Framework search_nodes talk Extracting logic from templates with Hanami Views search_nodes tool Ember.js search_nodes talk Towards the post framework future search_nodes concept Static Page Caching via nginx search_nodes takeaway Prefer Brotli over gzip when available search_nodes concept Trailblazer Workflow search_nodes concept HTTP Caching with ETag and Last-Modified search_nodes

2 edges