-
-
Notifications
You must be signed in to change notification settings - Fork 194
Make use of helper methods in StaticFileHandler
#714
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
`StaticFileHandler#call` was a complex method with > 100 loc. This patch extracts individual aspects into helper methods, which gives it more structure. This also enables inheriting types to inject partial custom behaviour by overriding individual helper methods (see kemalcr/kemal#714 for an example).
src/kemal/static_file_handler.cr
Outdated
# NOTE: This override opts out of some behaviour from HTTP::StaticFileHandler, | ||
# such as serving content ranges. | ||
private def serve_file(context : Server::Context, file_info, file_path : Path, last_modified : Time) | ||
send_file(context, file_path.to_s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is quite a lot of duplicated logic between what send_file
does verses what is being overridden. Since the primary difference is compression do you think it would make sense to do something like this instead?
private def serve_file(context : Server::Context, file_info, file_path : Path, last_modified : Time)
env.response.headers["X-Content-Type-Options"] = "nosniff"
config = Kemal.config
condition = config.is_a?(Hash) && config["gzip"]? == true && file_info.size > 860 && Kemal::Utils.zip_types(file_path.to_s)
if condition && context.request.headers.includes_word?("Accept-Encoding", "gzip")
context.response.headers["Content-Encoding"] = "gzip"
context.response.output = Compress::Gzip::Writer.new(context.response.output, sync_close: true)
elsif condition && context.request.headers.includes_word?("Accept-Encoding", "deflate")
context.response.headers["Content-Encoding"] = "deflate"
context.response.output = Compress::Deflate::Writer.new(context.response.output, sync_close: true)
end
super
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably, yes. But I'd like to keep the refactoring of StaticFileHandler
as a separate change, and address serve_file
in a follow-up.
@@ -1,88 +1,120 @@ | |||
module Kemal | |||
class StaticFileHandler < HTTP::StaticFileHandler | |||
# ameba:disable Metrics/CyclomaticComplexity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: I'm not sure why this needs to be removed. But ameba told me to 🤷
The #call
def didn't change its complexity.
else | ||
if @fallthrough | ||
call_next(context) | ||
{% if compare_versions(Crystal::VERSION, "1.17.0") >= 0 %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to support old versions, better add crystal 1.16.0 to the CI matrix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @straight-shoota 🙏
This patch simplifies the implementation of
StaticFileHandler
by inheriting most behaviour from the stdlib implementation. We only need to override the parts where Kemal provides custom behaviour.Following the upstream implementation more closely avoids missing out on improvements (such as the fix for #710 would have been available for a long time).
This requires a
HTTP::StaticFileHandler
with patch crystal-lang/crystal#15678