Kcgi – minimal CGI and FastCGI library for C/C++
kristaps.bsd.lv
kristaps.bsd.lv
Refer to the newest Talk Python podcast where a core CPython developer was told that Python is memory safe and his response was “is it?”.
At some point we need to be more sophisticated about this, our hardware is fundamentally unsafe, anything we build on it is fundamentally unsafe and there are degrees to which things are better or worse and that’s it. All that matters is the love, rigour and care you put into your work.
Proceed as you wish, a backend in C is valid a backend in LISP is valid.
* Most sites/projects are internal to an organization
* Most public facing websites/apps/projects won't be successful
It can get you most of the Smalltalk (Python/Ruby) conveniences with most of C's speed. In fact, if you do it really well you can leverage them together to get better than both. Simultaenously.
Doesn't mean that people don't manage to wield it in such a way as to get all the convenience of C combined with the performance of Python/Ruby. Which always baffles me. You .... did .... WAT?
To me the Right Thing™ here always seemed the obvious and simple thing to do, as in: just don't spend extra effort to mess it up and you'll be fine. YMMV.
Plug: my book gives fairly detailed instructions on how to achieve the positive combination. [1]
Other plug: Making it easier to get this right is the 2nd of the four stages of Objective-Smalltalk. [2][3]
[1] https://www.amazon.com/Cocoa-Objective-C-Performance-Tuning-...
[2] https://blog.metaobject.com/2019/12/the-4-stages-of-objectiv...
On a very-few/very-skilled developer project, this might work. But on projects with large or changing teams, that downside bites hard.
Fortunately, the run-time does this for you: it ignores messages to nil.
And the framework provides container objects for "bags of bytes": NSData.
So it is actually surprisingly hard to dereference a null pointer, and surprisingly easy to avoid mechanically without being perfect.
Just make sure that you delegate any manipulation of raw data to methods of the object holding the data.
https://blog.metaobject.com/2014/05/the-spidy-subset-or-avoi...
While it is certainly possible to circumvent this if you put your mind to it, it is remarkably safe in practice.
Just like in C++, while there are high level abstractions that avoid traditional C memory corruption issues, there are always those that insist in sticking to the C subset.
As I wrote, you wrap those in an Objective-C container that manages that pointer, and delegate the C access to that container.
So not:
c_pointer = [container getPointer]
<munge on pointer>
But rather: [container doSomeMungingOnYourCData];
Which is, of course, how you should be doing things in OO style anyhow. So that works out just fine.But yes, some people do insist on doing things the hard, slow, nasty way. They get punished.
This doesn't mean C is an equally valid choice for a web backend as Common Lisp when you care about development speed and don't want to get pwned. It's justified(ish) if you are Fossil SCM but much less so if you are a random website. When you need high performance, it's more justified, especially if it's 2006. When you can afford to use bindings for your C libraries, it's less. Etc.
To shift your perspective, replace C with x86-64 assembly. AsmBB (https://board.asm32.info/) is undeniably a cool thing. Is it valid to develop an e-commerce site the same way?
There is a general pattern of "there are degrees, so basically anything goes". It's important to recognize it and resist its siren song.
> The Sophisticate: “The world isn’t black and white. No one does pure good or pure bad. It’s all gray. Therefore, no one is better than anyone else.”
> The Zetet: “Knowing only gray, you conclude that all grays are the same shade. You mock the simplicity of the two-color view, yet you replace it with a one-color view . . .”
> —Marc Stiegler, David’s Sling
Sure why not. If it can process my transaction cleanly and securely why not?
It isn't a question of "could" but how likely you are to get good outcomes.
The risk of bugs goes up when lots of people (with different timelines/skill levels/expectations) are working on an enterprise codebase. Ergo, the risk of "entire backend vanished" crashes goes up over time. A huge benefit of HLLs is that they have a vastly reduced risk of whole-program-aborting bugs--even Erlang, with it's "let it crash" philosophy, is referring to letting the boundary of affected code within a larger program crash, not aborting every transaction/reinitializing all resources and restarting from scratch.
Things like CGI mitigate this a little bit by containing the blast radius to one request's handler (at a pretty severe complexity/performance/compute cost to things like shared connection pools/file handles/startup time), but they don't solve it. The same is true for things like autorestart services/orchestrators.
Sure, you can decline to abort in the event of a segfault, but that's .... ballsy, shall we say.
I say fck u to them :mid-finger: emoji.
All hail TIMTOWTDI! :)
Most of them were terrible. Many were insecure. Nearly all were written in total obfuscation, because who wrote Perl so other people could read it?
It was terrible.
It was glorious.
(Both) :)
Once I ditched the library idea and just coded to the spec things went much nicer lol it turned out to be a relatively normal socket coding project. Just hobby code tho.
Look at https://www.http-arena.com/. For raw throughput on keep-alive requests, low-level languages are going to win without a question. But once you put database roundtrip into the mix, the distance gets much smaller.
And I'm saying this as an author of another HTTP server in a low-level language.
Note that PHP and Perl also had enough C code, and Apache/IIS plugins, with enough C and C++ extensions.
Now all those "who cares scripting languages" are getting JIT compilers, or being rewritten into Go and Rust.
Things were shifting to Go gradually as I left though.