Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: onyxframework/http
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.7.4
Choose a base ref
...
head repository: onyxframework/http
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 12 commits
  • 17 files changed
  • 2 contributors

Commits on Apr 20, 2019

  1. fix: new Crystal HTTP status syntax

    BREAKING CHANGE: Requires Crystal 0.28+
    vladfaust committed Apr 20, 2019
    Copy the full SHA
    f43fb97 View commit details
  2. feat (Router): new API, add namespaces

    BREAKING CHANGE: `Router#new` now yields self as an argument
    BREAKING CHANGE: Removed `Router#draw` in favor of new `#on` overload with namespace
    
    Closes #71
    vladfaust committed Apr 20, 2019
    Copy the full SHA
    bff044e View commit details
  3. Copy the full SHA
    7558eea View commit details
  4. bump: 0.8.0

    vladfaust committed Apr 20, 2019
    Copy the full SHA
    8a63ade View commit details
  5. Copy the full SHA
    387aa3b View commit details
  6. Copy the full SHA
    c042410 View commit details
  7. Copy the full SHA
    2041154 View commit details

Commits on May 28, 2019

  1. Copy the full SHA
    873ae15 View commit details
  2. bump: 0.8.1

    vladfaust committed May 28, 2019
    Copy the full SHA
    7e355aa View commit details

Commits on Jun 8, 2019

  1. deps: crystal 0.28.0 β†’ 0.29.0

    It still works with Crystal 0.28, though.
    
    Require bug is related to crystal-lang/crystal#7408
    David Keller authored and vladfaust committed Jun 8, 2019
    Copy the full SHA
    289ae6c View commit details
  2. bump: 0.8.2

    vladfaust committed Jun 8, 2019
    Copy the full SHA
    5e950b4 View commit details

Commits on Aug 13, 2019

  1. deps: crystal β†’ 0.30.1, http-params-serializable β†’ 0.4.0

    BREAKING CHANGE: dependency version bumped
    vladfaust committed Aug 13, 2019
    Copy the full SHA
    7b23271 View commit details
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -22,13 +22,15 @@ Add these lines to your application's `shard.yml`:
dependencies:
onyx:
github: onyxframework/onyx
version: ~> 0.3.0
version: ~> 0.6.0
onyx-http:
github: onyxframework/http
version: ~> 0.7.0
version: ~> 0.9.0
```
This shard follows [Semantic Versioning v2.0.0](http://semver.org/), so check [releases](https://github.com/onyxframework/http/releases) and change the `version` accordingly. Please visit [github.com/crystal-lang/shards](https://github.com/crystal-lang/shards) to know more about Crystal shards.
This shard follows [Semantic Versioning v2.0.0](http://semver.org/), so check [releases](https://github.com/onyxframework/http/releases) and change the `version` accordingly.

> Note that until Crystal is officially released, this shard would be in beta state (`0.*.*`), with every **minor** release considered breaking. For example, `0.1.0` β†’ `0.2.0` is breaking and `0.1.0` β†’ `0.1.1` is not.

## Usage πŸ’»

@@ -37,11 +39,11 @@ The simplest hello world:
```crystal
require "onyx/http"
Onyx.get "/" do |env|
Onyx::HTTP.get "/" do |env|
env.response << "Hello, world!"
end
Onyx.listen
Onyx::HTTP.listen
```

Encapsulated endpoints:
@@ -61,14 +63,14 @@ struct GetUser
end
def call
user = Onyx.query(User.where(id: params.path.id)).first? # This code is part of onyx/sql
user = Onyx::SQL.query(User.where(id: params.path.id)).first? # This code is part of onyx/sql
raise UserNotFound.new unless user
return UserView.new(user)
end
end
Onyx.get "/users/:id", GetUser
Onyx::HTTP.get "/users/:id", GetUser
```

