Server Modes
Server Modes
Section titled “Server Modes”Stowry supports three server modes that change how requests are handled. Choose the mode that fits your use case.
Overview
Section titled “Overview”| Mode | Use Case | Path Fallback |
|---|---|---|
store | Object storage API | None (404 if not found) |
static | Static file server | {path}.html → {path}/index.html |
spa | Single-page application | /index.html |
Store Mode (Default)
Section titled “Store Mode (Default)”The default mode for object storage operations.
server: mode: storeBehavior
Section titled “Behavior”GET /{path}- Returns the exact file or 404GET /- Returns JSON list of objects- Full CRUD operations (PUT, DELETE)
- No automatic fallbacks
Use Cases
Section titled “Use Cases”- Backend file storage for applications
- User upload handling
- Asset management systems
- API-driven file operations
Example
Section titled “Example”# Start in store mode./stowry serve --mode store
# Upload a filecurl -X PUT -d "content" http://localhost:5708/documents/report.pdf
# Download - returns exact filecurl http://localhost:5708/documents/report.pdf # 200 OK
# Missing file - returns 404curl http://localhost:5708/documents/missing.pdf # 404 Not Found
# List objectscurl http://localhost:5708/ # JSON responseStatic Mode
Section titled “Static Mode”Serves static files with S3+CloudFront-style path resolution and clean URLs.
server: mode: static error_document: 404.html # optional custom error pageBehavior
Section titled “Behavior”GET /{path}- Tries exact match →{path}.html→{path}/index.htmlGET /{path}/- Tries{path}/index.html(trailing slash = directory index)GET /- Returns/index.html- Missing paths return an HTML 404 page (default Stowry-branded, or custom via
error_document) - Read-only: PUT and DELETE return
405 Method Not Allowed - Always public access (auth settings are ignored)
- Use
stowry addor store mode to populate content
Fallback Logic
Section titled “Fallback Logic”For /foo (no trailing slash):
- Try exact path
foo - Try
foo.html(clean URLs) - Try
foo/index.html(directory index) - Return 404 error page
For /foo/ (trailing slash):
- Try
foo/index.html(directory index) - Return 404 error page
Error Pages
Section titled “Error Pages”By default, Stowry serves a minimal HTML 404 page:
<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>stowry</center></body></html>Configure a custom error page:
server: error_document: 404.htmlThe custom error document is served from storage with a 404 status code. If the custom document is not found, the default page is used.
Use Cases
Section titled “Use Cases”- Static website hosting
- Documentation sites
- Marketing pages
- Any site with traditional URL structure
Example
Section titled “Example”Given this storage structure:
data/├── index.html├── about.html├── docs/│ └── index.html├── blog/│ ├── index.html│ └── post-1.html└── assets/ └── style.cssRequest handling:
GET / → data/index.htmlGET /about → data/about.html (clean URL)GET /about.html → data/about.html (direct)GET /docs/ → data/docs/index.html (trailing slash)GET /docs → data/docs/index.html (fallback chain)GET /blog/post-1.html → data/blog/post-1.htmlGET /assets/style.css → data/assets/style.cssGET /missing → 404 HTML pageSPA Mode
Section titled “SPA Mode”Designed for single-page applications with client-side routing.
server: mode: spaBehavior
Section titled “Behavior”GET /{path}- Returns file if exists, otherwise/index.html- Enables client-side routing (React Router, Vue Router, etc.)
- Read-only: PUT and DELETE return
405 Method Not Allowed - Always public access (auth settings are ignored)
- Use
stowry addor store mode to populate content
Fallback Logic
Section titled “Fallback Logic”- Try exact path
- If not found, return
/index.html - Client-side JavaScript handles routing
Use Cases
Section titled “Use Cases”- React applications
- Vue.js applications
- Angular applications
- Any SPA with client-side routing
Example
Section titled “Example”Given this storage structure:
dist/├── index.html├── assets/│ ├── main.js│ └── style.css└── favicon.icoRequest handling:
GET / → dist/index.htmlGET /dashboard → dist/index.html (SPA handles route)GET /users/123 → dist/index.html (SPA handles route)GET /assets/main.js → dist/assets/main.jsGET /favicon.ico → dist/favicon.icoClient-Side Router Setup
Section titled “Client-Side Router Setup”Ensure your SPA handles the current URL on load:
React Router:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/users/:id" element={<UserProfile />} /> </Routes> </BrowserRouter> );}Vue Router:
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: Home }, { path: '/dashboard', component: Dashboard }, { path: '/users/:id', component: UserProfile }, ],});Comparing Modes
Section titled “Comparing Modes”GET Request Behavior
Section titled “GET Request Behavior”| Request | Store | Static | SPA |
|---|---|---|---|
GET / | List objects (JSON) | /index.html | /index.html |
GET /about | Exact file or 404 | about → about.html → about/index.html | /index.html |
GET /about/ | Exact file or 404 | about/index.html | /index.html |
GET /file.txt | Exact file or 404 | Exact file or 404 | Exact file or 404 |
GET /missing | 404 (JSON) | 404 (HTML) | /index.html |
Write Operation Availability
Section titled “Write Operation Availability”| Operation | Store | Static | SPA |
|---|---|---|---|
PUT /{path} | Allowed | 405 | 405 |
DELETE /{path} | Allowed | 405 | 405 |
GET / (list) | JSON list | index.html | index.html |
When to Use Each
Section titled “When to Use Each”Use Store when:
- Building an API-driven application
- You need full control over responses
- Implementing custom 404 handling on the client
- File paths are dynamic/generated
Use Static when:
- Hosting a traditional static website
- Each URL corresponds to a specific page
- You want automatic directory index resolution
- SEO is important (each route has its own file)
Use SPA when:
- Building a single-page application
- Using client-side routing
- All routes should load the same entry point
- Deep linking should work for all routes
Populating Content
Section titled “Populating Content”Since static and SPA modes are read-only, use one of these methods to add files:
# Using the add command (recommended)stowry add -r ./dist
# Using store mode temporarilystowry serve --mode store# Upload files via PUT, then restart in static/spa modeSwitching Modes
Section titled “Switching Modes”You can change modes without modifying your stored files:
# Development with SPA mode./stowry serve --mode spa
# Production static hosting./stowry serve --mode static
# API mode for backend./stowry serve --mode storeOr via configuration:
server: mode: ${STOWRY_MODE:-store} # Default to store, override with env var