Skip to content

Commit

Permalink
routes/upload: figure out how to serve images
Browse files Browse the repository at this point in the history
However, browsers prompt for download since they're not coming down
with a relevant mimetype (they have application/octet-stream).

See: crystal-lang/crystal#5765
  • Loading branch information
adamdecaf committed May 3, 2018
1 parent 36ca520 commit f8a3839
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/main
/main.dwarf
/data/
/i/
11 changes: 7 additions & 4 deletions main.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require "./routes/ping"
require "./routes/upload"

# Create data directory if it doesn't exist
DATA_DIR="./data"
DATA_DIR="./i/"
Dir.mkdir_p(DATA_DIR)

# Start http server
Expand All @@ -16,7 +16,10 @@ HTTP::Server.new("0.0.0.0", 8080, [
PingHandler.new,
IndexHandler.new,
UploadHandler.new(DATA_DIR),
# Static assetsn
HTTP::StaticFileHandler.new("./html/", directory_listing=false),
HTTP::ErrorHandler.new,
# Serve images
HTTP::StaticFileHandler.new("./i", directory_listing=false),
# Static assets
HTTP::StaticFileHandler.new("./html", directory_listing=false),
# Final error page
HTTP::ErrorHandler.new, # TODO(adam): what does this do?
]).listen
3 changes: 3 additions & 0 deletions routes/index.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ class IndexHandler
if ctx.request.path == "/"
ctx.request.path = "/index.html"
end
if ctx.request.path.starts_with?("/i/")
ctx.request.path = ctx.request.path.gsub("/i/", "")
end
call_next(ctx)
end
end
9 changes: 4 additions & 5 deletions routes/upload.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ class UploadHandler

def call(ctx)
if ctx.request.method == "POST" && ctx.request.path == "/upload"
puts "#{ctx.request.method}"

# TODO(adam): Check content-length

HTTP::FormData.parse(ctx.request) do |part|
Expand All @@ -33,14 +31,15 @@ class UploadHandler
# Generate new path
checksum = hasher.hexdigest[0, 16]
ext = File.extname(File.basename(part.filename || "ukn")) # TODO(adam): detect content type
path = File.join([@data_dir, "#{checksum}#{ext}"])
name = "#{checksum}#{ext}"
path = File.join([@data_dir, name])

# Move uploaded file
File.rename(file.path, path) unless File.exists?(path)

# Set response
ctx.response.status_code = 200
ctx.response.print "uploaded #{File.size(path)} bytes"
ctx.response.status_code = 302
ctx.response.headers.add("Location", "/i/#{name}")

return # quit early after successful upload
end
Expand Down

0 comments on commit f8a3839

Please sign in to comment.