0.9.1: Upload file from URL with GET request
All checks were successful
File-uploader-crystal CI / build (push) Successful in 4m34s

This commit is contained in:
Fijxu 2024-09-11 01:50:17 -03:00
parent 493322039d
commit 4803700cab
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
4 changed files with 97 additions and 5 deletions

View file

@ -83,4 +83,6 @@ WantedBy=default.target
- Dockerfile and Docker image (Crystal doesn't has dependency hell like other languages so is not really necessary to do, but useful for people that want instant deploy)
- Custom file expiration using headers (Like rustypaste)
- Small CLI to upload files (like `rpaste` from rustypaste)
- Add more endpoints to Admin API
- Add more endpoints to Admin API
-

View file

@ -32,6 +32,7 @@ CURRENT_TAG = {{ "#{`git describe --long --abbrev=7 --tags | sed 's/([^-]*)-
Utils.check_dependencies
Utils.create_db
Utils.create_files_dir
Utils.create_thumbnails_dir
Routing.register_all
Utils.delete_socket

View file

@ -83,8 +83,7 @@ module Handling
end
# The most unoptimized and unstable feature lol
# TODO: Support batch upload via JSON array
def upload_url(env)
def upload_url_bulk(env)
env.response.content_type = "application/json"
ip_address = Utils.ip_address(env)
protocol = Utils.protocol(env)
@ -169,6 +168,92 @@ module Handling
json
end
# TODO: Add delete url, same for upload_url_bulk
def upload_url(env)
env.response.content_type = "application/json"
ip_address = Utils.ip_address(env)
protocol = Utils.protocol(env)
host = Utils.host(env)
url = env.params.query["url"]
successfull_files = [] of NamedTuple(filename: String, extension: String, original_filename: String, checksum: String, delete_key: String | Nil)
failed_files = [] of String
# X-Forwarded-For if behind a reverse proxy and the header is set in the reverse
# proxy configuration.
if url.empty?
end
# files.each do |url|
url = url.to_s
filename = Utils.generate_filename
original_filename = ""
extension = ""
checksum = ""
uploaded_at = Time.utc
extension = File.extname(URI.parse(url).path)
delete_key = nil
file_path = ::File.join ["#{CONFIG.files}", filename + extension]
File.open(file_path, "w") do |output|
begin
HTTP::Client.get(url) do |res|
IO.copy(res.body_io, output)
end
rescue ex
LOGGER.debug "Failed to download file '#{url}': #{ex.message}"
return error403("Failed to download file '#{url}'")
failed_files << url
end
end
# successfull_files << url
# end
if extension.empty?
extension = Utils.detect_extension(file_path)
File.rename(file_path, file_path + extension)
file_path = ::File.join ["#{CONFIG.files}", filename + extension]
end
# The second one is faster and it uses less memory
# original_filename = URI.parse("https://ayaya.beauty/PqC").path.split("/").last
original_filename = url.split("/").last
checksum = Utils.hash_file(file_path)
begin
spawn { Utils.generate_thumbnail(filename, extension) }
rescue ex
LOGGER.error "An error ocurred when trying to generate a thumbnail: #{ex.message}"
end
begin
# Insert SQL data just before returning the upload information
SQL.exec("INSERT INTO #{CONFIG.dbTableName} VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
original_filename, filename, extension, uploaded_at, checksum, ip_address, delete_key, nil)
successfull_files << {filename: filename,
original_filename: original_filename,
extension: extension,
delete_key: delete_key,
checksum: checksum}
rescue ex
LOGGER.error "An error ocurred when trying to insert the data into the DB: #{ex.message}"
return error500("An error ocurred when trying to insert the data into the DB")
end
# end
json = JSON.build do |j|
j.array do
successfull_files.each do |fileinfo|
j.object do
j.field "link", "#{protocol}://#{host}/#{fileinfo[:filename]}"
j.field "linkExt", "#{protocol}://#{host}/#{fileinfo[:filename]}#{fileinfo[:extension]}"
j.field "id", fileinfo[:filename]
j.field "ext", fileinfo[:extension]
j.field "name", fileinfo[:original_filename]
j.field "checksum", fileinfo[:checksum]
if CONFIG.deleteKeyLength > 0
delete_key = Random.base58(CONFIG.deleteKeyLength)
j.field "deleteKey", fileinfo[:delete_key]
j.field "deleteLink", "#{protocol}://#{host}/delete?key=#{fileinfo[:delete_key]}"
end
end
end
end
end
json
end
def retrieve_file(env)
begin
protocol = Utils.protocol(env)

View file

@ -54,10 +54,14 @@ module Routing
Handling.upload(env)
end
post "/api/uploadurl" do |env|
get "/upload" do |env|
Handling.upload_url(env)
end
post "/api/uploadurl" do |env|
Handling.upload_url_bulk(env)
end
get "/:filename" do |env|
Handling.retrieve_file(env)
end
@ -100,7 +104,7 @@ module Routing
Handling::Admin.retrieve_file_info(env)
end
get "/api/admin/torexitnodes" do |env|
get "/api/admin/torexitnodes" do |env|
Handling::Admin.retrieve_tor_exit_nodes(env, @@exit_nodes)
end
end