UI improvements: Code clearing fix and custom delete modal
Simple File Upload Server
A lightweight Flask-based file upload and download server with a modern UI. Perfect for temporary file sharing and mobile app log uploads.
The Android mobile app for this server can be found at: https://github.com/mattintech/simplefileupload-android
Features
- Clean, modern UI for file downloads
- Secure API authentication for uploads
- Mobile-friendly upload endpoint
- Chunked upload support for large files
- Specifically designed for the simplefileupload-android app
- Secure 6-digit alphanumeric code system
- Automatic file cleanup
- Configurable download limits and expiry times
- User-friendly error pages
- Docker support
Architecture
Built using the MVC design pattern:
- Model: File metadata management (code, path, downloads, expiry)
- View: Modern HTML templates with client-side validation
- Controller: Upload/download logic with error handling
Getting Started
Local Development
- Clone the repository
- Create and activate a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
- Install dependencies:
pip install -r requirements.txt
- Set environment variables (optional):
export CLIENT_KEY=your-secret-key # If not set, defaults to default-secret-key
- Run the server:
python src/app.py
Docker Deployment
- Build the image:
docker build -t simplefileupload-server .
- Generate SSL Certificate (Required for Mobile App): The mobile app requires SSL connections, so you'll need to generate a self-signed certificate or use your own certificate. To create a self-signed certificate:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
- Run the container:
Without SSL (Not compatible with mobile app):
docker run -p 7777:7777 simplefileupload-server
With SSL (Required for mobile app):
docker run -p 7777:7777 \
-v $(pwd)/cert.pem:/app/cert.pem \
-v $(pwd)/key.pem:/app/key.pem \
simplefileupload-server
You can combine the SSL certificates with other options like CLIENT_KEY and upload folder:
docker run -p 7777:7777 \
-e CLIENT_KEY=your-secret-key \
-v $(pwd)/cert.pem:/app/cert.pem \
-v $(pwd)/key.pem:/app/key.pem \
-v $(pwd)/tmp:/app/tmp \
simplefileupload-server
API Endpoints
POST /upload
Upload a file and receive a download code.
Authentication:
- Required:
X-Client-Keyheader with your API key
Form Fields:
file: File to upload (required)max_downloads: Maximum download count (optional, default: 1)expiry_hours: Hours until expiry (optional, default: 24)
Example using curl:
# Basic upload with default settings
curl -X POST http://localhost:7777/upload \
-H "X-Client-Key: your-secret-key" \
-F "file=@/path/to/your/file.txt"
# Upload with custom download limit and expiry time
curl -X POST http://localhost:7777/upload \
-H "X-Client-Key: your-secret-key" \
-F "file=@/path/to/your/file.txt" \
-F "max_downloads=5" \
-F "expiry_hours=48"
# Upload with SSL (for mobile app compatibility)
curl -X POST https://localhost:7777/upload \
-H "X-Client-Key: your-secret-key" \
-F "file=@/path/to/your/file.txt" \
--cacert cert.pem
Response:
{
"code": "ABC123"
}
Error Responses:
- 401: Invalid or missing client key
- 400: Missing file or invalid request
{
"error": "Error message here"
}
POST /upload/start
Start a chunked upload session for large files.
Authentication:
- Required:
X-Client-Keyheader with your API key
Form Fields:
filename: Name of the file being uploaded (required)total_chunks: Total number of chunks to expect (required)max_downloads: Maximum download count (optional, default: 1)expiry_hours: Hours until expiry (optional, default: 24)
Example using curl:
# Start a chunked upload session
curl -X POST http://localhost:7777/upload/start \
-H "X-Client-Key: your-secret-key" \
-F "filename=largefile.zip" \
-F "total_chunks=10" \
-F "max_downloads=5" \
-F "expiry_hours=48"
Response:
{
"upload_id": "abC123dEf456gHij"
}
POST /upload/chunk
Upload a single chunk of a file.
Authentication:
- Required:
X-Client-Keyheader with your API key
Form Fields:
upload_id: Upload session ID from /upload/start (required)chunk_index: Index of this chunk, starting from 0 (required)chunk: The file chunk data (required)
Example using curl:
# Upload chunk 0
curl -X POST http://localhost:7777/upload/chunk \
-H "X-Client-Key: your-secret-key" \
-F "upload_id=abC123dEf456gHij" \
-F "chunk_index=0" \
-F "chunk=@chunk_0.bin"
Response:
{
"success": true,
"received_chunks": 5,
"total_chunks": 10
}
POST /upload/complete
Complete a chunked upload session.
Authentication:
- Required:
X-Client-Keyheader with your API key
Form Fields:
upload_id: Upload session ID from /upload/start (required)
Example using curl:
# Complete the chunked upload
curl -X POST http://localhost:7777/upload/complete \
-H "X-Client-Key: your-secret-key" \
-F "upload_id=abC123dEf456gHij"
Response:
{
"code": "ABC123"
}
Error Responses for Chunked Upload Endpoints:
- 401: Invalid or missing client key
- 400: Missing required parameters or invalid request
- 404: Invalid upload session ID
{
"error": "Error message here"
}
GET /download/{code}
Download a file using a 6-character code.
Responses:
- 200: File download starts
- 404: File not found with specific error pages for:
- Invalid code
- Expired file
- Download limit reached
- File no longer exists
DELETE /delete/{code}
Delete a file using its code.
Responses:
- 200: File deleted successfully
- 404: File not found or expired
Security Features
- API Authentication: Client key required for file uploads
- Secure Downloads: 6-digit alphanumeric codes
- Auto Cleanup: Files are automatically deleted after:
- Reaching download limit
- Exceeding expiry time
- Server restart (temporary storage)
- Upload Security:
- Secure filename handling
- No file execution permissions
- File size limits
Configuration
All configuration is handled through environment variables:
Required Settings
None - all settings have defaults for easy testing
Optional Settings
CLIENT_KEY: API key for file uploads (default: default-secret-key)UPLOAD_FOLDER: Upload directory path (default: tmp/uploads)MAX_CONTENT_LENGTH: Maximum file size (default: 16MB)DEBUG: Enable debug mode (default: False)
Contributing
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
Security Best Practices
- Set a strong CLIENT_KEY in production
- Use HTTPS in production
- Regularly monitor disk usage
- Set appropriate file size limits
- Keep dependencies updated