Encapsulated views:
@@ -95,7 +97,7 @@ struct Echo
end
end
Onyx.ws "/", Echo
Onyx::HTTP.ws "/", Echo
```

## Documentation πŸ“š
6 changes: 3 additions & 3 deletions shard.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: onyx-http
version: 0.7.4
version: 0.9.0

authors:
- Vlad Faust <mail@vladfaust.com>

crystal: 0.27.2
crystal: 0.30.1

license: MIT

@@ -20,7 +20,7 @@ dependencies:
version: ~> 0.2.0
http-params-serializable:
github: vladfaust/http-params-serializable
version: ~> 0.3.0
version: ~> 0.4.0
kilt:
github: jeromegn/kilt
verstion: ~> 0.4.0
4 changes: 2 additions & 2 deletions spec/onyx-rest/channel_spec.cr
Original file line number Diff line number Diff line change
@@ -32,8 +32,8 @@ class Spec::Channel
def initialize
renderer = Onyx::HTTP::Middleware::Renderer.new
rescuer = Onyx::HTTP::Middleware::Rescuer::Silent(Exception).new(renderer)
router = Onyx::HTTP::Middleware::Router.new do
ws "/test/:id", Channel
router = Onyx::HTTP::Middleware::Router.new do |r|
r.ws "/test/:id", Channel
end

@server = Onyx::HTTP::Server.new([rescuer, router])
4 changes: 2 additions & 2 deletions spec/onyx-rest/endpoint/errors_spec.cr
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@ class Spec::Endpoint::Errors

class Server
def initialize
router = Onyx::HTTP::Middleware::Router.new do
get "/", Endpoint
router = Onyx::HTTP::Middleware::Router.new do |r|
r.get "/", Endpoint
end

renderer = Onyx::HTTP::Middleware::Renderer.new
20 changes: 12 additions & 8 deletions spec/onyx-rest/endpoint/params_spec.cr
Original file line number Diff line number Diff line change
@@ -62,21 +62,25 @@ class Spec::Endpoint::Params
include Onyx::HTTP::Endpoint

params do
form require: true do
form require: true, preserve_body: true do
type foo : Int32
end
end

def call
context.response << context.request.body.not_nil!.gets_to_end << "\n"
context.response << params.form.foo
end
end

class Server
def initialize
router = Onyx::HTTP::Middleware::Router.new do
post "/:foo/:bar", Endpoint
post "/form", FormEndpoint
router = Onyx::HTTP::Middleware::Router.new do |r|
r.on "/:foo" do
r.post "/:bar", Endpoint
end

r.post "/form", FormEndpoint
end

renderer = Onyx::HTTP::Middleware::Renderer.new
@@ -150,28 +154,28 @@ describe "Onyx::HTTP::Endpoint .params" do
end
end

context "when form is required" do
context "when form is required and body is preserved" do
context "without content type" do
it do
response = client.post("/form", body: "foo=42")
response.status_code.should eq 200
response.body.should eq "42"
response.body.should eq "foo=42\n42"
end
end

context "with invalid content type" do
it do
response = client.post("/form", headers: HTTP::Headers{"Content-Type" => "bar"}, body: "foo=42")
response.status_code.should eq 200
response.body.should eq "42"
response.body.should eq "foo=42\n42"
end
end

context "with valid content type" do
it do
response = client.post("/form", headers: HTTP::Headers{"Content-Type" => "application/x-www-form-urlencoded"}, body: "foo=42")
response.status_code.should eq 200
response.body.should eq "42"
response.body.should eq "foo=42\n42"
end
end

4 changes: 2 additions & 2 deletions spec/onyx-rest/endpoint/view_spec.cr
Original file line number Diff line number Diff line change
@@ -20,8 +20,8 @@ module Spec::Endpoint::View

class Server
def initialize
router = Onyx::HTTP::Middleware::Router.new do
get "/", Endpoint
router = Onyx::HTTP::Middleware::Router.new do |r|
r.get "/", Endpoint
end

renderer = Onyx::HTTP::Middleware::Renderer.new
4 changes: 2 additions & 2 deletions spec/onyx-rest/view_spec.cr
Original file line number Diff line number Diff line change
@@ -37,8 +37,8 @@ class Spec::View
def initialize
renderer = Onyx::HTTP::Middleware::Renderer.new
rescuer = Onyx::HTTP::Middleware::Rescuer::Silent(Exception).new(renderer)
router = Onyx::HTTP::Middleware::Router.new do
get "/" do |env|
router = Onyx::HTTP::Middleware::Router.new do |r|
r.get "/" do |env|
TestView.new("baz")
end
end
6 changes: 3 additions & 3 deletions src/onyx-http/channel.cr
Original file line number Diff line number Diff line change
@@ -73,10 +73,10 @@ require "./endpoint"
# Router example:
#
# ```
# router = Onyx::HTTP::Router.new do
# ws "/", Channels::Echo
# router = Onyx::HTTP::Router.new do |r|
# r.ws "/", Channels::Echo
# # Equivalent of
# ws "/" do |context|
# r.ws "/" do |context|
# channel.call(context)
# end
# end
6 changes: 3 additions & 3 deletions src/onyx-http/endpoint.cr
Original file line number Diff line number Diff line change
@@ -46,10 +46,10 @@ require "./ext/http/server/response/view"
# Router example:
#
# ```
# router = Onyx::HTTP::Router.new do
# get "/", Endpoints::GetUser
# router = Onyx::HTTP::Router.new do |r|
# r.get "/", Endpoints::GetUser
# # Equivalent of
# get "/" do |context|
# r.get "/" do |context|
# view? = Endpoints::GetUser.call(context)
#
# if view = view?.as?(HTTP::View)
13 changes: 13 additions & 0 deletions src/onyx-http/endpoint/params.cr
Original file line number Diff line number Diff line change
@@ -11,6 +11,19 @@ module Onyx::HTTP::Endpoint
# which all are `HTTP::Error`s with 400 code.
macro params(&block)
struct Params
# This method is used to copy request body if needed.
protected def copy_io(from : IO, limit = nil) : IO
to = IO::Memory.new

