<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kemal - Fast, Effective, Simple web framework for Crystal</title>
    <description>Fast, Effective, Simple web framework for Crystal</description>
    <link>http://kemalcr.com/</link>
    <atom:link href="http://kemalcr.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 21 Jul 2026 11:44:09 +0000</pubDate>
    <lastBuildDate>Tue, 21 Jul 2026 11:44:09 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Kemal 1.12.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework for &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal &lt;strong&gt;1.12.0&lt;/strong&gt; is out :tada: This release brings &lt;strong&gt;Crystal 1.21.0&lt;/strong&gt; support and a first-class &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sse&lt;/code&gt;&lt;/strong&gt; helper for Server-Sent Events, plus a handful of reliability and DX fixes.&lt;/p&gt;

&lt;h2 id=&quot;server-sent-events-with-sse-zap&quot;&gt;Server-Sent Events with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sse&lt;/code&gt; :zap:&lt;/h2&gt;

&lt;p&gt;You can now stream events to the client with a dedicated &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sse&lt;/code&gt;&lt;/strong&gt; route helper—no manual header juggling required (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/755&quot;&gt;#755&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sse&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/events&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tick&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;event: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tick&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;id: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ideal for live dashboards, notifications, and any one-way push where WebSockets would be overkill. Keep the connection open, send named events with optional ids, and let Kemal handle the SSE framing.&lt;/p&gt;

&lt;h2 id=&quot;crystal-1210-support-crystal_ball&quot;&gt;Crystal 1.21.0 support :crystal_ball:&lt;/h2&gt;

&lt;p&gt;Kemal 1.12.0 is tested and ready for &lt;strong&gt;Crystal 1.21.0&lt;/strong&gt;. The minimum Crystal version is now &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;= 1.12.0&lt;/code&gt;&lt;/strong&gt;—please upgrade your toolchain if you are still on an older release.&lt;/p&gt;

&lt;h2 id=&quot;fixes-and-polish-wrench&quot;&gt;Fixes and polish :wrench:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Headers already sent&lt;/strong&gt;: Avoid an unhandled exception when an error path tries to write headers that were already flushed to the client (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/760&quot;&gt;#760&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;before_all&lt;/code&gt; filters&lt;/strong&gt;: Fixed filters running twice (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/758&quot;&gt;#758&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CLI &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--help&lt;/code&gt;&lt;/strong&gt;: Show the actual host/port defaults when they have been overridden (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/751&quot;&gt;#751&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;Full change history and PR links are in the &lt;a href=&quot;https://github.com/kemalcr/kemal/blob/master/CHANGELOG.md&quot;&gt;CHANGELOG&lt;/a&gt;. Release tag: &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v1.12.0&quot;&gt;v1.12.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For end-to-end sample apps (blog, JSON API, WebSockets, OAuth, and more), see &lt;strong&gt;&lt;a href=&quot;https://github.com/sdogruyol/kemal-by-example&quot;&gt;Kemal by Example&lt;/a&gt;&lt;/strong&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can help sustain development via &lt;a href=&quot;https://github.com/sponsors/sdogruyol&quot;&gt;GitHub Sponsors&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Jul 2026 03:00:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2026/07/21/kemal-1.12.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2026/07/21/kemal-1.12.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 1.11.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework for &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal &lt;strong&gt;1.11.0&lt;/strong&gt; is out :tada: This release is focused on &lt;strong&gt;security hardening&lt;/strong&gt; for multipart uploads and &lt;strong&gt;WebSocket&lt;/strong&gt; connections. If you run Kemal in production, upgrading is strongly recommended :shield:&lt;/p&gt;

&lt;h2 id=&quot;chunked-multipart-limits-lock&quot;&gt;Chunked multipart limits :lock:&lt;/h2&gt;

&lt;p&gt;Multipart form parsing now respects safer limits for &lt;strong&gt;chunked&lt;/strong&gt; bodies, closing a gap where very large fields could be abused (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/748&quot;&gt;#748&lt;/a&gt;). Thanks &lt;a href=&quot;https://github.com/canermastan&quot;&gt;@canermastan&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;You can cap the size of a single multipart form field (default is &lt;strong&gt;8 MB&lt;/strong&gt;):&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;max_multipart_form_field_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tune this to match your app (file uploads, API payloads, etc.) so legitimate traffic still flows while oversized fields are rejected early.&lt;/p&gt;

&lt;h2 id=&quot;websocket-origin-validation-globe_with_meridians&quot;&gt;WebSocket origin validation :globe_with_meridians:&lt;/h2&gt;

&lt;p&gt;Browsers send an &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Origin&lt;/code&gt;&lt;/strong&gt; header on WebSocket handshakes. Kemal can now &lt;strong&gt;validate&lt;/strong&gt; that header against an allow list, so connections from unexpected sites are rejected (&lt;a href=&quot;https://github.com/kemalcr/kemal/pull/749&quot;&gt;#749&lt;/a&gt;). Thanks &lt;a href=&quot;https://github.com/past3l&quot;&gt;@past3l&lt;/a&gt; :pray:&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;websocket_allowed_origins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://myapp.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://localhost:3000&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Use your real production origins (and local dev URLs) here. Without configuration, behavior stays compatible with existing apps; set the list when you want strict origin checks.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Full change history and PR links are in the &lt;a href=&quot;https://github.com/kemalcr/kemal/blob/master/CHANGELOG.md&quot;&gt;CHANGELOG&lt;/a&gt;. Release tag: &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v1.11.0&quot;&gt;v1.11.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For end-to-end sample apps (blog, JSON API, WebSockets, OAuth, and more), see &lt;strong&gt;&lt;a href=&quot;https://github.com/sdogruyol/kemal-by-example&quot;&gt;Kemal by Example&lt;/a&gt;&lt;/strong&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can help sustain development via &lt;a href=&quot;https://github.com/sponsors/sdogruyol&quot;&gt;GitHub Sponsors&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Apr 2026 12:00:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2026/04/13/kemal-1.11.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2026/04/13/kemal-1.11.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 1.10.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework for &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 1.10.0 is here :tada: This is the biggest Kemal release to date: a modular router, a clearer way to plug in middleware, richer response helpers, and several reliability fixes across routing, the CLI, and request parsing :rocket:&lt;/p&gt;

&lt;h2 id=&quot;modular-kemalrouter-compass&quot;&gt;Modular &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kemal::Router&lt;/code&gt; :compass:&lt;/h2&gt;

&lt;p&gt;You can now build &lt;strong&gt;namespaced&lt;/strong&gt; apps with &lt;strong&gt;scoped filters&lt;/strong&gt;, &lt;strong&gt;WebSocket&lt;/strong&gt; routes, and &lt;strong&gt;flexible mounting&lt;/strong&gt;—while the classic top-level DSL stays fully supported.&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;kemal&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/users&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;users: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/:id&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;user &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mount&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api/v1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This makes it easier to organize large APIs, version routes, and reuse sub-applications without losing Kemal’s familiar style.&lt;/p&gt;

&lt;h2 id=&quot;the-use-keyword-for-middleware-link&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use&lt;/code&gt; keyword for middleware :link:&lt;/h2&gt;

&lt;p&gt;Register &lt;strong&gt;global&lt;/strong&gt; or &lt;strong&gt;path-specific&lt;/strong&gt; middleware in one place. You can pass a single handler, an &lt;strong&gt;array&lt;/strong&gt; of handlers, and control &lt;strong&gt;where&lt;/strong&gt; they sit in the chain.&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;kemal&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Path-specific middlewares for /api routes&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CORSHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AuthHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;Public home&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api/users&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;users: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;chainable-response-helpers-art&quot;&gt;Chainable response helpers :art:&lt;/h2&gt;

&lt;p&gt;Response helpers are &lt;strong&gt;chainable&lt;/strong&gt; for JSON, HTML, text, and XML. They understand &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP::Status&lt;/code&gt;&lt;/strong&gt; (including symbols like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:created&lt;/code&gt;), and you can &lt;strong&gt;halt&lt;/strong&gt; with a fully built response—handy for short API error paths.&lt;/p&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;kemal&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/users&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;users: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/users&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:created&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;id: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;created: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/admin&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;halt&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;403&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;h1&amp;gt;Forbidden&amp;lt;/h1&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/api/users&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;data: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]},&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;content_type: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;application/vnd.api+json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;filters-and-routing-correctness-white_check_mark&quot;&gt;Filters and routing correctness :white_check_mark:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Wildcard filters&lt;/strong&gt;: Global wildcard filters now &lt;strong&gt;always run&lt;/strong&gt; as intended, while &lt;strong&gt;namespace&lt;/strong&gt; filters stay &lt;strong&gt;scoped&lt;/strong&gt; to their routes—so behavior matches what you expect in modular apps.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Route LRU cache&lt;/strong&gt;: The route lookup cache is now &lt;strong&gt;concurrency-safe&lt;/strong&gt; thanks to a &lt;strong&gt;Mutex&lt;/strong&gt;, which matters under parallel request handling.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OverrideMethodHandler&lt;/code&gt;&lt;/strong&gt;: Fixed a &lt;strong&gt;route cache&lt;/strong&gt; bug when using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_method&lt;/code&gt; parameter for HTTP verb override (e.g. in HTML forms).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;cli-and-request-body-wrench&quot;&gt;CLI and request body :wrench:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CLI&lt;/strong&gt;: SSL validation and option parsing were tightened, with expanded specs around CLI behavior.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParamParser#raw_body&lt;/code&gt;&lt;/strong&gt;: Handlers can read the &lt;strong&gt;raw body&lt;/strong&gt; multiple times when needed (for example alongside &lt;strong&gt;kemal-session&lt;/strong&gt;), while still using parsed body params elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-crystal highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;raw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;raw_body&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# raw body, multiple handlers can call it&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# parsed body&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks for using and supporting Kemal. Full details and links to the related pull requests are in the &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v1.10.0&quot;&gt;v1.10.0 release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://github.com/sponsors/sdogruyol&quot;&gt;Github Sponsors&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Mar 2026 19:00:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2026/03/03/kemal-1.10.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2026/03/03/kemal-1.10.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 1.9.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework for &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 1.9.0 is here :tada: This release brings Crystal 1.19.0 support along with important security improvements and performance optimizations :rocket:&lt;/p&gt;

&lt;h2 id=&quot;crystal-1190-support-gem&quot;&gt;Crystal 1.19.0 Support :gem:&lt;/h2&gt;

&lt;p&gt;Kemal now fully supports Crystal 1.19.0, keeping up with the latest Crystal release. You can now enjoy all the new features and improvements that Crystal 1.19.0 brings to the table :heart:&lt;/p&gt;

&lt;h2 id=&quot;security-enhancement-shield&quot;&gt;Security Enhancement :shield:&lt;/h2&gt;

&lt;p&gt;This release includes an important security update that &lt;strong&gt;limits the maximum request body size&lt;/strong&gt; to prevent DoS (Denial of Service) attacks. This protection ensures your Kemal applications are more resilient against malicious requests attempting to overwhelm your server with large payloads.&lt;/p&gt;

&lt;p&gt;By default, Kemal now enforces sensible limits on incoming request body sizes, making your applications more secure out of the box :lock:&lt;/p&gt;

&lt;h2 id=&quot;performance-optimization-zap&quot;&gt;Performance Optimization :zap:&lt;/h2&gt;

&lt;p&gt;We’ve optimized JSON parameter parsing by directly using the request body IO instead of reading it into memory first. This improvement reduces memory allocations and speeds up JSON request handling, making your API endpoints even faster :fire:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can check the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v1.9.0&quot;&gt;CHANGELOG&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://github.com/sponsors/sdogruyol&quot;&gt;Github Sponsors&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Thu, 29 Jan 2026 11:49:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2026/01/29/kemal-1.9.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2026/01/29/kemal-1.9.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 1.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework written in &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/sdogruyol&quot;&gt;I’m&lt;/a&gt; super excited and happy to release Kemal 1.0 on my birthday (Mar 22) right after Crystal 1.0. It’s the best birthday present I could ever wish for :birthday:&lt;/p&gt;

&lt;p&gt;This release adds support for Crystal 1.0 and makes Kemal the first Crystal project to fully support Crystal 1.0.&lt;/p&gt;

&lt;p&gt;It’s been a long ride and Kemal is 1.0 after:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;733 Commits&lt;/li&gt;
  &lt;li&gt;601 Pull Requests&lt;/li&gt;
  &lt;li&gt;48 Releases&lt;/li&gt;
  &lt;li&gt;56 Contributors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and we’re just starting :rocket:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can check the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v1.0.0&quot;&gt;CHANGELOG&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://www.patreon.com/sdogruyol&quot;&gt;Patreon&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Mon, 22 Mar 2021 20:21:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2021/03/22/kemal-1.0.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2021/03/22/kemal-1.0.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 0.24.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework written in &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 0.24.0 is here :tada:&lt;/p&gt;

&lt;p&gt;This release brings support for Crystal 0.26.0 and adds new features. There are also some breaking changes.&lt;/p&gt;

&lt;h2 id=&quot;new-and-shiny-exception-page-star&quot;&gt;New and Shiny Exception Page :star:&lt;/h2&gt;

&lt;p&gt;Thanks to the awesome &lt;a href=&quot;exception_page&quot;&gt;exception_page&lt;/a&gt; shard, we got a new and shiny exception page implemented by &lt;a href=&quot;https://github.com/mamantoha&quot;&gt;@mamantoha&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/61285/42134697-a83be602-7d49-11e8-9082-06b53d26106d.png&quot; alt=&quot;new exception page&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;custom-port-bindings-tada&quot;&gt;Custom Port Bindings :tada:&lt;/h2&gt;

&lt;p&gt;You can now bind a single Kemal server to multiple ports. Thanks to &lt;a href=&quot;https://github.com/straight-shoota&quot;&gt;@straight-shoota&lt;/a&gt; :pray:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;not_nil!&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;bind_tcp&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;bind_tcp&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3001&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;breaking-changes-hammer&quot;&gt;Breaking changes :hammer:&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Removed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env.params.files&lt;/code&gt;. You can use Crystal’s built-in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP::FormData.parse&lt;/code&gt; instead&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/upload&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;FormData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filename&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;is_a?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;No filename included in upload&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;public_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;uploads/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tmpfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;Upload OK&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;From now on to access dynamic url params in a WebSocket route you have to use:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/:id&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ws_route_lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Removed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_method&lt;/code&gt; magic param from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env.params.body&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can check the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v0.24.0&quot;&gt;CHANGELOG&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://www.patreon.com/sdogruyol&quot;&gt;Patreon&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Tue, 14 Aug 2018 14:21:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2018/08/14/kemal-0.24.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2018/08/14/kemal-0.24.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 0.21.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Effective, Simple web framework written in &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 0.21.0 is here :tada: This release brings long wanted features with more performance :rocket:&lt;/p&gt;

&lt;h2 id=&quot;websocket-context-cookie&quot;&gt;WebSocket Context :cookie:&lt;/h2&gt;

&lt;p&gt;A long wanted feature, allows one to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP::Server::Context&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ws&lt;/code&gt; declarations :heart_eyes: This would allow accessing named url parameters and query parameters in WebSocket routes.&lt;/p&gt;

&lt;p&gt;For example consider having a WebSocket url like&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ws://myawesome.site/kemal?username=sdogruyol&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now you can access these variables from your url within your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ws&lt;/code&gt; route :sunglasses:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/:room_name&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;room_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; kemal&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; sdogruyol&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;customizable-static-file-headers-clap&quot;&gt;Customizable Static File Headers :clap:&lt;/h2&gt;

&lt;p&gt;Another long wanted feature, which adds support for customizing the headers of built-in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kemal::StaticFileHandler&lt;/code&gt; :hammer: Useful for single page applications which rely on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a quick snippet for allowing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORS&lt;/code&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.js&lt;/code&gt; files.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;static_headers&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filepath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filestat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filepath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/\.js$/&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Access-Control-Allow-Origin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;more-performance-rocket&quot;&gt;More Performance :rocket:&lt;/h2&gt;

&lt;p&gt;Kemal is built for being fast, we take &lt;em&gt;performance&lt;/em&gt; seriously. In recent benchmarks we discovered that Kemal is being blazing fast :fire:&lt;/p&gt;

&lt;p&gt;However, that’s not a reason to stop us from getting faster :fire:
This release brings &lt;em&gt;%10-%15 performance increase&lt;/em&gt; in overall execution times.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/blog/kemal_techempower_preview2.png&quot; alt=&quot;Kemal Blazing Fast&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can check the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v0.21.0&quot;&gt;CHANGELOG&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://www.patreon.com/sdogruyol&quot;&gt;Patreon&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Sep 2017 19:01:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2017/09/05/kemal-0.21.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2017/09/05/kemal-0.21.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 0.20.0 released!</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Kemal is a Fast, Simple, Effective web framework written in &lt;a href=&quot;https://crystal-lang.org/&quot;&gt;Crystal&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 0.20.0 is here :tada: This release brings more modularity and performance :rocket:&lt;/p&gt;

&lt;h2 id=&quot;crystal-0230-support-&quot;&gt;Crystal 0.23.0 support ✨&lt;/h2&gt;

&lt;p&gt;The latest Crystal 0.23.0 release is already supported by Kemal. Just update your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shard.yml&lt;/code&gt; to use Kemal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.20.0&lt;/code&gt; :sunglasses:&lt;/p&gt;

&lt;div class=&quot;language-yml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;kemal&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;github&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;kemalcr/kemal&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;0.20.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;customizable-handlers-clap&quot;&gt;Customizable Handlers :clap:&lt;/h2&gt;

&lt;p&gt;Great news everyone 🎉 All handlers are now completely &lt;strong&gt;&lt;em&gt;customizable&lt;/em&gt;&lt;/strong&gt;!. Use the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Kemal&lt;/code&gt; handlers or go wild to build your own custom framework, it’s all up to you ⛏&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Don&apos;t forget to add `Kemal::RouteHandler::INSTANCE` or your routes won&apos;t work!&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handlers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;InitHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YourHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RouteHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also insert a handler into a specific position.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# This adds MyCustomHandler instance to 1 position. Be aware that the index starts from 0.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;add_handler&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MyCustomHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Thanks for using and supporting Kemal. You can check the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v0.20.0&quot;&gt;CHANGELOG&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;P.S: You can support Kemal development via &lt;a href=&quot;https://www.patreon.com/sdogruyol&quot;&gt;Patreon&lt;/a&gt; :pray:&lt;/p&gt;

&lt;p&gt;Happy Crystalling :heart:&lt;/p&gt;
</description>
        <pubDate>Sat, 01 Jul 2017 18:55:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2017/07/01/kemal-0.20.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2017/07/01/kemal-0.20.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 0.18.1 released!</title>
        <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;It’s just been 59 minutes since &lt;a href=&quot;https://groups.google.com/forum/#!topic/crystal-lang/sGxeIxlLKX4&quot;&gt;Crystal 0.21.0 is released&lt;/a&gt; and Kemal 0.18.1 is already here :rocket:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Crystal 0.21.0 support :heart:&lt;/li&gt;
  &lt;li&gt;Drop &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multipart.cr&lt;/code&gt; dependency. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multipart&lt;/code&gt; support is now built-into Crystal &amp;lt;3&lt;/li&gt;
  &lt;li&gt;Since Crystal 0.21.0 comes built-in with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multipart&lt;/code&gt; there are some minor changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;meta&lt;/code&gt; has been removed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileUpload&lt;/code&gt; and now it has the following properties&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmpfile&lt;/code&gt;: This is temporary file for file upload. Useful for saving the upload file.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filename&lt;/code&gt;: File name of the file upload. (logo.png, images.zip e.g)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headers&lt;/code&gt;: Headers for the file upload.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;creation_time&lt;/code&gt;: Creation time of the file upload.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modification_time&lt;/code&gt;: Last Modification time of the file upload.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read_time&lt;/code&gt;: Read time of the file upload.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt;: Size of the file upload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;P.S&lt;/em&gt;: File uploads are faster :fire:&lt;/p&gt;

&lt;p&gt;Happy Crystalling!&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Feb 2017 18:55:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2017/02/21/kemal-0.18.1-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2017/02/21/kemal-0.18.1-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
      <item>
        <title>Kemal 0.18.0 released!</title>
        <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Kemal 0.18.0 is here :tada: Kemal gets better yet becoming simpler :heartpulse:&lt;/p&gt;

&lt;h2 id=&quot;simpler-file-upload&quot;&gt;Simpler File Upload&lt;/h2&gt;

&lt;p&gt;File uploads can now be accessed from request &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;params&lt;/code&gt; like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env.params.files[&quot;filename&quot;]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It has 5 useful methods to get the job done!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmpfile&lt;/code&gt;: This is the temporary file for file upload. Useful for saving or manipulating the upload file.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmpfile_path&lt;/code&gt;: File path of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmpfile&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filename&lt;/code&gt;: File name of the file upload. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logo.png&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;images.zip&lt;/code&gt; e.g)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;meta&lt;/code&gt;: Meta information for the file upload.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headers&lt;/code&gt;: Request headers for the file upload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a fully working sample for reading an image file upload with key &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;image1&lt;/code&gt; and saving it under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public/uploads&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/upload&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;image1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tmpfile&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Kemal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;public_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;uploads/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;Upload ok&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can test this with below &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl -F &quot;image1=@/Users/serdar/Downloads/kemal.png&quot; http://localhost:3000/upload&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;file-streaming&quot;&gt;File Streaming&lt;/h2&gt;

&lt;p&gt;Streaming is a serious business and Kemal has you covered :sunglasses: This release adds &lt;a href=&quot;http://www.rfc-base.org/rfc-7233.html&quot;&gt;RFC7233&lt;/a&gt; support.&lt;/p&gt;

&lt;p&gt;What this practically means is that you can partially request a file from Kemal without downloading the rest by utilizing HTTP Range header. Ain’t that cool :sushi:&lt;/p&gt;

&lt;h2 id=&quot;more&quot;&gt;More&lt;/h2&gt;

&lt;p&gt;Be sure to check out the full &lt;a href=&quot;https://github.com/kemalcr/kemal/releases/tag/v0.18.0&quot;&gt;CHANGELOG&lt;/a&gt; for the full awesomeness and bug fixes :) And a big THANKS to everyone for making this release possible :heart:&lt;/p&gt;

&lt;p&gt;Happy Crystalling!&lt;/p&gt;
</description>
        <pubDate>Sat, 11 Feb 2017 18:55:00 +0000</pubDate>
        <link>http://kemalcr.com/blog/2017/02/11/kemal-0.18.0-released/</link>
        <guid isPermaLink="true">http://kemalcr.com/blog/2017/02/11/kemal-0.18.0-released/</guid>
        
        <category>crystal</category>
        
        <category>kemal</category>
        
        
      </item>
    
  </channel>
</rss>
