Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 30 2019 08:08
    hoang17 starred kemalcr/kemal
  • Jan 30 2019 06:38
    cayter starred kemalcr/kemal
  • Jan 27 2019 18:40
  • Jan 27 2019 15:56
    sdogruyol closed #498
  • Jan 27 2019 15:56
    sdogruyol commented #498
  • Jan 27 2019 15:53
    sdogruyol closed #509
  • Jan 27 2019 15:53
    sdogruyol commented #509
  • Jan 27 2019 05:14
    mjb2kmn starred kemalcr/kemal
  • Jan 25 2019 01:42
    unixc3t starred kemalcr/kemal
  • Jan 24 2019 22:41
    talentlessguy starred kemalcr/kemal
  • Jan 24 2019 04:00
    ntilotta starred kemalcr/kemal
  • Jan 23 2019 10:12
    iwaruby starred kemalcr/kemal
  • Jan 23 2019 02:35
    isaced starred kemalcr/kemal
  • Jan 21 2019 18:33
    f9n starred kemalcr/kemal
  • Jan 19 2019 12:53
    SeedyROM starred kemalcr/kemal
  • Jan 17 2019 19:06

    sdogruyol on master

    Do not try to call ExceptionHan… Merge pull request #515 from ke… (compare)

  • Jan 17 2019 19:06
    sdogruyol closed #515
  • Jan 17 2019 19:06
    sdogruyol closed #514
  • Jan 17 2019 19:06
    sdogruyol edited #515
  • Jan 17 2019 15:09
    galfarragem starred kemalcr/kemal
Coding Concepts
@codingconcepts
No worries at all! If i manage, I’ll share back 🙂
Coding Concepts
@codingconcepts

Hey @erdnaxeli, solved for when you get round to testing your handlers :)

Spec.before_each do
  config = Kemal.config
  config.env = "test"
  config.setup
end

Spec.after_each do
  Kemal.config.clear
end

...in addition to calling SomethingApi.setup

