мелочи

This commit is contained in:
2026-07-24 21:16:00 +08:00
parent c87451eb9a
commit f97fd63d35
9 changed files with 278 additions and 61 deletions

61
403.html Normal file
View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trashbox - 403 Доступ запрещён</title>
<link rel="shortcut icon" href="/pic.svg" type="image/svg">
<style>
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8f9fa;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #333;
}
.container {
text-align: center;
padding: 2rem;
background: white;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
max-width: 500px;
}
.code {
font-size: 6rem;
font-weight: 700;
background: linear-gradient(135deg, #dc3545, #b02a37);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
}
.icon { font-size: 4rem; margin: 0.5rem 0; }
h1 { font-size: 1.5rem; margin: 0.5rem 0; }
p { color: #666; margin: 0.5rem 0 1.5rem; }
a {
display: inline-block;
padding: 0.75rem 2rem;
background: #667eea;
color: white;
text-decoration: none;
border-radius: 8px;
font-weight: 500;
transition: background 0.2s;
}
a:hover { background: #5a6fd6; }
</style>
</head>
<body>
<div class="container">
<div class="code">403</div>
<h1>Доступ запрещён</h1>
<p>Эй, дружок-пирожок, сюда нельзя</p>
<a href="/cgi-bin/index.cgi">Вернуться на главную</a>
</div>
</body>
</html>

60
404.html Normal file
View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trashbox - 404 Страница не найдена</title>
<link rel="shortcut icon" href="/pic.svg" type="image/svg">
<style>
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8f9fa;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #333;
}
.container {
text-align: center;
padding: 2rem;
background: white;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
max-width: 500px;
}
.code {
font-size: 6rem;
font-weight: 700;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0;
}
.icon { font-size: 4rem; margin: 0.5rem 0; }
h1 { font-size: 1.5rem; margin: 0.5rem 0; }
p { color: #666; margin: 0.5rem 0 1.5rem; }
a {
display: inline-block;
padding: 0.75rem 2rem;
background: #667eea;
color: white;
text-decoration: none;
border-radius: 8px;
font-weight: 500;
transition: background 0.2s;
}
a:hover { background: #5a6fd6; }
</style>
</head>
<body>
<div class="container">
<div class="code">404</div>
<h1>Страница не найдена</h1>
<p>Эй, дружок-пирожок, тобой выбрана неправильная дверь</p>
<a href="/cgi-bin/index.cgi">Вернуться на главную</a>
</div>
</body>
</html>

View File

@@ -30,7 +30,8 @@ cgi-bin/
│ └── status.c
├── index.cgi
├── style.cgi
└── status.cgi
└── status.cgi
403 и 404 опционально в папку уровнем выше, чем cgi-bin
```
### Компиляция CGI
```bash

52
busybox_nginx_reverse.txt Executable file → Normal file
View File

@@ -1,21 +1,42 @@
server {
listen 443 ssl http2;
listen 443 ssl;
http2 on;
server_name home.mashup.su www.home.mashup.su;
ssl_certificate /etc/letsencrypt/live/www.home.mashup.su/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.home.mashup.su/privkey.pem;
ssl_certificate /etc/letsencrypt/live/home.mashup.su/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/home.mashup.su/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# Прокси для MPD потока /gachi - ИСПРАВЛЕННЫЙ ВАРИАНТ
root /home/romkazvo/www;
# === КАСТОМНЫЕ СТРАНИЦЫ ОШИБОК ===
error_page 404 =404 /404.html;
location = /404.html {
root /home/romkazvo/www;
allow all;
}
error_page 403 =403 /403.html;
location = /403.html {
root /home/romkazvo/www;
allow all;
}
# === СТАТИКА ===
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# === СТРИМ /gachi ===
location = /gachi {
proxy_pass http://127.0.0.1:8001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600;
@@ -24,25 +45,40 @@ server {
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, OPTIONS, HEAD" always;
add_header Access-Control-Allow-Headers "Range, Accept-Encoding" always;
}
}
# === CGI (с перехватом ошибок) ===
location /cgi-bin/ {
proxy_pass http://127.0.0.1:8050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_intercept_errors on;
}
# === ВСЁ ОСТАЛЬНОЕ ===
location / {
proxy_pass http://127.0.0.1:8050;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_intercept_errors on;
}
}
# HTTP → HTTPS
server {
listen 80;
server_name home.mashup.su www.home.mashup.su;

View File

@@ -10,7 +10,7 @@ max_entries = 1000
[hidden]
dirs = cgi-bin,.git,.svn
files = .htpasswd,.htaccess,.gitignore
files = .htpasswd,.htaccess,.gitignore, robots.txt, 404.html, 403.html
[preview]
image = jpg,jpeg,png,gif,webp,bmp,svg,ico

View File

@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <time.h>
#include "config.h"
#include "auth.h"
#include "fs.h"
@@ -76,6 +77,7 @@ int main() {
}
}
// Обработка пароля (без кук)
if (strstr(query_string, "password=")) {
char *error = strstr(query_string, "error=1");
if (!error) {

View File

@@ -100,37 +100,50 @@ void print_content(buffer_t *buf, const char *base_path, const char *display_pat
int entry_count = 0, dir_count = 0, file_count = 0;
long long total_size = 0;
int is_recursive_search = 0;
// === ПАРСИМ ПАРОЛЬ ДО ВСЕГО ОСТАЛЬНОГО ===
char folder_name[256] = "";
char *password = NULL;
char *query_string = getenv("QUERY_STRING");
if (query_string) {
char *pass_start = strstr(query_string, "password=");
if (pass_start) {
pass_start += 9;
char *pass_end = strchr(pass_start, '&');
int pass_len = pass_end ? (int)(pass_end - pass_start) : (int)strlen(pass_start);
if (pass_len > 0 && pass_len < 256) {
char pass_buf[256];
strncpy(pass_buf, pass_start, pass_len);
pass_buf[pass_len] = '\0';
char decoded_pass[256];
url_decode_enhanced(pass_buf, decoded_pass, sizeof(decoded_pass));
password = decoded_pass;
}
}
}
if (display_path && display_path[0]) {
char *last_slash = strrchr(display_path, '/');
if (last_slash) strcpy(folder_name, last_slash + 1);
else strcpy(folder_name, display_path);
char *query_string = getenv("QUERY_STRING");
char *password = NULL;
if (query_string) {
char *pass_start = strstr(query_string, "password=");
if (pass_start) {
pass_start += 9;
char *pass_end = strchr(pass_start, '&');
int pass_len = pass_end ? (int)(pass_end - pass_start) : (int)strlen(pass_start);
if (pass_len > 0 && pass_len < 256) {
char pass_buf[256];
strncpy(pass_buf, pass_start, pass_len);
pass_buf[pass_len] = '\0';
char decoded_pass[256];
url_decode_enhanced(pass_buf, decoded_pass, sizeof(decoded_pass));
password = decoded_pass;
}
}
}
if (is_folder_protected(folder_name)) {
if (!password || !check_folder_password(folder_name, password)) {
print_password_form(buf, folder_name);
free(entries);
return;
}
}
// === ОТЛАДКА ===
fprintf(stderr, "DEBUG: folder_name = '%s'\n", folder_name);
fprintf(stderr, "DEBUG: password = '%s'\n", password ? password : "NULL");
if (password) {
fprintf(stderr, "DEBUG: check_folder_password = %d\n", check_folder_password(folder_name, password));
}
if (is_folder_protected(folder_name)) {
if (!password || !check_folder_password(folder_name, password)) {
print_password_form(buf, folder_name);
free(entries);
return;
}
}
if (g_params.search[0] != '\0') {
int result_count = 0;
search_recursive(g_config.base_path, "", g_params.search, entries, &result_count, g_config.max_entries);
@@ -171,15 +184,15 @@ void print_content(buffer_t *buf, const char *base_path, const char *display_pat
dir = opendir(alt_path);
if (!dir) {
buffer_append(buf, "<div class=\"empty-state\">\n");
buffer_append(buf, " <div class=\"icon\">📁</div>\n");
buffer_append(buf, " <h3>Ошибка открытия директории</h3>\n");
char error_msg[512];
snprintf(error_msg, sizeof(error_msg), " <p>Путь: %s</p>\n", base_path);
buffer_append(buf, error_msg);
snprintf(error_msg, sizeof(error_msg), " <p>Ошибка: %s</p>\n", strerror(errno));
buffer_append(buf, error_msg);
buffer_append(buf, " <p><a href=\"/cgi-bin/index.cgi\">← Вернуться на главную</a></p>\n");
buffer_append(buf, "</div>\n");
buffer_append(buf, " <div class=\"icon\">📁</div>\n");
char *display_base = strstr(base_path, "/www/");
if (!display_base) display_base = (char*)base_path;
buffer_append(buf, " <h3>Ошибка открытия: ");
buffer_append(buf, display_base);
buffer_append(buf, "</h3>\n");
buffer_append(buf, " <p>Папка не найдена</p>\n");
buffer_append(buf, " <p><a href=\"/cgi-bin/index.cgi\">← Вернуться на главную</a></p>\n");
buffer_append(buf, "</div>\n");
free(entries);
return;
}
@@ -312,7 +325,7 @@ void print_content(buffer_t *buf, const char *base_path, const char *display_pat
html_escape(entries[i].name, safe_name, sizeof(safe_name));
buffer_append(buf, safe_name);
buffer_append(buf, "')\">\n");
buffer_append(buf, " <span class=\"file-icon\">🔒</span>\n");
buffer_append(buf, " <span class=\"file-icon\">📁</span>\n");
buffer_append(buf, " <span class=\"file-name\">");
if (is_recursive_search) {
char safe_url[512];
@@ -323,7 +336,7 @@ void print_content(buffer_t *buf, const char *base_path, const char *display_pat
html_escape(entries[i].name, safe_name2, sizeof(safe_name2));
buffer_append(buf, safe_name2);
}
buffer_append(buf, " <span style=\"font-size:0.7rem;color:var(--text-muted);\">(защищена)</span></span>\n");
buffer_append(buf, " <span style=\"font-size:0.9rem;color:var(--text-muted);\">(🔒)</span></span>\n");
buffer_append(buf, " </a>\n");
buffer_append(buf, " <div class=\"file-controls\">\n");
buffer_append(buf, " <button class=\"preview-btn\" onclick=\"showPasswordForm('");
@@ -333,6 +346,10 @@ void print_content(buffer_t *buf, const char *base_path, const char *display_pat
html_escape(entries[i].name, safe_name3, sizeof(safe_name3));
buffer_append(buf, safe_name3);
buffer_append(buf, "')\" title=\"Ввести пароль\">🔑</button>\n");
buffer_append(buf, " <button class=\"copy-btn\" onclick=\"copyLink('/cgi-bin/index.cgi?path=");
buffer_append(buf, entries[i].encoded_path);
buffer_append(buf, "')\" title=\"Копировать ссылку на защищённую папку\">🔗</button>\n");
buffer_append(buf, " <span class=\"file-meta size\">—</span>\n");
buffer_append(buf, " </div>\n");
buffer_append(buf, " </div>\n");
} else {

View File

@@ -11,6 +11,11 @@
--accent-green: #188038;
--hover-bg: #f8f9fa;
--shadow: 0 2px 4px rgba(0,0,0,0.1);
/* === ПЕРЕМЕННЫЕ ДЛЯ МОДАЛКИ === */
--modal-bg: #ffffff;
--modal-text: #333333;
--modal-header-bg: #f8f9fa;
--modal-border: #e9ecef;
}
.dark-theme {
@@ -26,6 +31,11 @@
--accent-green: #68d391;
--hover-bg: #2d3748;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
/* === ПЕРЕМЕННЫЕ ДЛЯ МОДАЛКИ В ТЁМНОЙ ТЕМЕ === */
--modal-bg: #1e1e1e;
--modal-text: #e0e0e0;
--modal-header-bg: #2d3748;
--modal-border: #2d3748;
}
body {
@@ -387,7 +397,7 @@ li:hover {
padding: 0.75rem 0.5rem;
margin-bottom: 1rem;
background: var(--bg-primary);
border-radius: 8px;
border-radius: 0px;
border: 1px solid var(--border-color);
}
@@ -929,3 +939,29 @@ li:hover {
padding: 0.2rem 0.3rem !important;
}
}
/* ================================================
ПЕРЕОПРЕДЕЛЕНИЕ МОДАЛКИ (фикс темы)
================================================ */
.preview-content {
background: var(--modal-bg) !important;
color: var(--modal-text) !important;
border: 1px solid var(--modal-border) !important;
}
.preview-header {
background: var(--modal-header-bg) !important;
border-bottom: 1px solid var(--modal-border) !important;
}
.preview-title {
color: var(--modal-text) !important;
}
.preview-iframe {
background: var(--bg-primary) !important;
}
.preview-image-container {
background: var(--bg-primary) !important;
}

View File

@@ -3,8 +3,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
<title>Trashbox</title>
<link rel="shortcut icon" href="/logo.png" type="image/png">
<title>Trashbox - личная помоечка</title>
<link rel="shortcut icon" href="/pic.svg" type="image/svg">
<link rel="stylesheet" href="/cgi-bin/style.cgi">
<meta property="og:image" content="https://home.mashup.su/og.png" />
<meta property="og:image:width" content="600" />
@@ -21,7 +21,7 @@
<meta name="twitter:image" content="https://home.mashup.su/og.png" />
<meta name="description" content="Моя личная помоечка" />
<meta name="keywords" content="RomkaZVO, mashup, mashup su, файлы, обмен, скачать, загрузить" />
<script>
function getCookie(name) {
const value = `; ${document.cookie}`;
@@ -37,7 +37,6 @@
})();
</script>
<style>
/* Все кнопки в едином стиле */
.preview-btn,
.copy-btn,
.download-btn {
@@ -67,7 +66,6 @@
transform: scale(1.05) !important;
}
/* Уведомление */
#copyNotification {
position: fixed;
bottom: 80px;
@@ -97,15 +95,22 @@
</head>
<body>
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
<div class="container">
<div class="header">
<h1>Trashbox</h1>
<div style="margin-top: 0.5rem; opacity: 0.9; font-size: 1.1rem;">
Моя личная помоечка
<div style="display:flex;align-items:center;justify-content:center;gap:0.0002rem;flex-wrap:wrap;">
<img src="/pic.svg" alt="Trashbox" style="max-width:120px;height:auto;border-radius:12px;flex-shrink:0;">
<div>
<h1 style="margin:0;">Trashbox</h1>
<div style="opacity:0.9;font-size:1.1rem;margin-top:0.2rem;">
Склад всякой всячины
</div>
</div>
</div>
</div>
<div style="text-align:center;padding:0.5rem 1rem;font-size:1.1rem;color:var(--text-secondary);border-bottom:1px solid var(--border-color);background:var(--bg-primary);">
<span style="opacity:0.7;">Личный уголок для обмена файлами. Заливаю сюда то, чем хочу поделиться, без всяких лимитов и сторонних сервисов.</span>
</div>
<div class="content">
<!--BREADCRUMB-->
<!--CONTENT-->
@@ -117,9 +122,9 @@
<span>Навайбкодил с любовью ❤️</span>
<a href="https://romkazvo.ru" target="_blank" class="footer-link">RomkaZVO</a><br>
Работает на BusyBox httpd и Nginx для SSL<br>
Исходники<a href="https://git.mashup.su/RomkaZVO/Trashbox" target="_blank" class="footer-link">здесь</a><br>
Исходники <a href="https://git.mashup.su/RomkaZVO/Trashbox" target="_blank" class="footer-link">здесь</a><br>
</div>
<div id="status" style="margin-top: 1rem; font-size: 0.8rem; opacity: 0.7; line-height: 1.4;">
Загрузка статистики...
</div>
@@ -223,7 +228,6 @@
return true;
};
// === СКАЧИВАНИЕ ФАЙЛА ===
window.downloadFile = function(path) {
const link = document.createElement('a');
link.href = path;
@@ -233,7 +237,6 @@
document.body.removeChild(link);
};
// === КОПИРОВАНИЕ ССЫЛКИ ===
window.copyLink = function(path) {
const url = window.location.origin + path;
if (navigator.clipboard && navigator.clipboard.writeText) {
@@ -322,7 +325,8 @@
frame.style.display = 'block';
const fileName = fileUrl.split('/').pop();
title.textContent = 'Предпросмотр: ' + fileName;
const decodedFileName = decodeURIComponent(fileName);
title.textContent = decodedFileName;
const fileExt = fileName.split('.').pop().toLowerCase();
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'ico'];