Show and enforce max upload size in the web UI with clear error messages

This commit is contained in:
2026-08-29 00:48:25 +02:00
parent 2f91a056d5
commit 00920d42ef
2 changed files with 44 additions and 1 deletions
+39
View File
@@ -93,6 +93,7 @@
<h2>Upload with curl</h2>
<code>curl --upload-file myfile.txt {{ .Proto }}://{{ .Host }}/myfile.txt</code>
<p style="margin-top: 10px;">The server will respond with a download URL.</p>
<p style="margin-top: 10px;">Maximum upload size: <strong id="maxUploadSizeLabel" data-max-bytes="{{ .MaxUploadSize }}">{{ .MaxUploadSize }} bytes</strong></p>
</div>
<div class="section">
@@ -105,6 +106,7 @@
<h2>Web Upload</h2>
<div class="upload-area" id="uploadArea">
<p>📁 Click to select files or drag and drop here</p>
<p style="margin-top: 10px; font-size: 0.85em; color: #666;">Maximum file size: <span id="maxUploadSizeText"></span></p>
<input type="file" id="fileInput" multiple>
<button onclick="document.getElementById('fileInput').click()">Select Files</button>
</div>
@@ -120,6 +122,22 @@
const progressContainer = document.getElementById('progressContainer');
const progressBar = document.getElementById('progressBar');
const results = document.getElementById('results');
const maxUploadSize = parseInt(document.getElementById('maxUploadSizeLabel').dataset.maxBytes, 10) || 0;
function formatBytes(bytes) {
if (!bytes) return 'unknown';
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
let value = bytes;
let unitIndex = 0;
while (value >= 1024 && unitIndex < units.length - 1) {
value /= 1024;
unitIndex++;
}
return value.toFixed(unitIndex === 0 ? 0 : 1) + ' ' + units[unitIndex];
}
document.getElementById('maxUploadSizeLabel').textContent = formatBytes(maxUploadSize);
document.getElementById('maxUploadSizeText').textContent = formatBytes(maxUploadSize);
uploadArea.addEventListener('click', () => fileInput.click());
@@ -146,6 +164,27 @@
function uploadFiles(files) {
if (files.length === 0) return;
const oversizedFiles = [];
let totalSize = 0;
for (let file of files) {
totalSize += file.size;
if (maxUploadSize && file.size > maxUploadSize) {
oversizedFiles.push(file.name);
}
}
if (oversizedFiles.length > 0) {
results.innerHTML = '<div class="result-item">Upload failed: the following file(s) exceed the maximum size of ' +
formatBytes(maxUploadSize) + ': ' + oversizedFiles.join(', ') + '</div>';
return;
}
if (maxUploadSize && totalSize > maxUploadSize) {
results.innerHTML = '<div class="result-item">Upload failed: total upload size (' + formatBytes(totalSize) +
') exceeds the maximum of ' + formatBytes(maxUploadSize) + '</div>';
return;
}
const formData = new FormData();
for (let file of files) {
formData.append('files', file);
+5 -1
View File
@@ -430,7 +430,11 @@ func logRequest(r *http.Request, status int, duration time.Duration) {
func serveFrontpage(w http.ResponseWriter, r *http.Request) {
proto := getProtocol(r)
host := getHost(r)
pageData := map[string]string{"Proto": proto, "Host": host}
pageData := map[string]any{
"Proto": proto,
"Host": host,
"MaxUploadSize": maxUploadSize,
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
indexHTML.Execute(w, pageData)