erdnaxeli
@erdnaxeli:cervoi.se
[m]
Nice!
Alex Kampa
@alex-kampa
Hello everyone! Does anyhow here know how to run Kemal in silent mode ie without "Kemal doesn't know this way." screens and without any message when there is an execution error?
ddd
@Dan-Do
just overwrite the method error_400 and error_500?
Johannes Müller
@straight-shoota
the error page with stack trace etc. should only be shown in development mode
For adjusting the normal error page, see https://kemalcr.com/guide/#custom-errors
Alex Kampa
@alex-kampa
thanks @Dan-Do and @straight-shoota
Gabor Szabo
@szabgab
Hi, I am new to Kemal (and to Crystal as well). It seems to me that in the spec when I have a get "/blabla" to a URL that does not have a matching route, I get 200 OK. (Unlike when I run the application in which case I get 400 Not found as expected) Am I doing something incorrectly or is this the expected behavior?
Jonathan Silverman
@mixflame
is Kemal still alive? or was it abandoned?
Gabor Szabo
@szabgab
It is alive, but this channel is low on activity. If you need help try the generic #crystal channel or the generic crystal forum: https://forum.crystal-lang.org/
Isaac Sloan
@elorest
Pretty sure it's up to date on github.
Jonathan Silverman
@mixflame
glad to hear that it is alive
i don't need much help just wanted to make sure kemal is still in the toolbox
(right now LOL)
hoe
ops
oops
hows the websockets stuff?
like does it have multi process redis web socket adapter stuff yet for scaling? (i know its extreme because crystal alone is "good enough" but its a documented scaling technique and i wanted to see where crystal is on the issue. I have a good link on it somewhere from hackernoon
Gabor Szabo
@szabgab
I have not tried the websocket part
Jonathan Silverman
@mixflame
ok np
vectorselector
@vectorselector

anyone know how to set encoding of a raw env.request.body to UTF-8?

Stripe integration https://github.com/confact/stripe.cr loads it's helper json file "event.json" just fine, but when I substitute a file that I streamed directly from kemal as such:
payload = env.request.body.as(IO).gets_to_end
File.write("payload.json", payload)
then I get a US-ASCII encoded file.
I encounter parsing problems when trying to construct a Stripe::Webhook.construct_event from my stream (IO) or file,
however, the spec's helper json file "event.json" loads just fine and makes an event.
(secret is working fine with any consistent pair with the spec's "event.json" file)

I get JSON::SerializableError
Exception: Unexpected token: , at line 55, column 4
parsing Stripe::Event::Data#object at line 7, column 5
parsing Stripe::Event#data at line 6, column 3 (JSON::SerializableError)

I'm reasonably sure that the issue is the encoding of my env.request.body, which needs to be a precise bit-copy of the raw request body sent by Stripe, due to their webhook signature comparison authentication functionality.

vectorselector
@vectorselector
I've been trying to set_encoding on the IO, but no luck so far, as it's supposedly defaulting to UTF-8, which is what i need...
https://crystal-lang.org/api/1.0.0/IO.html
yet there is something wrong with MY env.request.body not being a raw UTF-8 string... even though when I pipe my env.request.body to a file it looks the same as the passing-spec's "event.json" !
this file this spec uses works fine in my code with any secret
spec = https://github.com/confact/stripe.cr/blob/master/spec/stripe/methods/webhook_spec.cr
file = https://github.com/confact/stripe.cr/blob/master/spec/support/event.json
vectorselector
@vectorselector
it's very odd, as the env.request.headers show a "Content-Type" => "application/json; charset=utf-8"
but yet, env.request.body.as(IO).gets_to_end gives me something broken, compared to this "event.json" file.
vectorselector
@vectorselector
even weirder is that this env.request.body.as(IO).gets_to_end is a String, and it returns String .valid_encoding? true (valid for UTF-8, according to Crystal String is sequence of UTF-8 characters)
vectorselector
@vectorselector

when I load the 2 files into the application and inspect them, they look identically formatted, yet mine gives parsing errors from_json

Exception: Unexpected token: , at line 55, column 4
parsing Stripe::Event::Data#object at line 7, column 5
parsing Stripe::Event#data at line 6, column 3 (JSON::SerializableError)
from /home/aaron/.crenv/versions/1.0.0/share/crystal/src/json/serialization.cr:159:7 in 'initialize:__pull_for_json_serializable'
from lib/stripe/src/stripe/objects/core/event.cr:4:3 in 'new_from_json_pull_parser'
from lib/stripe/src/stripe/objects/core/event.cr:4:3 in 'new'
from /home/aaron/.crenv/versions/1.0.0/share/crystal/src/json/from_json.cr:13:3 in 'from_json'
from lib/stripe/src/stripe/methods/core/webhook/webhook.cr:17:5 in 'construct_event'

and this "event.json" file parses fine and constructs an event after.

vectorselector
@vectorselector

anyway, the bottom line: Stripe makes a signature as an HMAC of a "secret" and a "signed payload"
the secret is a string.
the signed-payload is a concatenation of header-timestamp, a dot/period ".", and the literal request.body string as UTF-8

then we compare our signature with the signature that Stripe sent in the env.request.header["Stripe-Signature"]

the spec's "event.json" file compares correctly.
my env.request.body.as(IO).gets_to_end does not match signatures.
when I put the contents of env.request.body.as(IO).gets_to_end in a file, it still doesn't work. it looks the same as "event.json" in every way that I can see so far...

vectorselector
@vectorselector

in other words:

 require "stripe"

and in my webhook handler route

  stripe_webhook_secret = "whatever"
  headers = env.request.headers

  myFileData = env.request.body.as(IO).gets_to_end
  File.write("payload.json", myFileData)

  timestamp = Time.utc

  file1 = File.read("event.json") # the file from https://github.com/confact/stripe.cr/blob/master/spec/support/event.json
  file2 = File.read("payload.json") # can try with the file, or even just the IO stream myFileData, which is apparently a String...

  signature = Stripe::Webhook::Signature.compute_signature(
    timestamp,
    file1,
    stripe_webhook_secret
  )
  header = Stripe::Webhook::Signature.generate_header(
    timestamp,
    signature,
    scheme: "v1"
  )
  event = Stripe::Webhook.construct_event(file1, header, stripe_webhook_secret)
  pp event

and file1 works OK and parses and Stripe::Webhook.construct_event is constructed fine.
file2 gets parsing errors starting at the first comma ,

vectorselector
@vectorselector
(sorry about the extra variable headers it's not relevant. we use this fake header as constructed by Stripe::Webhook::Signature.generate_header so it's just the Stripe::Webhook.construct_event that has a problem parsing the file2,)
vectorselector
@vectorselector

but this works fine

payload = env.request.body.as(IO).gets_to_end 
json = JSON.parse(payload)
pp json

but somehow, somehow, payload is different than the literal string Stripe emitted...
for example, comparison here gives false
(#example of stripe_signature = "t=1627478133,v1=66a99c20d015638aec8733ec609a8e1c0555011c0b2275c97e2ec6776aabddfe")

  headers = env.request.headers
  stripe_signature = headers["Stripe-Signature"] 
  sigbits = stripe_signature.split(/,+/)
  t = sigbits[0].lchop("t=")
  v1 = sigbits[1].lchop("v1=")

  signed_payload = t + "." + payload

  hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Algorithm::SHA256, stripe_webhook_secret, signed_payload)

  comparison = Crypto::Subtle.constant_time_compare(hmac.to_s, v1)
  pp comparison
vectorselector
@vectorselector
(or just hmac with no .to_s)
vectorselector
@vectorselector
basically, either using this https://github.com/confact/stripe.cr
or manually verifying per https://stripe.com/docs/webhooks/signatures#verify-manually
even given fabricated headers that SHOULD be equal
i cannot get a signature match with a payload of env.request.body.as(IO).gets_to_end
but i can get a signature match with a payload of this file https://github.com/confact/stripe.cr/blob/master/spec/support/event.json
using ANY secret (in the fake header fabrication, and the expected-signature construction)
vectorselector
@vectorselector
well, upon further looking, Kemal is emitting a proper valid JSON String from env.request.body.as(IO).gets_to_end as far as even CR LF newlines etc. utf-8. at the moment i'm trying to see why the JSON::PullParser.read_raw can't handle a comma "," which is odd... I guess this is not a Kemal pertinent problem, sorry to drag you all through this...
Shootingfly
@shootingfly
If anyone is looking for a micro webframework, Runcobo may be a good choice. https://runcobo.github.io/docs/
Serdar Dogruyol - Sedo セド
@sdogruyol
Hey everyone, a lot of people asked for Discord and here it's
Official Kemal Discord Server is now live 🔊
You can join via https://discord.gg/prSVAZJEpz
Lewis E. Bogan
@lebogan
Will Kemal still support slang after depreciating kilt?
Johannes Müller
@straight-shoota
Yes. You don't need kilt for using slang directly. Or you can install kilt explicitly as a dependency.
It's just been removed from being shipped with kemal.
Lewis E. Bogan
@lebogan
How do you use slang directly?
Johannes Müller
@straight-shoota
Renich
@Renich:matrix.org
[m]
Hello! o/

I'm trying this:

require "kemal"

get "/hello/:name" do
  name = env.params.url["name"]
  "Hello, #{name}!"
end

Kemal.run

But getting this:

[renich@introdesk headers]$ crystal run src/headers.cr 
Showing last frame. Use --error-trace for full trace.

In src/headers.cr:4:10

 4 | name = env.params.url["name"]
            ^--
Error: undefined local variable or method 'env' for top-level

Any idea why?

ddd
@Dan-Do
you need get "/hello/:name" do |env|
ryanprior
@ryanprior:matrix.org
[m]
I want kemal to serve my public/index.html when a user requests /. How do I configure that? If I request /index.html then it works.
vectorselector
@vectorselector
Is there any way to list all routes?
Where do routes even "live"? I don't see them in Kemal.config etc..
ddd
@Dan-Do
Try Kemal::RouteHandler::INSTANCE.routes
vectorselector
@vectorselector
ah ha, thank you @Dan-Do