[HN Gopher] The beauty of CGI and simple design
       ___________________________________________________________________
        
       The beauty of CGI and simple design
        
       Author : susam
       Score  : 282 points
       Date   : 2023-01-07 09:38 UTC (13 hours ago)
        
 (HTM) web link (rubenerd.com)
 (TXT) w3m dump (rubenerd.com)
        
       | calltrak wrote:
       | [dead]
        
       | tasn wrote:
       | I always felt that the best software should be designed like an
       | onion. Very easy to get started (no need to peel too much to get
       | to the outer layer), but there should always be the possibility
       | to go deeper and peel more layers. Easy to get started is not
       | great (as a general purpose tool) if there is no decent upgrade
       | path.
       | 
       | What replaced CGI scripts is slightly more complex, but also more
       | naturally grows to other use-cases.
       | 
       | In short: I personally don't miss CGI. :)
        
         | VWWHFSfQ wrote:
         | CGI was also a security nightmare full of footguns. Not that
         | modern software isn't, but CGI was especially bad.
         | 
         | - Take untrusted input and pass it directly to shell scripts on
         | your filesystem. What could go wrong?
         | 
         | - Executables in cgi-bin were nearly always included in your
         | document root on shared hosting servers.
         | 
         | - File drops and web shells were rampant
         | 
         | - A trivial misconfiguration (not setting +x?) could result in
         | the web server just serving up the source code of your scripts
         | directly to the client. There's your database credentials hard-
         | coded right there at the top of your file now exposed for all
         | to see.
         | 
         | - You had to pay very close attention to resource limits on the
         | server itself to prevent malicious things like fork-bombs
         | 
         | - Apache was a nightmare to configure securely for CGI
         | 
         | The list goes on. I don't miss it at all.
        
           | kefka_p wrote:
           | You didn't have to hard-code database credentials into your
           | app, though. That's a design flaw, not a requirement of CGI.
           | 
           | Who passes non-sanitized or otherwise untrusted input to
           | executables, any more than is necessary? Why do you (seem to)
           | believe modern approaches to dynamism are immune when the
           | bulk of user input still comes from HTML forms? How do modern
           | web applications avoid input from untrusted sources?
           | 
           | Same applies to the directory layout of servers they were
           | hosted on. That's more a lack of server admin competence than
           | a fault of CGI. Was far easier than configuring Tomcat to
           | safely host Java web apps. I recall it being far easier to
           | configure than WebObjects, PHP, Rails, etc.
           | 
           | CGI programs were far from the only form of web application
           | effected by local security implementations. In my experience
           | common gateway interface applications consist of fewer files
           | than something written against Spring, WebObjects, or 99% of
           | server side web app frameworks. Fewer files means less system
           | configuration and less attack surface, no?
           | 
           | As to forking leading to DDOS, that was something that could
           | happen to any forking server, which was pretty much all
           | servers when CGI first came into existence. FastCGI helped
           | address that issue.
        
       | freyfogle wrote:
       | You will be pleased to know CGI.pm v4.55 was just released last
       | week https://metacpan.org/dist/CGI/view/lib/CGI.pod
       | 
       | It's still there, you can still use it. Works great.
        
       | HeckFeck wrote:
       | Recently I built a CGI script using Perl for my own pleasure. It
       | was quite easy indeed, just a case of importing Template Toolkit,
       | GD and CGI.pm then printing the result to stdout. Since I'm only
       | using CGI.pm to send the HTTP header it isn't really necessary.
       | 
       | The result is here: https://www.thran.uk/cgi-win/fleg.pl
       | 
       | It is a flag generator affectionately titled flegger.
        
         | nicky0 wrote:
         | You can't claim us we live here
        
           | HeckFeck wrote:
           | Sorry my friend but you are now all loyal subjects of the
           | Great Lordship of Gurgdill.
        
           | RedShift1 wrote:
           | Do you have an army?
        
           | mrweasel wrote:
           | Do you have a flag?
        
         | foldr wrote:
         | Emirates probably shouldn't have a big cross in the middle of
         | their flag :D But this was fun. My favorite was the "Socialist
         | Caliphate of Flugshire".
        
         | ilyt wrote:
         | Last time I used Perl for anything web it was via
         | https://mojolicious.org/
         | 
         | It even does event-based and websockets
        
       | habibur wrote:
       | CGI is slow [ spawns an OS process for every request ]. But FCGI
       | is as fast as any other solution, like compiling the whole app in
       | a single binary and running it as a HTTP server.
        
         | hawski wrote:
         | I did a simple benchmark to test how fast forking is:
         | https://gist.github.com/hadrianw/ad07a76f338f09565703ae6ea35...
         | 
         | It tested in a loop fork/exec and vfork/exec for a dynamic
         | binary and for a static binary with musl.
         | 
         | On an Intel Core i5 6600k:
         | 
         | regular:
         | 
         | fork 13179 ms / 100000 = 131 us, 7587 per sec
         | 
         | vfork 14423 ms / 100000 = 144 us, 6933 per sec
         | 
         | static:
         | 
         | fork 3173 ms / 100000 = 31 us, 31515 per sec
         | 
         | vfork 3833 ms / 100000 = 38 us, 26089 per sec
        
           | thehappypm wrote:
           | Wow, I read this as ms at first, microseconds is really
           | phenomenal
        
           | _flux wrote:
           | Yeah, I don't think the speed performance of FCGI vs CGI is
           | really about spawning in 2023: the benefit lies in the fact
           | that the app can keep state and resources between requests.
           | In particular, it can maintain a database connection all the
           | time (with a retry logic for the case when it gets
           | disconnected).
           | 
           | However, perhaps 15+ years ago I converted an application to
           | an Apache module from a cgi-bin binary and the performance
           | benefit was immense in an embedded Linux device. We certainly
           | were not talking even about tens requests per second in the
           | CGI version.
        
             | 10000truths wrote:
             | > the benefit lies in the fact that the app can keep state
             | and resources between requests.
             | 
             | You can share state between processes using temporary
             | files/shared memory. Like CGI itself, it doesn't scale as
             | well, but it's not even a blip on resource usage unless
             | you're dealing with thousands of requests per second.
             | 
             | > In particular, it can maintain a database connection all
             | the time (with a retry logic for the case when it gets
             | disconnected).
             | 
             | You can run a daemon that performs the connection pooling
             | for you, and have each request connect to the daemon
             | instead.
        
               | Kwpolska wrote:
               | Temporary files/shared memory won't solve the cost of
               | starting up a Python interpreter or a JVM or whatever and
               | importing all your code with its dependencies. As for the
               | connection pooling daemon, you still need to connect to
               | it. It might be faster than talking to the database
               | directly on a different server, but no new connection
               | still beats new local connection.
        
               | 10000truths wrote:
               | > Temporary files/shared memory won't solve the cost of
               | starting up a Python interpreter or a JVM or whatever and
               | importing all your code with its dependencies.
               | 
               | This is true, CGI is sensitive to startup latency. It can
               | be addressed with pre-forking, but doing so bears the
               | consequence of increased memory usage at idle workloads.
               | 
               | > As for the connection pooling daemon, you still need to
               | connect to it. It might be faster than talking to the
               | database directly on a different server, but no new
               | connection still beats new local connection.
               | 
               | It's a nothingburger. A connection pool's bottleneck is
               | in the TCP connection to the database. A UNIX socket has
               | orders of magnitude less latency (a couple ms) and
               | supports orders of magnitude more throughput (a few
               | GBs/sec). Compared to spawning new processes running
               | interpreters, it's noise.
        
               | naniwaduni wrote:
               | Some context: in 2017, I found by informal testing that I
               | could run (just on a dev laptop) about about 180 lua no-
               | op programs per second, 140 perl5, 35 py2, 30 py3, 15
               | node, 12 ruby; /usr/bin/true, as a benchmark, a bit over
               | 500 Hz.
               | 
               | Doesn't necessarily extrapolate back another 20 years,
               | but perhaps sheds some light on how "slow" CGI would've
               | been.
        
           | 10000truths wrote:
           | I would also try benchmarking the new io_uring_spawn
           | interface, which is said to be significantly faster than the
           | traditional fork+exec way of spawning processes.
           | 
           | https://lwn.net/Articles/908268/
        
             | gavinray wrote:
             | This
        
             | hawski wrote:
             | As far as I can see it is not yet done. It is not in the
             | current mainline. When it will go in I would certainly like
             | to revisit.
        
         | aliqot wrote:
         | > like compiling the whole app in a single binary and running
         | it as a HTTP server.
         | 
         | Not so uncommon these days tbh
        
         | ilyt wrote:
         | Probably still less slowdown than some heavy framework
        
         | sgbeal wrote:
         | > CGI is slow ....
         | 
         | CGI is _computationally_ slow, but in practice it's faster than
         | it needs to be for most sites. Some examples of CGI-powered
         | sites i'm aware of include:
         | 
         | - https://sqlite.org/forum
         | 
         | - https://sqlite.org/wasm (same domain, different sub-site)
         | 
         | - https://fossil-scm.org/home
         | 
         | - https://fossil-scm.org/forum (same domain, separate sub-site)
         | 
         | - https://fossil.wanderinghorse.net
         | 
         | All CGI, all the time, and _plenty_ performant for the purpose.
        
           | yakubin wrote:
           | Add to it https://git.kernel.org/
        
           | WJW wrote:
           | Many people confuse "X is slower than Y" with "X is slow in
           | some absolute sense". Starting a new process takes well under
           | a millisecond on most modern machines, so that would be
           | completely lost in the latency of most web requests. The real
           | benefits of persistent processes are in getting to reuse
           | database connections and the like.
        
             | ptx wrote:
             | > _Starting a new process takes well under a millisecond on
             | most modern machines_
             | 
             | But if that process is Python or Java it's going to be tens
             | to hundreds of milliseconds before it's ready to serve the
             | request.
        
       | samsquire wrote:
       | I appreciate this post, thank you for writing it.
       | 
       | There is something elegant about PHP and CGI. Just put file
       | somewhere and query it by browser.
       | 
       | How would you fix the design of PHP and CGI to be scalable?
       | 
       | I wrote a userspace scheduler that multiplexes lightweight
       | threads onto kernel threads. It is a 1:M:N scheduler since there
       | is a scheduler thread that preempts other thread's loops. I think
       | I can write a runtime that uses files. I also have an
       | epollserver. If I merge them together and write a HTTP router,
       | then in theory you could have a modern server runner that can
       | execute in-process with threads.
       | 
       | I would need to think how to execute Ruby, Lua, Javascript code
       | in a thread. Perhaps that's similar to NodeJs but it's a file
       | runner rather than a server application.
       | 
       | https://github.com/samsquire/preemptible-thread
       | https://github.com/samsquire/epoll-server
        
         | tyingq wrote:
         | >How would you fix the design of PHP and CGI to be scalable?
         | 
         | A lot of sites get pretty far with just FastCGI. If that's not
         | enough, then a user-space/mmap cache like Apcu. Then, if that's
         | not enough, horizontal scaling and Redis or similar.
        
       | BlueTemplar wrote:
       | I found CGI to combine quite well with bleeding edge JavaScript 7
       | : async / await (compared to JS6 promises that left me confused
       | as a JavaScript newbie).
       | 
       | I am more interested to know in which situations it's a bad idea
       | to use CGI ?
        
         | diamondap wrote:
         | In the old days (1990s), it was a "bad idea" to use CGI for
         | heavily trafficked sites because there was a lot of system
         | overhead involved in spawning a new CGI process for every
         | request, firing up an interpreter (usually Perl), parsing the
         | code, then executing it.
         | 
         | As one of the previous comments mentions, operating systems do
         | a better job of caching now, so there's less overhead there.
         | Fast CGI also gets rid of that problem by running your CGI
         | script as a single persistent process.
         | 
         | CGI may not be the best solution for really huge applications
         | that have hundreds of routes or very complex business logic.
         | 
         | That said, it's still incredibly useful. I use it on some
         | personal sites, and it's nice to know that I can drop it into
         | any new site without having to worry about dependencies and
         | without having to do much configuration. It's simple and it
         | works. Those are two big pluses in a world where things have
         | gotten so complex.
        
       | iamben wrote:
       | I started writing my dissertation project in Perl CGI back in
       | like 2001 or whatever it was. I moved to PHP pretty quickly when
       | I realised I could do the same things in 5 lines that took 70 in
       | Perl. I'd been making websites for about 6 years at that point
       | and PHP just absolutely changed my life. It was, arguably,
       | exactly like this post talks about CGI - put some script in a
       | file, FTP to your host and you're good to go. Web development was
       | simple and exciting - you could get a long way very quickly.
       | 
       | I was talking to a friend the other day who wants to learn some
       | web dev for _fun_ - he had no clue where to start because there
       | 's now SO much, so many 'best practice' posts, so much 'you must
       | learn like this'. I know the world changes (and often for the
       | better), but it was a magic time when you could get so far so
       | quickly.
       | 
       | As an aside, it's why I have huge amounts of respect for people
       | like Pieter Levels and his 'just get it done' approach to
       | building things.
        
         | giovannibonetti wrote:
         | Perhaps we should start making tutorials that follow that idea
         | from PHP: start with HTML, add an extension (e.g. .eex, .erb)
         | and make it dynamic. This would lower the barrier for
         | beginners.
         | 
         | By the way, the best HTML tutorial I found so far is Scrimba.
         | The idea of having interactive videos where you can pause and
         | edit the code is amazing.
        
           | iamben wrote:
           | You're right. And I'm sure they exist - just hard to find in
           | a sea of "you'll get nowhere without knowing React" (or
           | whatever) tutorials.
           | 
           | Equally, half the magic is ability to see it online quickly.
           | Cheap, basically set up free web hosting and FTP made that
           | very easy.
        
         | alerighi wrote:
         | To me PHP is still a great tool to do these sort of stuff. Not
         | to do a whole application, it was not what it was designed for,
         | but for simple stuff it's great!
         | 
         | And it's improved a lot PHP, nowadays it's not that bad
         | language...
        
           | pocketsand wrote:
           | For web apps, PHP is still a great candidate. Check out
           | Laravel or Symfony. It's not like the old days of PHP files
           | mixed with procedural code. Although those were good days :)
        
         | endemic wrote:
         | I _really_ tried to learn Perl back in the 90s, but PHP was
         | what "unlocked" server-side scripting for me.
        
       | samwillis wrote:
       | CGI was abandoned due to performance problems, but it is
       | surprising scalable on modern OSs, the kernel does a good job of
       | caching the code so it's not really a full round trip to the file
       | system and cold start on each request. Obviously you still have
       | the overhead of an interpreter for many languages, but they also
       | tend to do a fairly good job of caching their byte code. I
       | absolutely wouldn't recommend it for new systems, but for a quick
       | and dirty script it's fine.
       | 
       | The minute you want to do url routing and have middleware, a
       | persistent process makes everything much simpler and keeps
       | everything in one place. I much prefer routing inside a framework
       | than using Mod_Rewrite.
       | 
       | Edit: This article covers what I was thinking of:
       | 
       | "Myths About CGI Scalability"
       | 
       | http://z505.com/cgi-bin/qkcont/qkcont.cgi?p=Myths%20About%20...
       | 
       | Previously discussed:
       | 
       | https://news.ycombinator.com/item?id=32699395
        
         | scotty79 wrote:
         | > a persistent process makes everything much simpler ...
         | 
         | I started with PHP and never trusted persistent processes for
         | anything.
         | 
         | What if your persistent process hangs or crashes for whatever
         | reason?
         | 
         | Is your whole site down then, not just the part with the bug?
         | 
         | The only site I ever made in persistent process paradigm was in
         | ASP.NET and it didn't cause too many problems but it was more
         | of an app, not website, with limited number of logged in users
         | and pretty much no anonymous/guest part.
        
           | ilyt wrote:
           | > I started with PHP and never trusted persistent processes
           | for anything.
           | 
           | Well it's (maybe was, it _did_ get a bit nicer over years but
           | old shit code is still there) terrible language so no wonder
           | you have no trust.
           | 
           | > What if your persistent process hangs or crashes for
           | whatever reason?
           | 
           | depend on language. For example in Go (in most frameworks at
           | least) panic() in goroutine handling request will just...
           | nuke that request and nothing else. Sure, memory leaks can be
           | issue if the code is terrible but _essentially_ restarting
           | app after every request is just shitty workaround for shoddy
           | code.
           | 
           | That's how most other handle code. Other, that do multi-core
           | processing badly like Ruby, just spawn multiples of server so
           | it isn't really that different from PHP model, you get
           | "supervisor" that spawns few processes of app and feed them
           | requests, if one dies it just gets restarted.
        
           | wizzwizz4 wrote:
           | > _What if your persistent process hangs or crashes for
           | whatever reason?_
           | 
           | You've got the same problem with your web server, and your
           | operating system kernel. Simply write a program that _can 't_
           | hang or crash - at least, not due to an application bug. It
           | takes attention to detail, but this is a lot easier than
           | writing a program that always behaves correctly; if you limit
           | the syscalls you make, use timeouts appropriately, and don't
           | segfault, it's often achievable.
        
             | scotty79 wrote:
             | I don't think any mainstream framework in any mainstream
             | language has these kinds of precautions.
             | 
             | Rails? Django? Express? .NET? Do they kill long running
             | requests so they don't affect whole application?
             | 
             | Can the application still mostly work despite syntax error
             | in one of the files?
             | 
             | Another thing is level of trust. I trust Linux kernel, I
             | trust apache webserver. But some webserver written in
             | scripting language few years ago? Not so much.
        
               | alerighi wrote:
               | Well try in a nodejs server to put a `while(true);` in a
               | request handler. Do you know the answer? The whole
               | process blocks, since nodejs is single process.
               | 
               | I trust more the code that I wrote than the code written
               | from others... not because I'm better than others, but
               | because I know what it does, and I know how to fix it if
               | it breaks.
        
               | scotty79 wrote:
               | It still wouldn't hurt if the framework just killed it
               | after 3 seconds with timeout message.
        
               | Semaphor wrote:
               | > .NET? Do they kill long running requests so they don't
               | affect whole application?
               | 
               | Not sure about the built-in .net server, but IIS does
               | exactly that. It supports timeout and error/time based
               | restarts for the persistent process.
        
         | geenat wrote:
         | mod_rewrite hasn't been necessary since nginx.
         | 
         | 2023 - Use single binary caddy. It's like 2 lines of config
         | total to remove the extension from your CGI url's.
        
           | liveoneggs wrote:
           | What does nginx have to do with mod_rewrite?
        
           | qbasic_forever wrote:
           | Caddy doesn't support CGI out of the box. You need to use a
           | module (which requires a custom build of it and the hope the
           | module author continues to maintain it), or you need to run
           | something like fcgiwrap to convert FCGI (what Caddy does
           | support) to CGI (and now you need a process manager to make
           | sure your fcgiwrap and caddy processes are kept running,
           | restarted on failure, etc).
        
           | ptx wrote:
           | nginx hasn't been necessary since mpm_event_module.
        
             | ilyt wrote:
             | apache haven't been necessary since nginx.
        
           | samwillis wrote:
           | Absolutely, and Caddy is brilliant.
           | 
           | My point really was when having url routing, such as
           | ids/slugs in the url, it is much easier to implement in your
           | application code than in the web server configuration. It
           | keeps application code in one place.
        
       | Jabbles wrote:
       | https://en.wikipedia.org/wiki/Common_Gateway_Interface
        
       | reddec wrote:
       | I felt exactly the same as the author. That's why I created
       | https://trusted-cgi.reddec.net/ (currently on the way to v1 and
       | under the heavy refactoring)
        
       | hestefisk wrote:
       | I wrote Perl cgi scripts for a self-serve customer admin
       | interface for an ISP in the early 2000s. As users grew, we
       | started hitting the limits of what 1-2G ram could do. Thank
       | goodness for mod_perl and HTML::Mason, which could REALLY speed
       | up performance. I remain a huge fan of Perl these days.
        
         | papito wrote:
         | Still remember reloading a page and seeing _another_ customer
         | 's forms.
         | 
         | mod_perl teaches you quickly about state.
        
       | uhtred wrote:
       | The only side project I've managed to complete and put live in
       | the last 10 years used Perl and CGI. That was last year. It was
       | actually fun!
        
       | bombela wrote:
       | > Personal projects remain unfinished or abandoned because I've
       | wanted to do things the "right" way. So I start building it the
       | "right" way with complicated tools and processes, then raise my
       | hands and think it's all too much for what I want to do. It puts
       | all sorts of things out of reach.
       | 
       | So true it hurts.
        
         | satvikpendem wrote:
         | I was feeling the same way recently, and I made an HN post
         | about trying to solve this problem of perfectionism.
         | 
         | "Tell HN: I was tired of being a perfectionist so I built an
         | app within 24 hours"
         | 
         | https://news.ycombinator.com/item?id=33303269
        
         | ZephyrBlu wrote:
         | Yeah, the primary goal of any side project should be doing
         | whatever maximizes the chance you continue working on it.
         | 
         | The lesson from survivorship bias is to optimize for survival
         | :).
        
           | [deleted]
        
           | marginalia_nu wrote:
           | Yeah, I like the analogy of a march, as a contrast to the
           | sprints typically employed in commercial development. Like my
           | search engine project is 2 years in now, and still not
           | anywhere near "done". Yet it keeps getting better and more
           | capable at a slow but steady pace.
        
         | [deleted]
        
         | notjustanymike wrote:
         | What's funny is this is how Agile works in a functioning
         | organization. You validate the idea first and quick, and only
         | then iterate with new layers of complexity. Building something
         | the "right" way before ever having seen the product live is
         | called waterfall.
        
         | abc3354 wrote:
         | > Nobody should start to undertake a large project. You start
         | with a small trivial project, and you should never expect it to
         | get large. If you do, you'll just overdesign and generally
         | think it is more important than it likely is at that stage. Or
         | worse, you might be scared away by the sheer size of the work
         | you envision. So start small, and think about the details.
         | Don't think about some big picture and fancy design. If it
         | doesn't solve some fairly immediate need, it's almost certainly
         | over-designed. And don't expect people to jump in and help you.
         | That's not how these things work. You need to get something
         | half-way useful first, and then others will say "hey, that
         | almost works for me", and they'll get involved in the project.
         | 
         | A quote from Linus Torvalds someone posted on HN and I saved
         | almost a year ago
        
           | chrisweekly wrote:
           | "A complex system that works is invariably found to have
           | evolved from a simple system that worked. A complex system
           | designed from scratch never works and cannot be patched up to
           | make it work. You have to start over, beginning with a
           | working simple system."
           | 
           | - John Gall
        
             | satvikpendem wrote:
             | This describes biological evolution well too.
             | 
             | However, I wonder how this works for physical things, how
             | does one create a simple version of a train or bridge? Some
             | things have a complexity floor.
        
               | still_grokking wrote:
               | How did the "simpler" physical laws looked before nature
               | arrived at the current ones?
               | 
               | (That's a half serous question, of course.)
        
         | brightball wrote:
         | I feel this. The other day I decided to just use Rails for one
         | of these personal projects that I've been over-engineering for
         | a while and it's making progress.
         | 
         | Completely forgot how fast Rails makes everything. Based on the
         | experience I'm probably going to force myself to just use Rails
         | for any personal stuff now and figure if any of them actually
         | take off I'll rebuild if I need to.
        
           | svnpenn wrote:
           | this is the exact opposite of the point the comment you
           | replied to is making. Rails is not simple. we are talking
           | about SIMPLE, like CGI. Rails is a classic example of a slow
           | bloated framework.
        
             | brightball wrote:
             | Rails makes a lot of very complicated things, very simple.
             | 
             | Doing what I'm trying to do with CGI would be a huge
             | headache by comparison. When I said "how fast rails makes
             | things" I meant from a standpoint of productivity.
        
             | qbasic_forever wrote:
             | Rails will be significantly faster than a CGI script that
             | spawns a whole new process, starts up your script
             | interpreter, etc. with every single web request.
        
           | Ziggy_Zaggy wrote:
           | This. Find a tech (NOT the fotm shenanigans) that will help
           | you get a product up and running. Then you can always go back
           | and swap out parts as needed.
           | 
           | Try not to be influenced by the "omg, that tech is SOOO
           | old!!!" crowd.
        
           | [deleted]
        
         | derefr wrote:
         | The thing that nobody tells junior programmers, but which you
         | really have to pick up from experience, is this:
         | 
         | "The right final architecture" is never achieved by just
         | immediately going out and building that architecture, i.e. by
         | hooking up all the tools required to _support_ that
         | architecture. That 's cargo-culting the architecture.
         | 
         | Facebook's use of Cassandra and CI lint-checks and blue-green
         | deployments is just like military cargo planes' use of radio
         | towers -- they didn't build those _first_ ; they scaled the
         | thing they were _doing_ to the point that these things became
         | _necessary support structures_ , and _then_ they built them.
         | 
         | The "right way" -- the right _process for engineering a
         | solution_ -- has very little to do with up-front architectural
         | design. The  "right way" -- the way that'll be most likely to
         | get you to that "right final architecture" eventually -- is
         | really the _tenable_ way: the iterative approach that allows
         | you to build up your solution while keeping only one change or
         | consideration in your head at a time. Which means that
         | engineering  "the right way" involves _not_ doing all those
         | cargo-cult practices unless /until they become necessary, and
         | even then, only adopting them one at a time. Just like you
         | wouldn't try to make ten different refactorings in a codebase
         | in one patch-set.
         | 
         | Or, to put that another way: YAGNI applies to processes and
         | tools just as much as it does to code. Some projects never
         | exceed 1000 lines. Do those projects need CI cyclomatic-
         | complexity checkers? No.
         | 
         | Only introduce support structures to a project, as the pain of
         | not having them starts to outweigh the pain of adding them.
        
           | CM30 wrote:
           | > Facebook's use of Cassandra and CI lint-checks and blue-
           | green deployments is just like military cargo planes' use of
           | radio towers -- they didn't build those first; they scaled
           | the thing they were doing to the point that these things
           | became necessary support structures, and then they built
           | them.
           | 
           | This is so true. In fact, a lot of the technology choices
           | companies at the scale of Facebook use are only necessary
           | because they're so large/popular, and were added later to
           | stop everything falling over.
           | 
           | Because it's so unlikely your project will ever need to
           | contend with a billion users or whatever, you really
           | shouldn't be designing under the assumption that's likely to
           | happen.
        
         | hit8run wrote:
         | 100%. I finish projects with Rails... Can't say this about
         | things I start in Go with Clean Architecture and a distributed
         | frontend written in SvelteKit etc. pp.
         | 
         | I need to print this out:
         | 
         | "JUST USE RAILS FOR NOW."
        
           | ehnto wrote:
           | Some of the "right" tools are right only in context of a
           | professional team anyway. Especially true when deciding how
           | to organise a project.
           | 
           | If it is just me, for me, I will write it simply and from
           | scratch or use a familiar general purpose framework like
           | rails or laravel. One I have lots of experience with so the
           | project actually gets done, instead of spending all my energy
           | learning another new tool.
        
           | nickjj wrote:
           | > "JUST USE RAILS FOR NOW."
           | 
           | That could also be reduced down to "JUST USE RAILS".
           | 
           | Why not get the best of both worlds where you finish projects
           | AND be happy about it? The "for now" makes you think it's a
           | bad decision and you hacked something together to get it
           | done.
           | 
           | But you can finish, stick with Rails and be insanely
           | successful based on what's important to you (start, finish,
           | maintain, profit, IPO, etc.).
        
             | hit8run wrote:
             | You convinced me: JUST USE RAILS. It's printed out.
        
           | sgt wrote:
           | Or for us Pythonistas, just use Django. Heck, even if it's
           | just a simple REST API (using DRF), I often do it as the
           | project tends to grow.
        
             | satvikpendem wrote:
             | If only there were something similar for Node, or Rust.
        
         | rgrieselhuber wrote:
         | This brings to mind some of Paul Virilio's writings, who
         | discussed this idea of speed (to include not only velocity but
         | also the sensory assault that comes with complexity and speed
         | combined. This has been paraphrased as "speed is a continuation
         | of fear by other means." How many framework decisions are made
         | in this mindset?
        
           | riesenheim wrote:
           | Thanks for this fascinating connection. "History progresses
           | at the speed of its weapons systems."
           | https://en.wikipedia.org/wiki/Paul_Virilio#War_of_movement
        
             | rgrieselhuber wrote:
             | Virilio was a very interesting writer.
        
       | chazeon wrote:
       | If all the tools you need is in the shell, and you don't need to
       | maintain a state, CGI is extremely simple and powerful, all you
       | need to do is to write a shell script.
       | 
       | I found this useful when I create a HTTP service to check a
       | remote service's status over SSH.
        
       | soapdog wrote:
       | I remember CGI very fondly. I'd still use it to this day in my
       | personal projects if it was not for the fact that I'm running
       | vanilla Caddy 2 that comes without support for it.
       | 
       | Now, CGI and FastCGI are cool, but who else here built CGIs for
       | running on Pre-OSX Macs? I remember AppleScript/AppleEvents based
       | CGI. The Web Server would be a GUI program running on the Mac and
       | the CGI would also be one. They'd communicate to one another
       | sending AppleEvents. I once made good money with a system for
       | running school exams with it.
       | 
       | I miss those days a bit.
        
         | kefka_p wrote:
         | I wrote a few CGI applications for Schotton's MacHTTP and the
         | WebStar server on MacOS 7. Back before the days of
         | OpenTransport!
         | 
         | Yes, I'm old.
        
       | roywashere wrote:
       | I find it kind of interesting that people frowned upon CGI
       | because it was not efficient. And yet here we are using lambas on
       | AWS like it's the best invention ever
        
         | [deleted]
        
         | pjmlp wrote:
         | That is why with experience one learns to ignore fashion trends
         | until they eventually either become unavoidable, or fade away
         | from conference talks.
        
           | agumonkey wrote:
           | I wonder what's the best way: try to extract profit from the
           | fads (cynic) or isolate..
        
         | SoapSeller wrote:
         | Doesn't lambdas are more efficient than CGI due to ability to
         | keep the runtime env running (JIT cache and all)?
        
           | saurik wrote:
           | Yeah: AWS Lambda feels a lot more like the things that came
           | after CGI, not CGI.
        
           | speedgoose wrote:
           | Yes it's like FastCGI. But expensive.
        
             | scotty79 wrote:
             | Funny how the word "expensive" when referring to code
             | execution might today mean actual money, not just memory or
             | time.
        
         | squarefoot wrote:
         | No web dev here, but if memory serves, the main concerns about
         | CGI were about safety, not performance or efficiency. If that's
         | the case, I wonder if new more safe languages could make its
         | use viable again.
        
           | mrweasel wrote:
           | One issue was that people configured CGI wrong. You had
           | executable scripts that had free range on the entire
           | filesystem. Ideally you'd need to limit the cgi-scripts to a
           | chroot, but that made it difficult to use Perl, Python and
           | PHP. OpenBSD shipped/ships a chrooted Perl for use with CGI,
           | but other operating systems just left that bit as an exercise
           | to the programmer.
           | 
           | More modern languages like Go or Rust provides a lot of
           | safety and is pretty easy to statically compile, so it's
           | easily chrooted. It would however be weird to do a CGI
           | program in Go, because that language already have a really
           | good build in webserver and more powerful/easily accessible
           | features for interacting with requests compared to what CGI
           | provides.
        
             | sgbeal wrote:
             | > It would however be weird to do a CGI program in Go,
             | because that language already have a really good build in
             | webserver and more powerful/easily accessible features for
             | interacting with requests compared to what CGI provides.
             | 
             | Noting that not everyone has the ability to run standalone
             | servers on their web hoster. Shared hosters generally
             | enable CGIs but cannot support per-user standalone servers,
             | in particular not on common ports like 80 or 443.
        
           | ptx wrote:
           | What safety concerns are you referring to? CGI scripts often
           | had issues with SQL injection and shell command injection,
           | but that was because of badly designed (or poorly used)
           | libraries and unrelated to CGI itself. Or if CGI programs
           | were written in C (as a result of performance concerns) those
           | would of course have the usual memory safety issues of C
           | programs.
        
             | diocles wrote:
             | (Not the parent but) one cool CGI-specific problem that
             | always comes to mind is HTTPoxy:
             | 
             | https://www.ionos.co.uk/digitalguide/server/configuration/h
             | t...
             | 
             | You could write this off as a library implementation
             | problem, but it comes about because of unfortunate mapping
             | of HTTP parameters to well-known environment variables in
             | CGI, and has tripped up multiple library authors.
        
             | ilyt wrote:
             | Usually poor ops hygiene, same really as PHP problems:
             | 
             | * Code runs as web server user * Code is deployed as web
             | server user, because web monkey doesn't understand unix
             | permission (or alternatively chmod 777 everything for same
             | effect) * Code gets hacked, attacker can modify _any_ file
             | so they just leave backdoor in code
             | 
             | If you deploy code as different user attacker can still of
             | course steal all the data but at the very least they can't
             | modify the code that is running.
             | 
             | On top of that, a lot of poor security practices when it
             | comes to qouting stuff. Perl had kinda interesting feature
             | regarding that where in special mode (recommended for apps
             | dealing with untrusted inputs) the variable was considered
             | tainted [1] till something "cleaned" it by passing it thru
             | regexp. So say taking argument directly from environment
             | (so headers for web) or stdin and passing it with no
             | processing to system() would trigger it.
             | 
             | * [1] https://perldoc.perl.org/perlsec
        
           | yakubin wrote:
           | With people reaching for kqueue, epoll and io_uring to handle
           | the C10K problem it seems that spawning processes wouldn't be
           | a great idea, with the latency and memory overhead of
           | spawning itself, as well as the meagre limits of the number
           | of concurrent processes in a system.
        
         | geenat wrote:
         | lambda = highest efficiency path for your money into bezos'
         | bank account.
        
           | revskill wrote:
           | Because people lack enough time, but have enough money.
        
             | ilyt wrote:
             | Yet they always find a time to wank with some new tech
             | stack instead of just using what worked before just fine...
        
             | Existenceblinks wrote:
             | _Start time_ yeah. They seem to have a lot of time later
             | trying to come with something more time efficient in long
             | term.
        
         | ojkelly wrote:
         | Lambdas are awesome because they enable event driven computing
         | without needing to worry about scaling.
         | 
         | There's other ways to get that model, but lambda makes it
         | pretty easy.
        
         | WJW wrote:
         | If there is another request "in the queue", a lambda that is
         | done with a request will just pick that one up instead of
         | closing down and letting a new lambda spin up to deal with the
         | next request. So as soon as you have enough traffic that you
         | have $CONCURRENCY_LIMIT amount of lambdas running (otherwise
         | you would never build up a queue of course), the execution
         | model of lambdas approximates fastCGI much more than regular
         | CGI.
         | 
         | Personally I think the enthusiasm for lambdas stems from
         | several things:
         | 
         | - A (legitimate) interest in outsourcing non-essential things
         | like server maintenance to somewhere else with more ops
         | experience. This frees up the devs to work on business logic
         | instead of worrying about backups and log rotations.
         | 
         | - Some people are REALLY enthusiastic about the whole scale-
         | down-to-zero thing. I personally think that that is somewhat
         | shortsighted, since that means trading (expensive!) engineering
         | time to save a few 100 USD per month on your AWS bill.
         | Sometimes it is definitely worth it to cut costs, but usually
         | it's engineers overoptimizing the one aspect of profit they
         | have significant influence over (ie hosting costs).
         | 
         | - Some people are very enthusiastic about how you can instantly
         | get to "web scale" with lambdas by just putting a very large
         | max concurrency number. That is somewhat true, but massive
         | overkill for the vast majority of companies. It's "engineer it
         | like Google" syndrome but with Amazon instead.
        
       | lucidguppy wrote:
       | I'm having fun with django + htmx and going to deploy on elastic
       | beanstalk.
       | 
       | It hits that sweetspot of speed of development and
       | responsiveness. You also have the benefit of staying in one
       | language.
       | 
       | Django has so much out of the box that you don't have to decide
       | for yourself after the fact. So much accumulated knowledge of
       | what works too.
       | 
       | Sure go ahead rewrite it if it starts making money and you can
       | afford development time/salary. But these older technologies are
       | easier to fit inside one head and let you get enough speed to
       | take off.
        
         | hit8run wrote:
         | This is also a very sane combination. HTMX is great and Django
         | is also very impressive :) We need tools that work for us not
         | us working to make them work.
        
           | account-5 wrote:
           | >We need tools that work for us not us working to make them
           | work.
           | 
           | Stealing this for work, couldn't agree more.
        
             | hit8run wrote:
             | :) Go ahead. Spread the message.
        
           | elwebmaster wrote:
           | Wasn't that what Microsoft used to give us back in the days
           | of Visual Studio, .NET and especially LightSwitch? Amazing
           | technology, more than 10 years later we don't have anything
           | coming close to it for developer productivity.
        
       | jeffbee wrote:
       | Not mentioned: testing CGIs is extremely simple because it is
       | just stdio.
        
       | [deleted]
        
       | geenat wrote:
       | Yup been thinking of this a ton lately.
       | 
       | Combined with single binary caddy and sqlite (+wal) gets you down
       | to copy + paste production-ready deployments.
        
         | juanse wrote:
         | Are there any good and practical tutorials about this?
        
       | superkuh wrote:
       | You don't even need CGI. Just write your programs to tail the
       | webserver access log file and generate the appropriate
       | pages/changes. :) I'm not making fun. I actually do this to
       | implement my comment system.
        
       | okasaki wrote:
       | Eh, as someone who started with CGI, I think using something like
       | Flask is easier than fiddling around with CGI.
        
         | smetj wrote:
         | Yup agreed
        
         | NoboruWataya wrote:
         | If you're familiar with Python, sure. A great thing about CGI
         | is that you could use it with Bash if you were so inclined.
        
           | ilyt wrote:
           | That kind of shit gives sysadmins nightmares
        
         | nightfly wrote:
         | You can use flask with CGI too ;) I did this last month for a
         | website that only needed to live for a few weeks so it could
         | piggyback off an existing Apache setup and require less work to
         | setup and run.
        
       | revskill wrote:
       | Because of PHP. Noone wants to have joy coding in PHP.
       | 
       | There's a big difference between get shit done and enjoy it.
        
         | scotty79 wrote:
         | I don't think I ever ran PHP through CGI. It was either mod_php
         | in apache2 or FastCGI.
         | 
         | And I started around PHP 4
        
       | nine_k wrote:
       | CGI is fine for unfrequently accessed pages on a machine that has
       | some other purpose. Say, a stats / monitoring page on a file
       | server, or something similar.
       | 
       | [FastCGI] keeps most of the CGI's simplicity of the interface,
       | while keeping the worker processes running, instead of starting a
       | fresh copy every time. It's very widely used to this day.
       | 
       | [FastCGI]: https://en.wikipedia.org/wiki/FastCGI
        
       | 082349872349872 wrote:
       | I once got a term sheet on the basis of a "website" which was a
       | quick-n-dirty lash-up of CGI, cron, and email. Low-code can be
       | done not only with new tech but also with old.
        
       | TekMol wrote:
       | One of the strengths of building web apps in PHP is that you have
       | this nice "Every pageload starts from scratch" system. Much
       | easier to develop and reason about.
       | 
       | It's a petty that in Python, long running threads are the norm.
       | 
       | I hope the Python ecosystem can slowly convert to a CGI style
       | approach.
        
         | hprotagonist wrote:
         | nothing prevents you from spawning a new worker in every
         | endpoint.
         | 
         | it's a nice way to orchestrate long running workers actually:
         | the main process exists exclusively to keep the app up/ talking
         | to gunicorn/uvicorn and register PIDs of a worker process in a
         | queue.
         | 
         | but we're all in on wsgi, i don't see that changing.
        
           | TekMol wrote:
           | The way I understand you, the Python script responsible for
           | an endpoint will keep running for multiple requests?
           | 
           | I prefer it when it just runs for a single request.
        
       | phkahler wrote:
       | Is there a way to maintain a sort of process pool so CGI doesn't
       | have to start a new process with each request? It's also
       | important that a CGI crash doesn't kill the web server.
        
         | kristov wrote:
         | I think FCGI is what you want.
        
       | marban wrote:
       | I've built anything from CGI guestbooks to webrings in the '90s
       | but IMO the sweet-spot for solo projects in terms of time to
       | market and scalability/stability is the humble combo of Flask &
       | Caddy.
        
       | sgbeal wrote:
       | It might interest readers to know that the Fossil SCM's primary
       | mode of operation is CGI, and has been since it began life in
       | 2007: https://fossil-scm.org/home
       | 
       | When i first discovered fossil, in December 2007, its ability to
       | run as a CGI was one of its two "killer features" for me, and
       | it's still right at the top of its list of killer SCM features
       | for me.
       | 
       | (Disclaimer: i'm a long-time fossil contributor, but its CGI
       | support pre-dates my joining the project.)
        
       | didip wrote:
       | Just use your favorite programming language's http server
       | library. The development time will be faster and the code will be
       | more cohesive.
        
       | mmcgaha wrote:
       | I built a bunch of "contact us" pages for folks over the years
       | and always used python with the built in CGI library. The python
       | folks thought so little of CGI that they ripped it out of the
       | standard library. I wish I had just used Perl like god had
       | intended CGI scripts to be written.
        
         | pixelfarmer wrote:
         | I had a good laugh when reading this.
         | 
         | On that note, I recently revived some nearly 20 year old perl
         | CGI stuff. Had some minor syntax issues (language ambiguities
         | which got fixed), but it was running just fine after having
         | fixed these. There was also some C code with it (some tooling),
         | needed header include fixing + function renaming, otherwise
         | still worked. Small project all in all, not reliant on a lot of
         | external things.
        
         | anthonyhn wrote:
         | >The python folks thought so little of CGI that they ripped it
         | out of the standard library.
         | 
         | IIRC, the issue was that they didn't have a maintainer for the
         | cgi library anymore, and that is why they removed it.
        
       | cassepipe wrote:
       | I really like Haserl (https://haserl.sourceforge.net/). It acts
       | as a middleman for CGI scripts and and makes it easy to write
       | them with a shell or lua while keeping the look a HTTP response
       | with a html body.
        
         | synergy20 wrote:
         | same here,especially on embedded boards
        
         | cassepipe wrote:
         | Thought I'd post the description :
         | 
         | """ Haserl is a small cgi wrapper that allows "PHP" style cgi
         | programming, but uses a UNIX bash-like shell or Lua as the
         | programming language. It is very small, so it can be used in
         | embedded environments, or where something like PHP is too big.
         | 
         | It combines three features into a small cgi engine:
         | 
         | It parses POST and GET requests, placing form-elements as
         | name=value pairs into the environment for the CGI script to
         | use. This is somewhat like the uncgi wrapper.
         | 
         | It opens a shell, and translates all text into printable
         | statements. All text within <% ... %> constructs are passed
         | verbatim to the shell. This is somewhat like writing PHP
         | scripts.
         | 
         | It can optionally be installed to drop its permissions to the
         | owner of the script, giving it some of the security features of
         | suexec or cgiwrapper. """
        
       | synergy20 wrote:
       | is there a good fastcgi implementation somewhere,the "official"
       | one was not maintained since years ago. https://fastcgi-
       | archives.github.io/
        
         | neilv wrote:
         | FastCGI is tricky to implement, which can mean server bugs you
         | don't ever want to have to debug. SCGI is much simpler:
         | 
         | http://python.ca/scgi/protocol.txt
         | 
         | I started implementing a FastCGI client library for Racket, and
         | (though I have experience getting into the bytes and bits of
         | protocol implementation) it seemed harder than it needed to be.
         | So I decided to try SCGI first, and SCGI ended up working great
         | in production:
         | 
         | https://docs.racket-lang.org/scgi/
        
         | habibur wrote:
         | I have followed this tutorial and wrote my own.
         | 
         | https://www.mit.edu/~yandros/doc/specs/fcgi-spec.html
         | 
         | Easier than integrating a 3rd party tool.
        
       | ytjohn wrote:
       | I've been doing a good bit of research and planning for self-
       | hosted Functions as a Service (also marketed as Serverless). Now,
       | right off the bat, setting up one of the frameworks in kubernetes
       | to accomplish this is going to be more complicated than setting
       | up a cgi-bin capable system. So I wouldn't quite recommend self
       | hosting it for a personal project.
       | 
       | But if someone else set it up, or you're using one of the cloud
       | ones, FaaS sort of reinvents the cgi-bin mindset. Here is a talk
       | by one of the Fission.io devs showing the similarities.
       | 
       | https://www.youtube.com/watch?v=X-XV6vvwhuo
       | 
       | Not a plug for fission, not affiliated. I mainly like how they
       | integrate with Keda for event/message queue setups.
        
       | derekzhouzhen wrote:
       | For CGI you need a interpreted language that start up fast. Last
       | I checked Perl5 is still the king.
       | 
       | Writing CGI scripts with node.js is theoretically possible but
       | you are in for a lot of pain.
        
         | rascul wrote:
         | It doesn't have to be an interpreted language. As long as you
         | can read environment variables and write to stdout then it can
         | be any language.
        
           | dizhn wrote:
           | PHP's original creator was doing this with C when he decided
           | to write a simpler alternative I believe.
        
           | derekzhouzhen wrote:
           | You can do CGI in C, but isn't it defeating the biggest
           | advantage which is simplicity?
        
       | cassepipe wrote:
       | IIRC from when I wrote a basic http server, the problem with CGI
       | is that you have to store the output of the script in memory in
       | order to insert the Content Length field value in the http
       | respondse header. It seems like a rather innefficient operation,
       | especially if repeated a million times on a server. Else you
       | could just read from the your CGI process in a non blocking
       | manner, writing back to the socket whenever output is available.
       | Am I correct ?
        
         | sdflhasjd wrote:
         | You can use chunked transfer encoding to send data of unknown
         | length.
        
         | habibur wrote:
         | transfer-encoding: chunked, and then send data in 64kb packets.
         | You need to tell the size of each packet at its header. Even
         | then, it is an optional good practice, but not required by RFC.
        
       | ananonymoususer wrote:
       | I had to click and read the article to see whether CGI in this
       | context was "Computer Generated Imagery" or "Common Gateway
       | Interface". I've always been a fan of simple CGI interfaces. More
       | middle-ware always means more bugs.
        
       | ilyt wrote:
       | As someone that was sysadmin back in the days where cgi-bin was
       | norm I can only say one thing about cgi-bni:
       | 
       |  _projectile vomits profusely_
       | 
       | > No dependencies or libraries to install, upgrade, maintain,
       | test, and secure.
       | 
       | Except entire webserver. Just install <your language's preferred
       | web server lib> if you want simple.
       | 
       | > Works with any programming language ever that can read text and
       | print text.
       | 
       | You won't use it with those that can't anyway unless for mental
       | excercise
       | 
       | > Zero external configuration, other than telling your webserver
       | to enable CGI on your file.
       | 
       | Except entire webserver. Just install <your language's preferred
       | web server lib> if you want simple.
       | 
       | Seriously, what kind of nostalgia someone needs to have to have
       | any positive thoughts over cgi-bin?
        
       | Animats wrote:
       | I still use FCGI. FCGI works a lot like CGI; it loads programs
       | when a request comes in, and the programs deal with the request.
       | But it's much higher performance, because it doesn't have to
       | freshly load the target program each time.
       | 
       | FCGI is an orchestration system. It starts up more worker
       | processes if there are more requests, up to some limit it figures
       | out by itself. If there are few requests, some of the worker
       | processes get an end of file notification and exit. If a worker
       | process crashes, it loads a fresh copy. Little or no human
       | attention required. One of my systems has been up for 1788 days
       | now.
       | 
       | FCGI works fine with Go programs, Python programs, etc. If you
       | use Go, you can get performance reasonably close to what the
       | hardware can do. Until you get to the point that you're renting
       | additional servers as load increases, you don't need more than
       | that for most applications.
       | 
       | You can run FCGI on some cheap shared hosting systems. Why pay
       | more?
        
         | LAC-Tech wrote:
         | I'm really interested in this. How do you handle DB
         | connections? I guess each CGI file becomes stateful because
         | it's not reloaded all the time, and there's a connection handle
         | there.
        
         | lma21 wrote:
         | for Go, do you rely on `net/http/fcgi` to run it? Do you have
         | any example i can have a look at?
        
           | Animats wrote:
           | > for Go, do you rely on `net/http/fcgi` to run it?
           | 
           | Yes.
           | 
           | > Do you have any example I can have a look at?
           | 
           | https://github.com/John-
           | Nagle/vehiclelogserver/blob/master/v...
           | 
           | There's not much machinery required.
           | package main         import (             "database/sql"
           | "net/http"             "net/http/fcgi"         )
           | //         //  Called by FCGI for each request         //
           | func (sv FastCGIServer) ServeHTTP(w http.ResponseWriter, req
           | *http.Request) {             body := make([]byte, 5000) //
           | buffer for body, which should not be too big             if
           | req.Body != nil {                 len, _ :=
           | req.Body.Read(body)          // body of HTTP request
           | bodycontent := body[0:len]             // take correct part
           | of buffer                 Handlerequest(sv, w, bodycontent,
           | req) // handle request             }         }
           | //  Run FCGI server         func main() {             sv :=
           | new(FastCGIServer)             fcgi.Serve(nil, sv)         }
           | //  Handlerequest -- handle one request from a client
           | func Handlerequest(sv FastCGIServer, w http.ResponseWriter,
           | bodycontent []byte,              req *http.Request) {
           | // GENERATE REPLY CONTENT HERE
           | w.WriteHeader(statuscode)           // internal server error
           | w.Write(content) // report error as text ***TEMP***         }
           | 
           | That will run on low-end hosting at Dreamhost.
           | 
           | So there you are, in a modern language, with hard-compiled
           | code with good performance, and reasonably good fault
           | tolerance. Next step up would be a load balancer and
           | redundant databases.
        
       | 1vuio0pswjnm7 wrote:
       | I got a 404 when trying to access the referenced blog post about
       | CGI.
       | 
       | https://web.archive.org/web/20210822121843if_/https://halest...
       | 
       | https://webcache.googleusercontent.com/search?q=cache:https:...
       | 
       | "If I'm ever in the situation again of helping new people learn
       | web technology then I'm going to get or convert them to use CGI
       | right off the bat. It's easier to teach, it's easier to
       | understand, easier to get working on most webservers and isn't
       | locked in to any particular language or framework.
       | 
       | The only downside of CGI that I know about is the fact it starts
       | a new process to handle each user request. Yes that's a problem
       | in big sites handling hundreds or thousands of visitors per
       | second. But by the time a new student gets to running a big site
       | they will have already encountered many, many other scalability
       | issues in their code and backend/storage. Let alone teaching them
       | database and security concepts. There's a reason we have quotes
       | like "premature optimisation is the root of all evil".
       | 
       | I don't think students new to webdev should be started on
       | anything other than CGI. They can use any language they want.
       | They can actually understand what they're doing. And they're not
       | hitting any artificial barriers or limits set by frameworks or
       | libraries."
       | 
       | OpenWRT still uses CGI
       | 
       | https://openwrt.org/docs/guide-user/luci/luci.on.lighttpd
        
         | wrycoder wrote:
         | https://web.archive.org/web/20221208052912/https://halestrom...
        
         | yarg wrote:
         | It's still there, hug of death?
        
         | [deleted]
        
       | qbasic_forever wrote:
       | In 2023 I don't think CGI is as easy as it was back in the day.
       | The major proxies/servers most people use like nginx only support
       | FCGI which isn't directly compatible with CGI--you need to run
       | helpers like fcgiwrap or other new layers of complexity. The only
       | major servers that still support plain old CGI are apache and
       | lighttpd. IMHO properly configuring apache is a mess.
       | 
       | I think what people really want when they pine for the days of
       | CGI is simple file-based routing for dynamic content. Look around
       | and you can see new frameworks are coming back around to this...
       | or consider plain old PHP.
        
       | eknkc wrote:
       | I would ocassionally see dynamic web pages with .exe extensions
       | before 2000s. I assume Windows IIS was also CGI capable and
       | people were building dynamic web handlers in whatever language,
       | compiling down to an executable.
       | 
       | It makes perfect sense but always felt out of place to me for
       | some reason.
        
         | HeckFeck wrote:
         | I recall eBay used to have ISAPI.dll in most of its request
         | URLs. It bewildered my younger self who thought DLLs were only
         | for a Windows machine, not a web server.
        
           | mrweasel wrote:
           | A previous employer of mine build a CMS for newspapers,
           | written in Delphi and ran on Windows under IIS, it too was
           | had a .dll extension. I believe it was the same IIS API
           | (ISAPI) that made it work. It was an insane product that had
           | simply failed to move forwards.
           | 
           | It's not that you can't do what you need to do using the
           | ISAPI, but the ecosystem is just to small for things like the
           | Delphi stuff and keeping up with expectations of customers
           | becomes to much work.
        
             | HeckFeck wrote:
             | It's impressive that anything that built the correct DLL
             | could be leveraged by it.
             | 
             | But I assume ISAPI didn't have anything like CPAN or pip.
             | It seems likely you'd have to write everything yourself -
             | perhaps worthwhile if you were a very large corporation
             | with the manpower. But something as simple as PHP would
             | swamp it for the rest of us.
        
         | RedShift1 wrote:
         | IIS was and still is CGI capable, but starting a process on
         | Windows is a very heavy weight thing (compared to starting a
         | process on linux), so it doesn't scale well and a noticeable
         | initial delay whenever it executes. To solve that MS made
         | ISAPI, which runs inside the webserver similar to an Apache
         | httpd module.
        
           | Semaphor wrote:
           | Until early 2009, we ran a PHP website under IIS via an ISAPI
           | FastCGI module that executed PHP :D
        
         | cassepipe wrote:
         | In the CGI RFC, IIRC they say that what they call a script can
         | totally be a binary. The fact that _execve_ on linux can take a
         | script with a #! shebang makes it it easy to implement, you don
         | 't have to care whehter you are exec'ing a binary or a script.
        
       | VWWHFSfQ wrote:
       | > No dependencies or libraries to install, upgrade, maintain,
       | test, and secure.
       | 
       | So you don't actually want this program to do nearly anything
       | useful unless you write it all yourself.
       | 
       | > Zero external configuration, other than telling your webserver
       | to enable CGI on your file.
       | 
       | So now you have to have a webserver external dependency and also
       | configure it. Configuring Apache for CGI securely was no fun
       | unless you were an expert webmaster.
       | 
       | People really put their rose-colored glasses on when they
       | reminisce about this stuff. But there's a reason why we don't use
       | it anymore. We don't need to make up nonsense about why it was so
       | great.
        
         | MintPaw wrote:
         | > So you don't actually want this program to do nearly anything
         | useful unless you write it all yourself.
         | 
         | I think the idea is that there's no _required_ dependencies.
         | Unless I misunderstand, you can take on whatever dependencies
         | you want from your chosen language.
        
         | myth2018 wrote:
         | With all due respect, I think you missed some points there.
         | 
         | > > No dependencies or libraries to install, upgrade, maintain,
         | test, and secure.
         | 
         | This is mentioned as opposed to what we have today with
         | Node.js, Pip and so on. Old CGI programs surely had
         | dependencies. But dependency management was dramatically
         | simpler. Of course there are pros and cons in the comparison.
         | But simplicity is the key reminiscence here.
         | 
         | > But there's a reason why we don't use it anymore.
         | 
         | However I wonder: are all those reasons still valid? To what
         | extent were those reasons motivated by rational decisions
         | instead of pure trend-following? We shall not fool ourselves:
         | not every technical decision we make have grounds on reason. I
         | suspect most of them are not.
        
       | torstenvl wrote:
       | I love CGI and still use it all the time. It's natural MVC too
       | which is great.
       | 
       | Someone should make a framework like Electron or Tauri or
       | NeutralinoJS that works like CGI. Neutralino on is probably the
       | closest but... could be simpler. Just push everything over a
       | pipe.
        
         | RedShift1 wrote:
         | Can you explain the "natural MVC" part?
        
         | transfire wrote:
         | GTK Server (https://www.gtk-server.org/intro.html)
        
           | [deleted]
        
         | hnlmorg wrote:
         | > _Someone should make a framework like Electron or Tauri or
         | WebKit that works like CGI. Don 't need to use TypeScript or
         | Rust or whatever. Just push between backend and frontend over a
         | file stream._
         | 
         | I'd argue that already exists in the form of your $SHELL.
        
           | [deleted]
        
       | rwmj wrote:
       | As someone who wrote a large, commercial social network for
       | schools in Perl + CGI.pm in ~ 2000, here were the problems:
       | 
       | * Perl was very memory inefficient so you could often only serve
       | 4 users at the same time, given the limited RAM available (eg.
       | 512M - 1G). Note that Perl's speed was not a problem. I suspect
       | this one has probably gone away with modern servers with massive
       | amounts of RAM, plus the cloud allows you to quickly scale up and
       | down with demand. Nevertheless using a compiled language would be
       | better. (I later wrote a vastly more efficient framework in C).
       | 
       | * Every action on the page had to round-trip to the server, and
       | always involved a database check (at minimum to map the user's
       | cookie to a user ID). This is sort of solved now that Javascript
       | is widely supported, although that brings its own issues along.
       | Also memcached neatly solves the database access problem. Our
       | website was developed a little bit before memcached.
       | 
       | * It's very clumsy and time-consuming to write any non-trivial
       | CRUD-style action using CGI. eg. Just having a table with
       | update/delete buttons is going to involve writing paging code,
       | update form, update submit form (repeat for every possible
       | action). This is the kind of thing that Ruby on Rails solved
       | quite nicely.
       | 
       | * Organizational problems interfacing with the database. We had
       | to negotiate with the DBA for every schema change, which is a
       | problem when the DBA is a sociopath supported by management.
       | Devops sort of solves this (but also I appreciated not being on
       | call).
       | 
       | * The general hassle of dealing with the web, like setting all
       | the non-obvious HTTP headers to make it secure. I think modern
       | frameworks just deal with this, although I've not used them very
       | much.
       | 
       | However if I was to go back and change anything, it wouldn't have
       | been to change the technology. It would have been to extend the
       | service first to university students and later to the whole world
       | :-)
        
         | daneel_w wrote:
         | _" Perl was very memory inefficient so you could often only
         | serve 4 users at the same time, given the limited RAM available
         | (eg. 512M - 1G). Note that Perl's speed was not a problem. I
         | suspect this one has probably gone away with modern servers
         | with massive amounts of RAM. Nevertheless using a compiled
         | language would be better. (I later wrote a vastly more
         | efficient framework in C)."_
         | 
         | I cannot even imagine the strange complexities of this circa
         | year 2000 web application if it could only fit 4 simultaneous
         | page loads on 1 GB of RAM. It's baffling, in fact. Perl isn't
         | really memory hungry these days. Was it really that bad 20
         | years ago? I would be surprised if the Perl 5 interpreter
         | wasn't in fact much leaner back then. At least my immediate
         | impression of this bullet point is that it wasn't a programming
         | language problem, but a software design problem.
        
           | ilyt wrote:
           | It was definitely a software problem. Small Perl app would
           | take few tens of MBs max back then (and now).
           | 
           | Also Perl FCGI existed much earlier than 2000 (looking at
           | CPAN ~'96-97 appear to be first versions), althought
           | obviously the code would be bit more complex than just "dump
           | html on stdout"
        
           | rwmj wrote:
           | Well it depends what you're doing of course. Part of the
           | application was an email interface which I remember was a
           | particular problem - it was likely loading whole emails into
           | memory to do MIME parsing. But the point here is that large,
           | slow processes gradually take over your system crowding out
           | smaller and simpler requests. We had our own cage in a
           | Docklands data centre, so "spinning up another server" was a
           | weeks long process involving many people.
           | 
           | In modern terms Perl isn't a problem, especially when you
           | have servers with hundreds of gigabytes.
        
             | daneel_w wrote:
             | I can safely say that it's not really an immediately
             | impeding problem with 1 GB of RAM either. I have a bit of
             | experience in the context as I develop and manage a _very
             | large_ Perl software stack that runs on a fleet of servers
             | ranging from itty-bitty to small /medium. Some of it is
             | inefficient CGI, some of it is FastCGI, some of it is
             | resident in the background and some of it fires up on
             | intervals. All of it is heavily trafficated.
             | 
             | But, certainly, I'll concede that if the platform is
             | completely CGI-based and for some reason is written such
             | that there's a minimum footprint of 50-100 MB for any
             | single invocation, then servers will be needing a bit of
             | memory in lieu of a software rethink.
        
       | est wrote:
       | Nextup: inetd was better than sidecars.
        
         | mmcgaha wrote:
         | I wrote a web app that launched from inetd to control my cd
         | player. It worked great but wasn't super practical since I
         | tended to use it from the same computer that it ran from.
         | Everything web was fun in the 90s though.
        
       | grose wrote:
       | Recently I enjoyed some "retrofuturistic" development with WASM
       | and CGI. Spin[1], a webserver written in Rust, can execute
       | WASI[2] binaries that speak CGI. You can then deploy it to
       | Fermyon Cloud or your own server and it "just works". It's a
       | wonderful mix of old and new. I used it for PHP (Prolog Home
       | Page): https://github.com/guregu/php
       | 
       | [1]: https://spin.fermyon.dev/
       | 
       | [2]: WASI is a POSIX-ish standard for WASM that gives you all the
       | low level stuff like standard input and output. It includes all
       | the bits and pieces needed for CGI to work.
        
         | bmacho wrote:
         | It interprets PHP-style commands, hence the name.
        
         | IshKebab wrote:
         | Kind of feels like the AssemblyScript guys were right - WASI is
         | becoming a standard for WASM modules that foists Unix on
         | Webassembly, including stuff that isn't really portable like
         | symlinks.
         | 
         | That makes sense if you want to compile existing software to
         | WASM but that isn't the case here is it?
        
           | sitkack wrote:
           | Wasm allows you to consume as much or as little of the API
           | surface area as you want. You are free to construct Wasm
           | modules in whatever way you see fit for your application.
        
           | grose wrote:
           | This does use existing software. The onus behind this project
           | was to test my port of Trealla Prolog (which was written by
           | someone else) to WASM. Without a Unixy standard environment
           | it would have been a lot harder. In theory, WASI should
           | enable many CGI-like usages of pre-existing software, but in
           | my experience the quirks between the WASI implementations
           | push you towards using nonstandard things anyway. For
           | example, trealla-js is mostly WASI but uses a couple extra
           | imported functions to coordinate calling into JS. If I wanted
           | to let PHP make outgoing requests I'd have to implement
           | Spin's custom nonstandard components. I hope the WASM
           | Components proposal makes this easier in the future.
           | Personally, I might have preferred a more Plan 9-style
           | approach that uses special files to do things like make
           | outgoing connections, purely because it would be trivial to
           | implement client-side as a simple printf vs. integrating wit-
           | bindgen into the build system and all of that. However, I can
           | see many benefits of the strongly typed component model as
           | well.
           | 
           | I don't have a strong opinion on the AssemblyScript
           | controversy[1]. I agree that WASI is imperfect, especially in
           | browsers, but I'm also glad that _something_ exists with not-
           | horrible runtime support. WASI was pretty nice to use as
           | someone who just wanted to get a C program running on WASM.
           | 
           | [1] https://www.assemblyscript.org/standards-objections.html
        
       | rvense wrote:
       | I developed a need recently to gather some answers to a few
       | simple questions from people all around the internet. Maybe a few
       | hundred at most.
       | 
       | I don't want to make a Google survey or a Doodle or any of that.
       | It's not for me, not off the clock anyway.
       | 
       | I built a simple HTML form to start with. Just typed it out like
       | it was 1997 again (and then added a little Javascript so it
       | remembers that you've submitted the form to soft-block people
       | from submitting more than once; and some CSS to make it look a
       | little nicer and work on phones and such).
       | 
       | Then I thought I had to build a small backend with a database...
       | I'd originally planned to do a simple CGI thing that stuck the
       | form in SQLite or whatever, but then, when I was doing the
       | frontend, I saw that the web server that I use to serve the file
       | actually puts the entire query string in the access log on disk.
       | 
       | So that's it. That's the backend. I can just grep the log file
       | when I want the answers.
        
         | [deleted]
        
       | jstrieb wrote:
       | > Zero external configuration, other than telling your webserver
       | to enable CGI on your file
       | 
       | This is only true if you've done it before, and know what you're
       | doing. In reality, it looks like a mess of `mod_cgi`
       | configuration, trying different combinations of file permissions,
       | finding the magic `cgi_bin` directory, finding the right obscure
       | log files when there are inevitably errors, wrestling with CORS
       | and other subtleties of HTTP headers, and other complexities that
       | are only easy to navigate if you're already an experienced CGI
       | user.
       | 
       | That being said, I love the philosophy of using CGI for scripts.
       | Instead of using CGI itself, though, I wrote a (single-file,
       | statically-linked) web server called "QuickServ" to bring this
       | philosophy into the twenty-first century. It has all of the
       | upside of CGI, but is much easier to set up and run, especially
       | for beginners.
       | 
       | One of its benefits is that it automatically parses submitted
       | HTTP forms, and converts the form fields to command line
       | arguments. That means it's extremely easy to put existing CLIs on
       | the web with minimal changes other than writing an HTML form
       | front-end.
       | 
       | If you like CGI, I will (shamelessly) ask that you check it out!
       | 
       | https://github.com/jstrieb/quickserv
       | 
       | https://news.ycombinator.com/item?id=29002694
        
         | ilyt wrote:
         | I thought about that for few of the personal stuff but in the
         | end I just opted to have _a_ binary that 's just http router +
         | abstracted away way to handle requests. So when I need new
         | feature I just add a module and deploy whole (that includes
         | static files) blob. No need to create new service, add it to
         | loadbalancer etc.
        
         | iso1631 wrote:
         | a2enmod cgi; service apache2 restart
         | 
         | Then in your config file                 AddHandler cgi-script
         | .cgi       Options +ExecCGI
        
       | rgrieselhuber wrote:
       | This will sound weird but I felt a sense to relief that there are
       | other people still thinking about the web in this manner.
        
         | monkeycantype wrote:
         | I do contract work for a company that has it's pretty customer
         | facing site as a mix of angular/react/react native and .net
         | core apis and the less pretty internal staff site which is
         | vanilla html, js and c++ cgi apis, so I get to work in both on
         | the same day. The internal c++ site has been running for ~25
         | years. The customer site seems to need to be re-written every
         | time we add a new feature, because all the tech is out of
         | support and there are breaking changes to libraries
        
       ___________________________________________________________________
       (page generated 2023-01-07 23:00 UTC)