8000 Make use of helper methods in `StaticFileHandler` by straight-shoota · Pull Request #714 · kemalcr/kemal · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

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

Merged
merged 4 commits into from
Jun 3, 2025

Conversation

straight-shoota
Copy link
Contributor

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

@straight-shoota straight-shoota self-assigned this Apr 17, 2025
straight-shoota added a commit to crystal-lang/crystal that referenced this pull request May 10, 2025
`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).
# 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)
Copy link
Contributor

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

Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@straight-shoota straight-shoota marked this pull request as ready for review May 27, 2025 08:37
else
if @fallthrough
call_next(context)
{% if compare_versions(Crystal::VERSION, "1.17.0") >= 0 %}
Copy link
Contributor

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.

Copy link
Member
@sdogruyol sdogruyol left a 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 🙏

@sdogruyol sdogruyol merged commit f41025c into master Jun 3, 2025
15 checks passed
@straight-shoota straight-shoota deleted the feat/static_file_handler branch June 3, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0