if limit
IO.copy(from, to, limit)
else
IO.copy(from, to)
end

return to.rewind
end

def initialize(request : ::HTTP::Request)
end

12 changes: 11 additions & 1 deletion src/onyx-http/endpoint/params/form.cr
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ module Onyx::HTTP::Endpoint
# * `require` -- if set to `true`, will attempt to parse form params regardless
# of the `"Content-Type"` header and return a parameter error otherwise; the `params.form`
# getter becomes non-nilable
# * `preserve_body` -- if set to `true`, the request body would be **copied**
# and thus accessible after the parsing
#
# ## Example
#
@@ -74,7 +76,7 @@ module Onyx::HTTP::Endpoint
# ```shell
# > curl -X POST -d "user[email]=foo@example.com" http://localhost:5000/users/42
# ```
macro form(require required = false, &block)
macro form(require required = false, preserve_body = false, &block)
class FormError < Onyx::HTTP::Error(400)
def initialize(message : String, @path : Array(String))
super(message)
@@ -152,7 +154,15 @@ module Onyx::HTTP::Endpoint
if request.headers["Content-Type"]?.try &.=~ /^application\/x-www-form-urlencoded/
{% end %}
if body = request.body
{% if preserve_body %}
body = copy_io(body, request.content_length)
{% end %}

@form = Form.from_query(body.gets_to_end)

{% if preserve_body %}
request.body = body.rewind
{% end %}
else
raise FormError.new("Missing request body", [] of String)
end
12 changes: 11 additions & 1 deletion src/onyx-http/endpoint/params/json.cr
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@ module Onyx::HTTP::Endpoint
# * `require` -- if set to `true`, will attempt to parse JSON params regardless
# of the `"Content-Type"` header and return a parameter error otherwise; the `params.json`
# getter becomes non-nilable
# * `preserve_body` -- if set to `true`, the request body would be **copied**
# and thus accessible after the parsing
#
# ## Example
#
@@ -75,7 +77,7 @@ module Onyx::HTTP::Endpoint
# ```shell
# > curl -X POST -d '{"user":{"email":"foo@example.com"}}' http://localhost:5000/users/1
# ```
macro json(require required = false, &block)
macro json(require required = false, preserve_body = false, &block)
class JSONError < Onyx::HTTP::Error(400)
end

@@ -146,7 +148,15 @@ module Onyx::HTTP::Endpoint
if request.headers["Content-Type"]?.try &.=~ /^application\/json/
{% end %}
if body = request.body
{% if preserve_body %}
body = copy_io(body, request.content_length)
{% end %}

@json = JSON.from_json(body.gets_to_end)

{% if preserve_body %}
request.body = body.rewind
{% end %}
else
raise JSONError.new("Missing request body")
end
2 changes: 1 addition & 1 deletion src/onyx-http/ext/http/server/response/view.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require "http/server/response"
require "../../../view"
require "../../../../view"

class HTTP::Server::Response
# A view to render.
4 changes: 2 additions & 2 deletions src/onyx-http/middleware/renderer.cr
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ module Onyx::HTTP::Middleware
else
{
error: {
name: ::HTTP.default_status_message_for(500),
name: ::HTTP::Status.new(500).description,
message: nil,
code: 500,
payload: nil,
@@ -201,7 +201,7 @@ module Onyx::HTTP::Middleware
context.response << "500 " << error.status_message
context.response << " β€” " << error.message << "\n\n" << error.backtrace.join("\n")
else
context.response << "500 " << ::HTTP.default_status_message_for(500)
context.response << "500 " << ::HTTP::Status.new(500).description
end
end
end
4 changes: 2 additions & 2 deletions src/onyx-http/middleware/renderer/rest_error.html.ecr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title><%= error.is_a?(Error) ? error.status_message : ::HTTP.default_status_message_for(500) %></title>
<title><%= error.is_a?(Error) ? error.status_message : ::HTTP::Status.new(500).description %></title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700" rel="stylesheet">
<style type="text/css">
@@ -49,7 +49,7 @@
</head>
<body>
<div class="code"><%= error.is_a?(Error) ? error.code : 500 %></div>
<h1 class="status-message"><%= error.is_a?(Error) ? error.status_message : ::HTTP.default_status_message_for(500) %></h1>
<h1 class="status-message"><%= error.is_a?(Error) ? error.status_message : ::HTTP::Status.new(500).description %></h1>
<% if @verbose && (message = error.message) %>
<h2 class="message"><%= message %></h2>
<% end %>
Loading