From 839bd717b352db91c59a8fa62662b6ca72e056bd Mon Sep 17 00:00:00 2001 From: Fijxu Date: Sun, 4 Aug 2024 15:13:45 -0400 Subject: [PATCH] 0.5.1: return a proper error message if the file doesn't exist. Return proper HTTP error codes. --- public/favicon.gif | Bin 0 -> 53255 bytes public/styles.css | 10 +++---- src/config.cr | 4 +-- src/file-uploader.cr | 1 + src/handling.cr | 62 ++++++++++++++++++++++++++++++++----------- src/log.cr | 3 +++ src/utils.cr | 1 + src/views/index.ecr | 4 ++- 8 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 public/favicon.gif create mode 100644 src/log.cr diff --git a/public/favicon.gif b/public/favicon.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cae26f87d0c4104bdd0520a863fb663409a9dfd GIT binary patch literal 53255 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 W^^qFsO9B%I(DgB)r1`^ROaB)ZvkbKW literal 0 HcmV?d00001 diff --git a/public/styles.css b/public/styles.css index f48fa5a..d7950bd 100644 --- a/public/styles.css +++ b/public/styles.css @@ -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 */ } diff --git a/src/config.cr b/src/config.cr index ade0e06..9c38f2f 100644 --- a/src/config.cr +++ b/src/config.cr @@ -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" diff --git a/src/file-uploader.cr b/src/file-uploader.cr index c704481..7fcf35c 100644 --- a/src/file-uploader.cr +++ b/src/file-uploader.cr @@ -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 diff --git a/src/handling.cr b/src/handling.cr index bb04397..7556f8e 100644 --- a/src/handling.cr +++ b/src/handling.cr @@ -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 - 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}" + 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" - json_data = JSON.build do |json| - json.object do - json.field "stats" do - json.object do - begin + begin + json_data = JSON.build do |json| + json.object do + json.field "stats" do + json.object do 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 diff --git a/src/log.cr b/src/log.cr new file mode 100644 index 0000000..91a6ce2 --- /dev/null +++ b/src/log.cr @@ -0,0 +1,3 @@ +module LOGGER + +end \ No newline at end of file diff --git a/src/utils.cr b/src/utils.cr index c654d35..00e437e 100644 --- a/src/utils.cr +++ b/src/utils.cr @@ -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 diff --git a/src/views/index.ecr b/src/views/index.ecr index 3dae6d6..9576f92 100644 --- a/src/views/index.ecr +++ b/src/views/index.ecr @@ -30,13 +30,14 @@ <%= host %> +

<%= host %>

<%= CONFIG.siteInfo %>

-

Drop or Choose file(s)

+

Arrastra, Pega o Selecciona archivos.

@@ -47,6 +48,7 @@

Chatterino Config

ShareX Config

file-uploader-crystal (BETA <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %> @ <%= CURRENT_BRANCH %>)

+

Archivos alojados: <%= files_hosted %>