Releases: kemalcr/kemal
v0.26.1
- Fix process request when a response already closed #550. Thanks @mamantoha π
- Switch to new Ameba repository #549. Thanks @mamantoha π
- Check for
KEMAL_ENV
variable already inConfig#initialize
#552. Thanks @Sija π - Cleanup Ameba warnings #551. Thanks @Sija π
- Flush io buffer after each write to log #554. Thanks @mang π
v0.26.0
0.25.2
-
Crystal 0.27.2 support π
-
Add option to config to parse or not command line parameters #483. Thanks @diegogub π
-
Allow to set filename for
send_file
#512. Thanks @mamantoha π
send_file env, "./asset/image.jpeg", filename: "image.jpg"
v0.25.1
v0.25.0
-
Crystal 0.27.0 support.
-
[breaking change] Added back
env.params.files
.
Here's a fully working sample for reading a image file upload image1
and saving it under public/uploads
.
post "/upload" do |env|
file = env.params.files["image1"].tmpfile
file_path = ::File.join [Kemal.config.public_folder, "uploads/", file.filename]
File.open(file_path, "w") do |f|
IO.copy(file, f)
end
"Upload ok"
end
To test
curl -F "image1=@/Users/serdar/Downloads/kemal.png" http://localhost:3000/upload
- Cache HTTP routes to increase performance π #493
v0.24.0
-
Crystal 0.26.0 support
-
[breaking change] Removed
env.params.files
. You can use Crystal's built-inHTTP::FormData.parse
instead
post "/upload" do |env|
HTTP::FormData.parse(env.request) do |upload|
filename = file.filename
if !filename.is_a?(String)
"No filename included in upload"
else
file_path = ::File.join [Kemal.config.public_folder, "uploads/", filename]
File.open(file_path, "w") do |f|
IO.copy(file.tmpfile, f)
end
"Upload OK"
end
end
- [breaking change] From now on to access dynamic url params in a WebSocket route you have to use:
ws "/:id" do |socket, context|
id = context.ws_route_lookup.params["id"]
end
-
[breaking change] Removed
_method
magic param. -
Added new exception page #466. Thanks @mamantoha π
-
Support custom port binding. Thanks @straight-shoota π
Kemal.run do |config|
server = config.server.not_nil!
server.bind_tcp "127.0.0.1", 3000, reuse_port: true
server.bind_tcp "0.0.0.0", 3001, reuse_port: true
end
v0.23.0
v0.22.0
- Crystal 0.24.1 support π
- Only return string from route.#408 thanks @crisward π
- Don't crash on empty path when compiled in --release. #407 thanks @crisward π
- Rename
Kemal::CommonLogHandler
toKemal::LogHandler
andKemal::CommonExceptionHandler
toKemal::ExceptionHandler
. - Allow videos to be opened with correct mime type. #406 thanks @crisward π
- Add webm mime type.#413 thanks @reindeer-cafe π
v0.21.0
- Dynamically insert handlers πͺ Fixes #376.
- Add context to WebSocket. This allows one to use
HTTP::Server::Context
inws
declarations π Fixes #349.
ws "/:room_name" do |socket, env|
env.params.url["room_name"]
end
- Add support for customizing the headers of built-in
Kemal::StaticFileHandler
π¨ Useful for supportingCORS
for single page applications π
static_headers do |response, filepath, filestat|
if filepath =~ /\.html$/
response.headers.add("Access-Control-Allow-Origin", "*")
end
response.headers.add("Content-Size", filestat.size.to_s)
end
end
-
Security: X-Content-Type-Options: nosniff for static files. Fixes #379. Thanks @crisward π
-
Performance: Remove tempfile management to OS. This brings %10 - 15 performance boost to Kemal π
v0.20.0
- Crystal 0.23.0 support! As always, Kemal is compatible with the latest major release of Crystal π
- Great news everyone π All handlers are now completely customizable!. Use the default
Kemal
handlers or go wild, it's all up to you β
# Don't forget to add `Kemal::RouteHandler::INSTANCE` or your routes won't work!
Kemal.config.handlers = [Kemal::InitHandler.new, YourHandler.new, Kemal::RouteHandler::INSTANCE]
You can also insert a handler into a specific position.
# This adds MyCustomHandler instance to 1 position. Be aware that the index starts from 0.
add_handler MyCustomHandler.new, 1
- Updated Kilt to v0.4.0.
- Make
Route
aStruct
. This improves the performance of route declarations.