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;
|
||||
margin: auto;
|
||||
/* background: white; */
|
||||
padding: 20px;
|
||||
/*! padding: 20px; */
|
||||
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 {
|
||||
|
@ -86,9 +86,9 @@ nav a, nav > ul
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border: 2px solid #f40101; /* Optional styling for the status box */
|
||||
padding: 10px; /* Optional padding */
|
||||
border-radius: 6px; /* Optional rounded corners */
|
||||
border: 2px solid #eee; /* Optional styling for the status box */
|
||||
padding: 5px; /* Optional padding */
|
||||
/*! border-radius: 6px; */ /* Optional rounded corners */
|
||||
/*! background-color: #f9f9f9; */ /* Optional background color */
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ class Config
|
|||
property unix_socket : String?
|
||||
property delete_files_after : Int32 = 7
|
||||
# How often should the check of old files be performed? (in seconds)
|
||||
property delete_files_after_check_seconds : Int32 = 60
|
||||
property delete_key_lenght : Int8 = 8
|
||||
property delete_files_after_check_seconds : Int32 = 1800
|
||||
property delete_key_lenght : Int8 = 4
|
||||
# Blocked extensions that are not allowed to be uploaded to the server
|
||||
property blocked_extensions : Array(String) = [] of String
|
||||
property siteInfo : String = "xd"
|
||||
|
|
|
@ -23,6 +23,7 @@ Utils.create_db
|
|||
Utils.create_files_dir
|
||||
|
||||
get "/" do |env|
|
||||
files_hosted = SQL.query_one "SELECT COUNT (filename) FROM files", as: Int32
|
||||
host = env.request.headers["Host"]
|
||||
render "src/views/index.ecr"
|
||||
end
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
module Handling
|
||||
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)
|
||||
env.response.content_type = "application/json"
|
||||
env.response.status_code = 403
|
||||
|
@ -8,6 +15,27 @@ module Handling
|
|||
return error_message
|
||||
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)
|
||||
env.response.content_type = "application/json"
|
||||
msg = {"message" => {{message}}}.to_json
|
||||
|
@ -18,7 +46,7 @@ end
|
|||
env.response.content_type = "application/json"
|
||||
# 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
|
||||
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
|
||||
filename = ""
|
||||
extension = ""
|
||||
|
@ -32,13 +60,13 @@ end
|
|||
next if upload.filename.nil? || upload.filename.to_s.empty?
|
||||
extension = File.extname("#{upload.filename}")
|
||||
if CONFIG.blocked_extensions.includes?(extension.split(".")[1])
|
||||
error403("Extension '#{extension}' is not allowed")
|
||||
error401("Extension '#{extension}' is not allowed")
|
||||
end
|
||||
# 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)
|
||||
filename = Random.base58(CONFIG.filename_lenght)
|
||||
if !filename.is_a?(String)
|
||||
return "This doesn't look like a file"
|
||||
error403("This doesn't look like a file")
|
||||
else
|
||||
file_path = ::File.join ["#{CONFIG.files}", filename + extension]
|
||||
File.open(file_path, "w") do |file|
|
||||
|
@ -73,26 +101,30 @@ end
|
|||
|
||||
def retrieve_file(env)
|
||||
puts env.params.url
|
||||
begin
|
||||
filename = SQL.query_one "SELECT filename FROM files WHERE filename = ?", env.params.url["filename"].to_s.split(".").first, as: String
|
||||
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
|
||||
|
||||
def stats(env)
|
||||
env.response.content_type = "application/json"
|
||||
begin
|
||||
json_data = JSON.build do |json|
|
||||
json.object do
|
||||
json.field "stats" do
|
||||
json.object do
|
||||
begin
|
||||
json.field "filesHosted", SQL.query_one "SELECT COUNT (filename) FROM files", as: Int32
|
||||
json.field "maxUploadSize", CONFIG.size_limit
|
||||
rescue
|
||||
json.field "error", "Unknown error"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue ex
|
||||
error500("Unknown error: #{ex.message}")
|
||||
end
|
||||
json_data
|
||||
end
|
||||
|
@ -106,10 +138,10 @@ end
|
|||
SQL.exec "DELETE FROM files WHERE delete_key = ?", env.params.query["key"]
|
||||
msg("File '#{file_to_delete}' deleted successfully")
|
||||
rescue ex
|
||||
error403("Unknown error: #{ex.message}")
|
||||
error500("Unknown error: #{ex.message}")
|
||||
end
|
||||
else
|
||||
error403("Huh? This delete key doesn't exist")
|
||||
error401("Huh? This delete key doesn't exist")
|
||||
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
|
||||
if !Dir.exists?("#{CONFIG.files}")
|
||||
puts "INFO: Creatin files folder under '#{CONFIG.files}'"
|
||||
begin
|
||||
Dir.mkdir("#{CONFIG.files}")
|
||||
rescue ex
|
||||
|
|
|
@ -30,13 +30,14 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title> <%= host %> </title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="icon" href="./favicon.gif" type="image/gif" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 style="font-size: 72px; text-align: center; margin: 20px;"> <%= host %> </h1>
|
||||
<p style="text-align: center; font-size: 22px;"> <%= CONFIG.siteInfo %> </p>
|
||||
<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;">
|
||||
<!-- <label for="fileElem" class="button">Select File</label> -->
|
||||
</div>
|
||||
|
@ -47,6 +48,7 @@
|
|||
<p> <a href='./chatterino.png'>Chatterino 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>Archivos alojados: <%= files_hosted %></p>
|
||||
</div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
|
|
Loading…
Reference in a new issue