0.5.1: return a proper error message if the file doesn't exist. Return proper HTTP error codes.
This commit is contained in:
parent
b2395b3dea
commit
839bd717b3
8 changed files with 62 additions and 23 deletions
BIN
public/favicon.gif
Normal file
BIN
public/favicon.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -17,9 +17,9 @@ p, h1, h2, h3, h4, h5 {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
/* background: white; */
|
/* background: white; */
|
||||||
padding: 20px;
|
/*! padding: 20px; */
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
/*! box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); */
|
||||||
}
|
}
|
||||||
|
|
||||||
#drop-area {
|
#drop-area {
|
||||||
|
@ -86,9 +86,9 @@ nav a, nav > ul
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border: 2px solid #f40101; /* Optional styling for the status box */
|
border: 2px solid #eee; /* Optional styling for the status box */
|
||||||
padding: 10px; /* Optional padding */
|
padding: 5px; /* Optional padding */
|
||||||
border-radius: 6px; /* Optional rounded corners */
|
/*! border-radius: 6px; */ /* Optional rounded corners */
|
||||||
/*! background-color: #f9f9f9; */ /* Optional background color */
|
/*! background-color: #f9f9f9; */ /* Optional background color */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ class Config
|
||||||
property unix_socket : String?
|
property unix_socket : String?
|
||||||
property delete_files_after : Int32 = 7
|
property delete_files_after : Int32 = 7
|
||||||
# How often should the check of old files be performed? (in seconds)
|
# How often should the check of old files be performed? (in seconds)
|
||||||
property delete_files_after_check_seconds : Int32 = 60
|
property delete_files_after_check_seconds : Int32 = 1800
|
||||||
property delete_key_lenght : Int8 = 8
|
property delete_key_lenght : Int8 = 4
|
||||||
# Blocked extensions that are not allowed to be uploaded to the server
|
# Blocked extensions that are not allowed to be uploaded to the server
|
||||||
property blocked_extensions : Array(String) = [] of String
|
property blocked_extensions : Array(String) = [] of String
|
||||||
property siteInfo : String = "xd"
|
property siteInfo : String = "xd"
|
||||||
|
|
|
@ -23,6 +23,7 @@ Utils.create_db
|
||||||
Utils.create_files_dir
|
Utils.create_files_dir
|
||||||
|
|
||||||
get "/" do |env|
|
get "/" do |env|
|
||||||
|
files_hosted = SQL.query_one "SELECT COUNT (filename) FROM files", as: Int32
|
||||||
host = env.request.headers["Host"]
|
host = env.request.headers["Host"]
|
||||||
render "src/views/index.ecr"
|
render "src/views/index.ecr"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
module Handling
|
module Handling
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
|
private macro error401(message)
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
env.response.status_code = 401
|
||||||
|
error_message = {"error" => {{message}}}.to_json
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
private macro error403(message)
|
private macro error403(message)
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
env.response.status_code = 403
|
env.response.status_code = 403
|
||||||
|
@ -8,6 +15,27 @@ module Handling
|
||||||
return error_message
|
return error_message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private macro error404(message)
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
env.response.status_code = 404
|
||||||
|
error_message = {"error" => {{message}}}.to_json
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
|
private macro error413(message)
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
env.response.status_code = 413
|
||||||
|
error_message = {"error" => {{message}}}.to_json
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
|
private macro error500(message)
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
env.response.status_code = 500
|
||||||
|
error_message = {"error" => {{message}}}.to_json
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
private macro msg(message)
|
private macro msg(message)
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
msg = {"message" => {{message}}}.to_json
|
msg = {"message" => {{message}}}.to_json
|
||||||
|
@ -18,7 +46,7 @@ end
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
# You can modify this if you want to allow files smaller than 1MiB
|
# You can modify this if you want to allow files smaller than 1MiB
|
||||||
if env.request.headers["Content-Length"].to_i > 1048576*CONFIG.size_limit
|
if env.request.headers["Content-Length"].to_i > 1048576*CONFIG.size_limit
|
||||||
error403("File is too big. The maximum size allowed is #{CONFIG.size_limit}MiB")
|
error413("File is too big. The maximum size allowed is #{CONFIG.size_limit}MiB")
|
||||||
end
|
end
|
||||||
filename = ""
|
filename = ""
|
||||||
extension = ""
|
extension = ""
|
||||||
|
@ -32,13 +60,13 @@ end
|
||||||
next if upload.filename.nil? || upload.filename.to_s.empty?
|
next if upload.filename.nil? || upload.filename.to_s.empty?
|
||||||
extension = File.extname("#{upload.filename}")
|
extension = File.extname("#{upload.filename}")
|
||||||
if CONFIG.blocked_extensions.includes?(extension.split(".")[1])
|
if CONFIG.blocked_extensions.includes?(extension.split(".")[1])
|
||||||
error403("Extension '#{extension}' is not allowed")
|
error401("Extension '#{extension}' is not allowed")
|
||||||
end
|
end
|
||||||
# TODO: Check if random string is already taken by some file (This will likely
|
# TODO: Check if random string is already taken by some file (This will likely
|
||||||
# never happen but it is better to design it that way)
|
# never happen but it is better to design it that way)
|
||||||
filename = Random.base58(CONFIG.filename_lenght)
|
filename = Random.base58(CONFIG.filename_lenght)
|
||||||
if !filename.is_a?(String)
|
if !filename.is_a?(String)
|
||||||
return "This doesn't look like a file"
|
error403("This doesn't look like a file")
|
||||||
else
|
else
|
||||||
file_path = ::File.join ["#{CONFIG.files}", filename + extension]
|
file_path = ::File.join ["#{CONFIG.files}", filename + extension]
|
||||||
File.open(file_path, "w") do |file|
|
File.open(file_path, "w") do |file|
|
||||||
|
@ -73,26 +101,30 @@ end
|
||||||
|
|
||||||
def retrieve_file(env)
|
def retrieve_file(env)
|
||||||
puts env.params.url
|
puts env.params.url
|
||||||
filename = SQL.query_one "SELECT filename FROM files WHERE filename = ?", env.params.url["filename"].to_s.split(".").first, as: String
|
begin
|
||||||
extension = SQL.query_one "SELECT extension FROM files WHERE filename = ?", filename, as: String
|
filename = SQL.query_one "SELECT filename FROM files WHERE filename = ?", env.params.url["filename"].to_s.split(".").first, as: String
|
||||||
send_file env, "#{CONFIG.files}/#{filename}#{extension}"
|
extension = SQL.query_one "SELECT extension FROM files WHERE filename = ?", filename, as: String
|
||||||
|
send_file env, "#{CONFIG.files}/#{filename}#{extension}"
|
||||||
|
rescue
|
||||||
|
error404("This file does not exist")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats(env)
|
def stats(env)
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
json_data = JSON.build do |json|
|
begin
|
||||||
json.object do
|
json_data = JSON.build do |json|
|
||||||
json.field "stats" do
|
json.object do
|
||||||
json.object do
|
json.field "stats" do
|
||||||
begin
|
json.object do
|
||||||
json.field "filesHosted", SQL.query_one "SELECT COUNT (filename) FROM files", as: Int32
|
json.field "filesHosted", SQL.query_one "SELECT COUNT (filename) FROM files", as: Int32
|
||||||
json.field "maxUploadSize", CONFIG.size_limit
|
json.field "maxUploadSize", CONFIG.size_limit
|
||||||
rescue
|
|
||||||
json.field "error", "Unknown error"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue ex
|
||||||
|
error500("Unknown error: #{ex.message}")
|
||||||
end
|
end
|
||||||
json_data
|
json_data
|
||||||
end
|
end
|
||||||
|
@ -106,10 +138,10 @@ end
|
||||||
SQL.exec "DELETE FROM files WHERE delete_key = ?", env.params.query["key"]
|
SQL.exec "DELETE FROM files WHERE delete_key = ?", env.params.query["key"]
|
||||||
msg("File '#{file_to_delete}' deleted successfully")
|
msg("File '#{file_to_delete}' deleted successfully")
|
||||||
rescue ex
|
rescue ex
|
||||||
error403("Unknown error: #{ex.message}")
|
error500("Unknown error: #{ex.message}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error403("Huh? This delete key doesn't exist")
|
error401("Huh? This delete key doesn't exist")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
3
src/log.cr
Normal file
3
src/log.cr
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module LOGGER
|
||||||
|
|
||||||
|
end
|
|
@ -14,6 +14,7 @@ module Utils
|
||||||
|
|
||||||
def create_files_dir
|
def create_files_dir
|
||||||
if !Dir.exists?("#{CONFIG.files}")
|
if !Dir.exists?("#{CONFIG.files}")
|
||||||
|
puts "INFO: Creatin files folder under '#{CONFIG.files}'"
|
||||||
begin
|
begin
|
||||||
Dir.mkdir("#{CONFIG.files}")
|
Dir.mkdir("#{CONFIG.files}")
|
||||||
rescue ex
|
rescue ex
|
||||||
|
|
|
@ -30,13 +30,14 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title> <%= host %> </title>
|
<title> <%= host %> </title>
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<link rel="icon" href="./favicon.gif" type="image/gif" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 style="font-size: 72px; text-align: center; margin: 20px;"> <%= host %> </h1>
|
<h1 style="font-size: 72px; text-align: center; margin: 20px;"> <%= host %> </h1>
|
||||||
<p style="text-align: center; font-size: 22px;"> <%= CONFIG.siteInfo %> </p>
|
<p style="text-align: center; font-size: 22px;"> <%= CONFIG.siteInfo %> </p>
|
||||||
<div id="drop-area">
|
<div id="drop-area">
|
||||||
<p style='padding: 0;margin: 0; color: #123718bf;'>Drop or Choose file(s)</p>
|
<p style='padding: 0;margin: 0; color: #123718bf;'>Arrastra, Pega o Selecciona archivos.</p>
|
||||||
<input type="file" id="fileElem" accept="*/*" style="display: none;">
|
<input type="file" id="fileElem" accept="*/*" style="display: none;">
|
||||||
<!-- <label for="fileElem" class="button">Select File</label> -->
|
<!-- <label for="fileElem" class="button">Select File</label> -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
<p> <a href='./chatterino.png'>Chatterino Config</a> </p>
|
<p> <a href='./chatterino.png'>Chatterino Config</a> </p>
|
||||||
<p> <a href='./sharex.sxcu'>ShareX Config</a> </p>
|
<p> <a href='./sharex.sxcu'>ShareX Config</a> </p>
|
||||||
<p> <a href='https://codeberg.org/Fijxu/file-uploader-crystal'>file-uploader-crystal (BETA <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %> @ <%= CURRENT_BRANCH %>)</a> </p>
|
<p> <a href='https://codeberg.org/Fijxu/file-uploader-crystal'>file-uploader-crystal (BETA <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %> @ <%= CURRENT_BRANCH %>)</a> </p>
|
||||||
|
<p>Archivos alojados: <%= files_hosted %></p>
|
||||||
</div>
|
</div>
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Add table
Reference in a new issue