From fe84924f786a4858849deb4492eca284abfe5046 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 8 Oct 2026 14:20:01 -0400 Subject: [PATCH] The opaque content type is one core constant: local::OPAQUE_MIME "application/octet-stream" was written out in the blob server, its test, the store's normalize_mime and the wire default. All four now read OPAQUE_MIME; the schema's SQL column default names the same string and says so. DRY pass #2, batch 2, F7 (#5372). Co-Authored-By: Claude Opus 5.5 --- core/src/local/mod.rs | 5 +++++ core/src/local/store.rs | 4 ++-- core/src/sync/blobs.rs | 6 ++++-- core/src/sync/wire.rs | 4 +++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/core/src/local/mod.rs b/core/src/local/mod.rs index fa0fffb..c2ab2a8 100644 --- a/core/src/local/mod.rs +++ b/core/src/local/mod.rs @@ -24,6 +24,11 @@ pub const DB_FILE: &str = "inkwell.db"; /// Attachment bytes, filed by content hash, beside [`DB_FILE`]. pub const BLOBS_DIR: &str = "blobs"; +/// The type of bytes whose type isn't known, or isn't safe to say: stored for an +/// attachment that declared none, and served for one that can't be shown inline. +/// The schema's column default (`schema.rs`) is the same string, in SQL. +pub const OPAQUE_MIME: &str = "application/octet-stream"; + /// An instant in the store's own form: RFC 3339, UTC, milliseconds, `Z`. Every /// stored time is written this way, which is what makes lexical order chronological. pub fn iso(t: DateTime) -> String { diff --git a/core/src/local/store.rs b/core/src/local/store.rs index a8ef48a..811eb6e 100644 --- a/core/src/local/store.rs +++ b/core/src/local/store.rs @@ -15,7 +15,7 @@ use uuid::Uuid; use crate::local::derive; use crate::local::models::*; use crate::local::recur; -use crate::local::{iso, now}; +use crate::local::{iso, now, OPAQUE_MIME}; fn new_id() -> String { Uuid::new_v4().to_string() @@ -792,7 +792,7 @@ fn normalize_mime(raw: &str) -> String { .trim() .to_ascii_lowercase(); if bare.is_empty() { - "application/octet-stream".to_string() + OPAQUE_MIME.to_string() } else { bare } diff --git a/core/src/sync/blobs.rs b/core/src/sync/blobs.rs index 0f47152..9a889ee 100644 --- a/core/src/sync/blobs.rs +++ b/core/src/sync/blobs.rs @@ -12,6 +12,8 @@ use std::fs; use std::path::{Path, PathBuf}; use std::sync::OnceLock; +use crate::local::OPAQUE_MIME; + /// A sha256 in lowercase hex, and nothing else. /// /// This is a **path-safety** check, not a formatting nicety: the hash is taken @@ -189,7 +191,7 @@ fn content_type_for(mime: &str) -> String { if familiar && printable { mime.to_string() } else { - "application/octet-stream".to_string() + OPAQUE_MIME.to_string() } } @@ -306,7 +308,7 @@ mod tests { fn a_scriptable_type_is_served_as_a_download() { // This scheme is an origin of its own. An attachment claiming to be HTML // must not be handed back as a document that can run there. - let opaque = "application/octet-stream"; + let opaque = OPAQUE_MIME; assert_eq!(content_type_for("text/html"), opaque); assert_eq!(content_type_for("application/javascript"), opaque); // An image family member that is really a document with script in it. diff --git a/core/src/sync/wire.rs b/core/src/sync/wire.rs index d1dc94b..6bb2efe 100644 --- a/core/src/sync/wire.rs +++ b/core/src/sync/wire.rs @@ -8,6 +8,8 @@ use serde::Deserialize; +use crate::local::OPAQUE_MIME; + #[derive(Debug, Clone, Deserialize, Default)] pub struct ChangesPage { #[serde(default)] @@ -161,5 +163,5 @@ fn default_color() -> String { } fn default_mime() -> String { - "application/octet-stream".to_string() + OPAQUE_MIME.to_string() }