<FromGitter>
<j8r> @Blacksmoke16 what does it implies for us?
<FromGitter>
<Blacksmoke16> im just saying there is a difference between knowing who the authenticated user is during a request, and if that user has permission to access a specific route
<postmodern>
hello, new to crystal and wanting a more in-depth overview of the C bindings API. For example, how do I map in the `FILE*` type or variable arguments (aka `foo(int x, ...)`)?
<FromGitter>
<Blacksmoke16> for example, what symfony doe, (as thats what im familiar with) is you can define `firewalls` which group together routes that share common authentication logic
<FromGitter>
<j8r> @Blacksmoke16 I guess the user can be in a header, query or path param, then the hanlders do the auth
<FromGitter>
<Blacksmoke16> then they have the concept of user providers, whose job it is to set the authed user on a request
<FromGitter>
<Blacksmoke16> which could be via however you define it, lookup user in db based on jwt token, or username password etc
<FromGitter>
<Blacksmoke16> then from there they have extra stuff to define logic of if that user has access to x
<FromGitter>
<Blacksmoke16> the crystal version of this could be like
<FromGitter>
<Blacksmoke16> 1) resolve the user from the request, 2) determine the firewall to use based on request path, 3) determine if that user has access to a specific route within that "domain"
<FromGitter>
<Blacksmoke16> i didnt really dive into how i want to handle all this yet, but probably will be some concept of roles and you can do like
<FromGitter>
<Blacksmoke16> so it could work well if you maybe store the auth "requirements" of a given route, then have a middleware that applies those requirements to see if it should continue or not
<FromGitter>
<j8r> It sounds like this configuration file exists because of a language limitation?
<FromGitter>
<j8r> Or a feature is to modify the file at runtime?
<FromGitter>
<Blacksmoke16> they support yaml, xml, or php code to configure the stuff
<FromGitter>
<j8r> Wow ok
<FromGitter>
<Blacksmoke16> yea, prob could think of a better way to define all this
<FromGitter>
<Blacksmoke16> some DSL or something idk
<postmodern>
wow that is slick. variadic C function mappings use the same syntax as C, just `, ...)`
<FromGitter>
<Blacksmoke16> main point i was trying to make is maybe have 2 separate middleware, one for authenticating the user, and the other for authorization of that user
<FromGitter>
<Blacksmoke16> postmodern: not super familiar with c bindings, but indeed it is :p
<FromGitter>
<j8r> Why not, one issue is to pass the info between them
<FromGitter>
<j8r> *challenge I can say
<FromGitter>
<j8r> Possible with generics
<FromGitter>
<j8r> But it is simpler to put both in one handler/middleware
<postmodern>
still wondering how to handle FILE*. Would likely need to map in fopen as well. FILE appears to be some struct called _IO_FILE under the hood.
<FromGitter>
<Blacksmoke16> > Why not, one issue is to pass the info between them ⏎ ⏎ This is where a DI approach helpful imo, as you can store data in a service and access it in other services, versus putting everything in `HTTP::Server::Context` which you only have access to in controller action and its middleware
<FromGitter>
<Blacksmoke16> :shrug:
<FromGitter>
<j8r> In act no authentication means no authorization – I don't see how we will just need one and not another
<FromGitter>
<Blacksmoke16> like symfony's authentication set is like `$this->tokenStorage->setToken(...);` then other stuff can inject `TokenStorage` to access current token/user
<FromGitter>
<j8r> Oh yes, different means of authentication
<FromGitter>
<Blacksmoke16> yup
<FromGitter>
<Blacksmoke16> also have diff types of tokens, like `Anonymous`, or whatever else you define to allow knowing where a user came from, like `JwtToken` or whatever
<FromGitter>
<j8r> I think, not ideal, but the main authentication handler can call a method of `@next`
<FromGitter>
<j8r> (with the `HTTP::Handler` logix)
<FromGitter>
<j8r> Handling multiple authentication means in only middlewares on a single route is not easy
<FromGitter>
<j8r> But doable
<FromGitter>
<j8r> Ho right, got it
<FromGitter>
<Blacksmoke16> oh?
_whitelogger has joined #crystal-lang
<postmodern>
aka so-called private structs
return0e_ has joined #crystal-lang
confact_ has joined #crystal-lang
badeball has joined #crystal-lang
<FromGitter>
<j8r> Still don't get the diff between handler and middleware
return0e has quit [Read error: Connection reset by peer]
confact has quit [Read error: Connection reset by peer]
davic has quit [Ping timeout: 272 seconds]
dostoyevsky has quit [Ping timeout: 272 seconds]
confact_ is now known as confact
<FromGitter>
<j8r> For me `HTTP::Handler` IS a middleware by essence
<FromGitter>
<Blacksmoke16> i think their synonymous
<FromGitter>
<Blacksmoke16> they're
<FromGitter>
<dscottboggs_gitlab> handlers are a type of middleware? at least as far as I understand
dostoyevsky has joined #crystal-lang
davic has joined #crystal-lang
<FromGitter>
<j8r> More or less
<FromGitter>
<j8r> What I see is middlewares are more powerful
<FromGitter>
<dscottboggs_gitlab> I mean, there are many types of useful middleware, which may or may not intercept a request, of which a "handler" is one
<postmodern>
is there a project like ruby_crystal_codemod, but for converting C headers into crystal C bindings? not looking forward to mapping in all of linux/videodev2.h ...
<FromGitter>
<oren> i want to save some state about my program. where is a typical place and what format is common? i am thinking of ~./config/<app-name>/config.json
<postmodern>
oren, if your storing configuration that the user can mange from inside the app, then ~/.config/ makes sense. There's also ~/.cache/ and ~/.local/share/ if you want to just dump out state before exiting.
<FromGitter>
<oren> yeah. it's a CLI that I want to run and it opens vim for me with some options. one of the options is where is the notes file to open. i want to store it somewhere so next time you run the CLI, it will default to that location.
<FromGitter>
<oren> and is json the usual format for that?
<postmodern>
oren, there's no format restrictions AFAIK. Looking at my own ~/.config/, I can see INI files, XML files, and shell env variable files.
<postmodern>
when dealing with LibC, I notice the Crystal code base doesn't call strerror, but initializes their own Errno messages. Is this the preferred way of handling libc errors?
<FromGitter>
<636f7374> YAML, TOML
<FromGitter>
<636f7374> ENV[HOME]?
<FromGitter>
<636f7374> i18n -> ENV[LANG]
<FromGitter>
<636f7374> IpcSocket -> ENV[TMPDIR]
<FromGitter>
<636f7374> and (similar CRUD).
<FromGitter>
<636f7374> Create, read, update and delete.
<postmodern>
i am kind of weary of TOML due to how it was created ad-hoc and without a formal RFC style ABNF parser spec for other implementations to implement off of. Crystal stdlib seems to support parsing INI, but not generating it.
<FromGitter>
<636f7374> Diesel is the most productive way to interact with databases in Rust because of its safe and composable abstractions over queries.
<FromGitter>
<636f7374> I will try Diesel later. ORM
<FromGitter>
<636f7374> TOML is great in Rust.
<FromGitter>
<oren> is there a repl i can play with to try random things?
<FromGitter>
<636f7374> May not actually.
<FromGitter>
<636f7374> but it's probably like this.
<oprypin>
oren, my favorite is $XDG_CONFIG_HOME (falling back to ~/.config) / yourprogramrc, in INI format
<oprypin>
don't expect a REPL, just try things in a file
ur5us has joined #crystal-lang
Nicolab has joined #crystal-lang
postmodern has quit [Quit: Leaving]
ur5us has quit [Ping timeout: 248 seconds]
<FromGitter>
<636f7374> @TheOnlyArtz Since you include `http/client`, why don't you use it?
<FromGitter>
<636f7374> Or why don't you use `HTTP::Request.to_io`?
<FromGitter>
<636f7374> `! = nil`, `.nil?`, `unless` Which do you think is better.
<FromGitter>
<636f7374> Crystal `STDOUT` doesn't seem to work on Heroku?
<FromGitter>
<636f7374> Still need `flush`? I will check again later.
<FromGitter>
<636f7374> Cloudflare AnyCast IP should improve Heroku network performance (SOCKS5 over WebSocket), but damn I didn't buy a domain name, `dot.tk` is no longer available for free, It seems I need to buy a domain name for $1.
Nicolab has quit [Quit: Leaving.]
darkstardevx has quit [Ping timeout: 272 seconds]
darkstardevx has joined #crystal-lang
tangorri has quit [Remote host closed the connection]
<oprypin>
636f7374, `if a != nil` can be written as `if a`.
<oprypin>
*also* i recently had a thought that i never ever want to use `unless` and `until`
darkstardevx has quit [Ping timeout: 240 seconds]
darkstardevx has joined #crystal-lang
<FromGitter>
<636f7374> @oprypin I know these, just a rhetorical question.
<FromGitter>
<636f7374> @oprypin `unless` and `until` will make the expression clearer, `unless` can solve the nil problem in the first place.
postmodern has joined #crystal-lang
<FromGitter>
<TheOnlyArtz> @636f7374 I want to use the socket library and not the http/client
alexherbo2 has joined #crystal-lang
<FromGitter>
<636f7374> @TheOnlyArtz why don't you use `HTTP::Request.to_io`?
<postmodern>
can you define methods in C lib structs, or are they only intended to be templates for the C struct's memory layout?
<postmodern>
also i take it anonymous unions within structs is not currently possible with crystal's C lib syntax?
<postmodern>
also odd that libs are not modules, and cannot be included into the namespace of a module. would be handy
<oprypin>
postmodern, no, just how you can't define them in C structs.
<oprypin>
postmodern, anonymous unions have to be non-anonymous
<oprypin>
postmodern, `lib` are a low-level wrapper and aren't to be exposed directly
<postmodern>
oprypin, grumble. i was hoping to define the union as FooUnion, then add methods so s.bar maps to s.foo_union.bar
<postmodern>
guess i should submit an issue and start a discussion
<postmodern>
i do appreciate that the crystal-lang issues i have found via google always include lengthy and thoughtful discussion
<sorcus>
And `.extname` about `~16` slower than `ends_with?` if extensions with dot too. :-D
<oprypin>
postmodern, if you're gonna start an issue about making `lib` more convenient, keep in mind that it's a non-goal
<postmodern>
oprypin, what is the criteria for something becoming a goal?
alexherbo23 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 272 seconds]
alexherbo23 is now known as alexherbo2
<FromGitter>
<asterite> sorcus it's because `extname` allocates a string, but `ends_with?` doesn't. Allocating vs. not allocating always make a huge difference
<sorcus>
asterite: Yeah, i understand this, but it still looks cool :-D
FromGitter has quit [Read error: Connection reset by peer]
FromGitter has joined #crystal-lang
sagax has quit [Ping timeout: 240 seconds]
return0e has joined #crystal-lang
return0e_ has quit [Ping timeout: 240 seconds]
alexherbo22 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo22 is now known as alexherbo2
sagax has joined #crystal-lang
masterdonx2 has joined #crystal-lang
MasterdonX has quit [Ping timeout: 272 seconds]
<sorcus>
Who want to criticize my script? :-D :-D :-D
Xeago has quit [Read error: Connection reset by peer]
Xeago has joined #crystal-lang
<sorcus>
dscottboggs_gitlab: Why not use absolute? - don't really know. There is any benefits for `absolute` instead `relative`?
<FromGitter>
<dscottboggs_gitlab> idk, not using ../?
<FromGitter>
<dscottboggs_gitlab> I don't see the issue really tbh
<sorcus>
dscottboggs_gitlab: Maybe... But what if website directory renamed? With absolute path symlinks could be broken.
<FromGitter>
<dscottboggs_gitlab> Oh, no, you're totally right
<sorcus>
dscottboggs_gitlab: But yes, they can be recreated... Haha...
<FromGitter>
<dscottboggs_gitlab> this is one case where using ../ makes perfect sense
postmodern has quit [Quit: Leaving]
<FromGitter>
<dscottboggs_gitlab> you *could* put it in a path and do like `pathstr.count('/').times { path = ".." / path }` but I don't think it matters for a script
<sorcus>
Main idea is to not hosted website in public. Instead use `src` (/home/web.apps/example.com/www/src) for sources and `public` (/home/web.apps/example.com/www/public) for symlinks.
<sorcus>
In `www` directory place `data.yaml` file with paths / directories, which should be symlinked from src to public.
<sorcus>
This useful for me, because sometimes in `src` can be placed some files, that should not be visible for anyone.
<sorcus>
And if someone upload bad file (like backdoor.php) inside upload directory (for example), this file can't be called, because `public/upload` doesn't have symlink to this file.
<sorcus>
It's controlled by `allowed_extension`.
<sorcus>
dscottboggs_gitlab: Hmmm... Only if it can be more faster than current. :-D
<FromGitter>
<dscottboggs_gitlab> Nah, the point of Path is to make it work cross-platform. I don't even know if the .. path works on windows
<sorcus>
dscottboggs_gitlab: "linker data.yaml 0.00s user 0.00s system 97% cpu 0.004 total" - this is repeated call for 640 directories in cache.
<FromGitter>
<dscottboggs_gitlab> nice
<sorcus>
dscottboggs_gitlab: But i don't use Windows on servers :-D :-D :-D
<sorcus>
dscottboggs_gitlab: But you are right.
<FromGitter>
<dscottboggs_gitlab> Yeah, and why would you? Haha. So using a string is fine IMO
<sorcus>
tenebrousedge: Yeah, with multiple slash the can be something wrong... But currently i control all `data.yaml` files and i don't think i can have a trouble with this.
<sorcus>
tenebrousedge: Maybe i need to check all paths from `data.yaml` for leading slash and if any has, raise exception.
<FromGitter>
<tenebrousedge> that seems reasonable
<FromGitter>
<tenebrousedge> and you could also use `squeeze("/")` to compress multiple slashes
<sorcus>
And for directories, where files or directories can be created at any time, i use systemd unit `.path`. If any changes in `src` directory, linker will be called.
<sorcus>
tenebrousedge: Or cut slashes from the beginning...
<FromGitter>
<tenebrousedge> it's probably also worth aliasing `Array(String)` to `PathArray`
<FromGitter>
<tenebrousedge> or `Paths`
<FromGitter>
<dscottboggs_gitlab> > Why not create a tutorial ⏎ ⏎ decided this would be easier haha. I was kinda hoping that since each example is kinda its own thing that other community members would also contribute to the examples
tangorri has joined #crystal-lang
<sorcus>
tenebrousedge: "early returns not necessary" - hmmm. But why? Some kind of optimisation?
<FromGitter>
<tenebrousedge> there are methods in the standard library that do what you want, without the early return
<sorcus>
dscottboggs_gitlab: I think i've seen crystal examples somewhere before...
<sorcus>
tenebrousedge: Ah, yours truth. I should be more attentive.
alexherbo27 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 272 seconds]
alexherbo2 has joined #crystal-lang
alexherbo27 has quit [Ping timeout: 260 seconds]
tangorri has quit [Remote host closed the connection]
<FromGitter>
<j8r> is it common to have nested http route controllers?
<FromGitter>
<Blacksmoke16> Example?
<FromGitter>
<j8r> for instance, a controller for all routers related to users, and inside one for its settings, a other for its posts, an other fur its images, etc
ht_ has joined #crystal-lang
<FromGitter>
<Blacksmoke16> I doubt it. No reason you can't define all your routes in one controller
<FromGitter>
<Blacksmoke16> But if you wanted to separate them they would most likely be individual classes
<FromGitter>
<j8r> its the purpose of controllers: group a logical set of routes
_ht has quit [Ping timeout: 272 seconds]
ht_ is now known as _ht
<FromGitter>
<Blacksmoke16> `AppController`
<FromGitter>
<Blacksmoke16> Has all the routes for my app :p
<FromGitter>
<j8r> sure we can have everything in a single controller, meh
<FromGitter>
<j8r> why not
<FromGitter>
<tenebrousedge> yes, you can have nested controllers, and it's common
<FromGitter>
<j8r> Great :)
<FromGitter>
<tenebrousedge> usually it's more of a routing level concern
<FromGitter>
<tenebrousedge> I should mention, that there's also a standard mapping of `GET` => Controller#index, DELETE => Controller#delete
<FromGitter>
<tenebrousedge> but that these are defaults and can be changed
<FromGitter>
<j8r> so, `R` is the result type of route actions.
<FromGitter>
<tenebrousedge> what if you want `/users/images` and `images` to point to the same controller action?
<FromGitter>
<Blacksmoke16> > so, `R` is the result type of route actions. ⏎ ⏎ result type meaning the return type of each method?
<FromGitter>
<tenebrousedge> what if certain path elements should go to one controller over another?
<FromGitter>
<j8r> yep @Blacksmoke16
<FromGitter>
<Blacksmoke16> so `get` and `post` would both have to return the same type?
<FromGitter>
<j8r> @tenebrousedge they can both call the same method
<FromGitter>
<tenebrousedge> the same controller method?
<FromGitter>
<j8r> @Blacksmoke16 yes
<FromGitter>
<Blacksmoke16> that doesnt seem ideal tho?
<FromGitter>
<tenebrousedge> and does this handle parameterized path segments?
<FromGitter>
<j8r> yes @tenebrousedge , and they are casted
<FromGitter>
<Blacksmoke16> like `GET /user/1` would return `User` while `GET /user` would return `Array(User)`
<FromGitter>
<j8r> agree
<FromGitter>
<j8r> this is due to the handler sending the response
<FromGitter>
<j8r> I will try to do a `forall T`, it may work
<FromGitter>
<Blacksmoke16> or union together each method's return type?
<FromGitter>
<Blacksmoke16> idk the implementation
<FromGitter>
<j8r> ho no, in fact that's the Proc
<FromGitter>
<j8r> the Proc insides the Nodes must be typed
<FromGitter>
<Blacksmoke16> right, should each method not get its own node?
<FromGitter>
<j8r> yes you can have `Controller(String | Nil | User)`
<FromGitter>
<j8r> it has its own node, but inside a tree of nodes
<FromGitter>
<Blacksmoke16> gotcha
<FromGitter>
<j8r> can be mitigated by unions, or the routes writing to the context IO, or an object wrapper
<FromGitter>
<j8r> btw thanks,
<FromGitter>
<Blacksmoke16> np
<FromGitter>
<j8r> I realized it's possible to merge 2 trees, one of `T` and the other of `R` ⏎ A new hash will have to be created - not a big deal Crystal is fast :) ⏎ More importantly, it is possible to change the type of an ivar