Most active commenters
  • ryao(4)
  • zokier(3)
  • (3)

53 points heavensteeth | 60 comments | | HN request time: 1.958s | source | bottom
1. sshine ◴[] No.43651854[source]
RIP, FastCGI.
replies(1): >>43652949 #
2. ryao ◴[] No.43652062[source]

  If you find yourself with a scripted language where processing HTTP requests might be too slow or unsafe, I can still see some utility for FastCGI. For most of the rest of us, HTTP won, just write little HTTP webservers.
Without serious development effort, I would expect using an existing web server with FastCGI is faster than writing your own web server. It is also more secure as the FastCGI application can be run as a different user in a chroot, or a namespace based sandbox like a docker container.
replies(4): >>43652278 #>>43652341 #>>43654110 #>>43671603 #
3. cess11 ◴[] No.43652135[source]
Was FCGI ever common outside of PHP?
replies(6): >>43652165 #>>43652177 #>>43652287 #>>43652408 #>>43652637 #>>43653139 #
4. miggol ◴[] No.43652150[source]
Similar protocols like ASGI for Python are still ubiquitous. I assume because they offer separation of concerns and as a result good performance.

You would think the separation argument would still hold true for compiled languages, even if performance is no longer as relevant.

replies(1): >>43652273 #
5. jeltz ◴[] No.43652165[source]
It was common in the Perl world.
6. actionfromafar ◴[] No.43652177[source]
I don't know, but I think I used it with Java and/or C at some point. It's very simple, you don't need libraries or anything.
7. zokier ◴[] No.43652273[source]
I don't think interfaces like ASGI/WSGI etc are that similar to FastCGI. The crucial difference is that FastCGI is a protocol, something you need to do IO for and crucially something you need to parse. In contrast ASGI etc by virtue of being in-process and specific to the language can provide an true API. In many ways FastCGI is closer to HTTP than ASGI.
replies(2): >>43652708 #>>43654852 #
8. usef- ◴[] No.43652278[source]
I was thinking that.

Was FastCGI a child of a world where we had neither good library use ("import net/http"), nor (much) layering in front of the server (balancers / cdns / cloudflare etc). So it made sense to assume a production-level layer on the box itself was always needed?

I remember the vigorous discussions comparing security of Apache vs IIS etc

replies(3): >>43652393 #>>43652689 #>>43653386 #
9. p_l ◴[] No.43652287[source]
Before Phusion Passenger and Mongrel it was common in Rails world too.
10. zokier ◴[] No.43652325[source]
It's baffling how FastCGI ever was popular, considering how weird it's premise is: let's take this well-known standard simple text based protocol and convert it to our own custom binary protocol, that will make writing services somehow simpler?! You are still dealing with all the complexity of writing a daemon, only difference is that instead of parsing HTTP you parse FastCGI.

Maybe today with all the complexity that is with http2/http3 etc it would make slightly more sense. But FastCGI was popular when all the world was just good old plain http1.

replies(2): >>43652435 #>>43653370 #
11. zokier ◴[] No.43652341[source]
Using HTTP does not preclude having a reverse proxy. So the only difference between FastCGI and HTTP is really what protocol your proxy and your application use, and I don't really see why FastCGI would be major win there.
replies(3): >>43655728 #>>43655779 #>>43655823 #
12. erincandescent ◴[] No.43652355[source]
The thing (Fast)CGI had, that http proxying doesn't (and lots of web frameworks/libraries a bit too tied to http, like go net/http don't) have is the SCRIPT_NAME (path processed so far) / PATH_INFO (path left to handle) distinction
13. immibis ◴[] No.43652368[source]
FastCGI is a protocol you can use between a reverse proxy and a back end. It's better for this than HTTP because it passes proxy-generated metadata out of band from client-generated metadata, so you can't have vulnerabilities like fake X-Forwarded-For. It's also strictly defined so you can't have request parsing differences or request smuggling.

If you're currently using a reverse proxy, did you remember to make sure that your proxy always deletes X-Forwarded-For from the client, always adds its own, OR that the backend always ignores it? And you have to do this for each piece of metadata you expect to come from the proxy. With FastCGI this is not needed.

I chose SCGI instead of FastCGI, though, since nginx doesn't support multiplexing and I don't use large request bodies. SCGI not supporting multiplexing makes it much simpler to write a back end. You just accept a new socket and fork for each request.

By the way, FastCGI wasn't designed as "binary HTTP" as implied by some sibling comments, but rather "CGI over a socket". It passes the environment variables the CGI program would have had, and multiplexes its stdin, stdout and even stderr. SCGI is the same but without multiplexing or stderr.

Author complains about having to use a reverse proxy at all, which is fine for prototyping, but I have about 5 domains pointed at the same server, and multiple apps on some domains, so why wouldn't I use a reverse proxy to route those requests? And yes, I run the same nginx reverse proxy on my development machine for testing.

14. phire ◴[] No.43652393{3}[source]
Partly.

But I suspect it's more that CGI was the way things had always been done. They didn't even consider doing a reverse proxy. They asked the question "how do we make CGI faster" and so ended up with FastCGI.

Other developers asked the same question and ended up making mod_php (and friends), embedding the scripting language directly into the web server.

15. 4ndrewl ◴[] No.43652408[source]
Before PHP it was common in the Perl world.
16. lmz ◴[] No.43652419[source]
There are also other modes/roles of FastCGI: Authorizer and Filter which may be interesting: https://fastcgi-archives.github.io/FastCGI_Specification.htm...

Not sure I've ever seen Filter in real life.

17. jagged-chisel ◴[] No.43652435[source]
I (the user of the FastCGI library) don’t parse anything. I use the library. Whether it does HTTP or some custom protocol is irrelevant to my coding task. Might be relevant for performance, but who’s building anything big enough to worry about that? ;-)
18. knagy ◴[] No.43652490[source]
I went down this rabbit hole a while ago[1], it's a fun experience to try out technologies that nowadays are considered unconventional or outdated.

[1]: https://deadlime.hu/en/2023/11/24/technologies-left-behind/

19. mhd ◴[] No.43652509[source]
Sure, but does anyone remember SCGI?
replies(2): >>43652808 #>>43654464 #
20. NoboruWataya ◴[] No.43652525[source]
Those of us with an interest in Gemini (the small web protocol, not the AI thing) will have become familiar with CGI and its variants again, as they are commonly used to serve dynamic content over that protocol. Another variant is SCGI[0]. It doesn't seem to have ever been nearly as popular as FastCGI, but seems to be more commonly supported by Gemini servers due to its simplicity.

0: https://github.com/nascheme/scgi

21. ◴[] No.43652628[source]
22. mrweasel ◴[] No.43652637[source]
I used it quite a bit with Python, but it was quickly supplanted by UWSGI.
23. Calzifer ◴[] No.43652654[source]
My biggest annoyance with FastCGI is the ambiguity between FastCGI Server, FastCGI Application and FastCGI Proxy in documentation and articles.

To give some examples what I mean:

- Apache can be a FastCGI server (mod_fcgid) and proxy (mod_proxy_fcgi) - Nginx (and most other Webservers I checked) is only a FastCGI proxy

Wikipedia [1] lists both as "Web servers that implement FastCGI". For me it took some time to recognize the difference whether a server speaks the FastCGI protocol or can also host/spawn FastCgi supporting applications which do not daemonize by themself.

For the (probably) most used FastCGI application PHP this is easy because php-fpm is both a FastCGI server and application.

An example for a (Fast)CGI application which is not also a server is MapServer [2] which is listed by Wikipedia as CGI program and by its own documentation with "FastCGI support" or "FastCGI-enabled".

The fact that it is only a FastCGI application and needs an additional FastCGI server to host it is (in my opinion) not clearly communicated.

A common tutorial to combine MapServer with Nginx is to use fcgiwrap or spawn-fcgi as FastCGI server.

Since a FastCGI application can usually also act as CGI application it is easy to miss that the first option is running the application as CGI and only the second as FastCGI where one instance serves more than one request.

For me the main difference is that a FastCGI server will open a socket and can spawn worker processes (which php-fpm does and MapServer does not) and a FastCGI application (the worker process) will accept and handle connections/requests.

A FastCGI proxy translates requests (usually from HTTP to FastCGI protocol) and redirects them to a FastCGI server. It does not spawn processes like Apaches mod_fcgid does.

Due to the simplicity it should be even possible to use systemd as simple FastCGI server. [3] (I have never tried it)

My recommendation if you ever come across an FastCGI application which cannot open a socket / daemonize by itself use Apache mod_fcgid. Even if you already use another Webserver to handle HTTP. From all options I checked it has by far the most useful options to dynamically limit the number of worker processes and respawn them from time to time.

[1] https://en.wikipedia.org/wiki/FastCGI [2] https://en.wikipedia.org/wiki/MapServer [3] https://nileshgr.com/2016/07/09/systemd-fastcgi-multiple-pro...

24. chasd00 ◴[] No.43652689{3}[source]
Iirc most of the content was static html/css in those days. Running code on a request was rare so cgi was like a bolt on to a static content server. It was available but not the norm. Perl and php gradually made it the norm to run code on every request.
replies(1): >>43652966 #
25. miggol ◴[] No.43652708{3}[source]
That does make sense: an application server like Gunicorn talks ASGI with the application, but Gunicorn itself speaks plain old HTTP with the outside world (or reverse proxy). No more need for FastCGI inbetween.

That is in line with what the article is saying. Thanks for clarifying.

26. dfox ◴[] No.43652808[source]
In my opinion that was step in the right direction, but the protocol design is truly weird. Somehow managing to come up with 4 different ways to encode length of byte strings in otherwise so simple protocol is remarkable achievement.
27. brazzy ◴[] No.43652949[source]
https://www.youtube.com/watch?v=DscJ5PFkZxQ
replies(1): >>43653705 #
28. mdpye ◴[] No.43652966{4}[source]
I remember in the very early days as a hobbyist working with cgi perl scripts for forums or guest books where the script just edited the "static" content in place.

The script would write new html files for new posts and do "fun" (I mean, terrifying) string manipulation on the main index to insert links to posts etc. Sometimes they used comments with metadata to help "parse" pages which would see edits.

These both were, and definitely were not, "the days" :D

29. geenat ◴[] No.43653036[source]
Rails, PHP, a lot of Python stuff (WSGI is CGI wrapped in a dict).

It's not only just about separation of concerns, but also separation of crashes/bugs/issues. FastCGI servers can run for years without restarts.

Thread creation/teardown/sleeping has gotten a lot faster as well in linux.

https://php-fpm.org/about/ it may be old but PHP-FPM is still one of the best FastCGI servers from a pragmatic point of view... ex: the ability to gracefully hot reload code, stop and start workers without losing any queries... all in production.

replies(1): >>43659795 #
30. Aldipower ◴[] No.43653139[source]
Yes, it was very common with Perl, even before PHP. I've written quite a lot of dynamic webpages with FastCGI and Perl and it led to fast and direct results. Combined with mod_perl you also could held this in memory. This was around 2000-2005.
31. zoobab ◴[] No.43653287[source]
Python has cgi-bin support, I made a proxy of the poor like this:

$ mkdir cgi-bin $ echo -e "#!/bin/bash\necho -e \"Content-type: text/html\n"curl -s -k http://www.zoobab.com -o -" > cgi-bin/proxy.sh $ python -m http.server --cgi 8000 $ curl http://localhost:8000/cgi-bin/proxy.sh

You should get the html page of http://www.zoobab.com

replies(2): >>43653841 #>>43654809 #
32. BobbyTables2 ◴[] No.43653370[source]
I think it still makes sense if one wants all the fancy bells & whistles of Apache without reimplementing them in their own webserver.

In some sense, implementing a full webserver just because the world standardized on a horribly inefficient way of handling CGI is pretty silly.

We don’t rewrite “cp” and such just because we want to copy multiple files quickly…

Of course, if the sole purpose is just to handle CGI types of things, then the custom embedded webserver likely makes more sense. Apache is a horribly complex beast.

33. BobbyTables2 ◴[] No.43653386{3}[source]
Sure beats maintaining a custom webserver written in C!
34. sshine ◴[] No.43653705{3}[source]
Since I make most things in Rust nowadays, and the article references the pointlessness of FastCGI when you can write native Rust apps, FastCGI has, for me, entered the realm of the forever undying. I configured it many times in the past, so may it rest in peace. (Not sure why that deserves a downvote.)
35. smittywerben ◴[] No.43653841[source]
Python removed cgi-bin calling it a dead battery module.

> cgi — Common Gateway Interface support Deprecated since version 3.11, removed in version 3.13.

https://docs.python.org/3/library/cgi.html

replies(2): >>43654137 #>>43655992 #
36. assimpleaspossi ◴[] No.43654110[source]
This is exactly why my web dev company used FastCGI for all our development and would still today if I didn't retire it just two years ago.

Wherever we needed faster interaction, FastCGI did the job and allowed us to interface with anything in the backend including our C programs.

replies(1): >>43656823 #
37. at_a_remove ◴[] No.43654137{3}[source]
A shame, I used to use cgi all the time, back when I did web stuff. I wouldn't know what to do now, especially on IIS. Never did understand why I ought to want or need WSGI, other than I "ought to." Nor did I see how I was supposed to code against it, so I simply did cgi. It never raised a problem for me.
replies(1): >>43657530 #
38. immibis ◴[] No.43654464[source]
nginx supports four backend protocols out of the box: HTTP, FastCGI, SCGI, and static files.

Of these, if you get to pick one and the request isn't for a static file, SCGI is the obvious best choice.

You can also load extra plugin modules into nginx itself, of course, including one that puts a Lua interpreter inside nginx (mod_php-style).

39. whalesalad ◴[] No.43654809[source]
The first startup I ever worked for used Python server pages, .psp file extension.
40. ge96 ◴[] No.43654827[source]
I still see it today
41. whalesalad ◴[] No.43654852{3}[source]
WSGI and FastCGI are not mutually exclusive. They talk to each other. They can both be part of the same stack.
42. somat ◴[] No.43655047[source]
I never really understood the rational for using fastcgi. For everything I wanted to do it always made more sense to just use custom http servers and proxys.

CGI makes sense, it fills a specific environment, one request, one process, but fastCGI? why? its a server with a different incompatible HTTP. did everyone jump on it just because it had CGI in the name and the associativity CGI == web process was too firmly entrenched in peoples minds.

But I am not really in a web ops role, so who knows, perhaps fastcgi does have some sort of advantage when run at scale.

replies(2): >>43659523 #>>43671651 #
43. ◴[] No.43655728{3}[source]
44. ◴[] No.43655779{3}[source]
45. ryao ◴[] No.43655823{3}[source]
Given that the article’s comparison is between a HTTP server with fastCGI, and writing a little HTTP server, the web server with fastCGI will scale better, contrary to what the article suggests. It also would likely be more secure. Reverse proxies are tangential to this.
46. ryao ◴[] No.43655992{3}[source]
That is irrelevant as he is talking about the Python http server that runs CGI executables, not using Python as a CGI executable. As for the latter, it is still an option:

https://pypi.org/project/legacy-cgi/

replies(1): >>43672010 #
47. ryao ◴[] No.43656823{3}[source]
Why did you retire it?
replies(1): >>43659851 #
48. mxuribe ◴[] No.43657530{4}[source]
When i started dabbling in python back in the day, and when i had a need for cgi-bin sort of functionality (for simple web front-end), i think it was the sunsetting of popularity of python cgi, and more of the rise of WSGI...so there was less blog posts out there showing best practices around cgi, and more on wsgi...and to me it often felt like i was doing more unnecessary work via wsgi...but then, maybe i'm old and stodgy, and came from the php world prior to dabbling python? Then again, even though i feel i am more mentally sharper now than my younger self...it sure feels like back in the day i was able to be more productive sooner...and nowadays there's just so much setup and harnesses to begin with.
replies(1): >>43664531 #
49. oso2k ◴[] No.43658122[source]
Lots of people are forgetting the context in which FastCGI was conceived: servers were expensive uniprocesser machines and enterprise servers with 2 or 4 sockets were relatively extremely expensive. All processors at the time paid heavier penalties for context switching and/or creating between processes. So the optimization folks building web servers were things like preforking the front end in Apache and/or preforking the middle end (FastCGI, WSGI, SCGI, Java App Servers, et al). The database was Oracle, or MySQL or SQLServer which was already multi client based. Also, in *nix land, the popular scripting languages (Perl, PHP, bash) of the time had a ways to go in reducing their startup times.
50. trashface ◴[] No.43658674[source]
In the pre-days before fastcgi, I knew a guy who compiled his c++ "cgi-bin" programs directly into apache, so running them was just a function call, not a fork.
51. ianburrell ◴[] No.43659523[source]
FastCGI was from time before languages had good HTTP servers. HTTP is complicated, FastCGI is simple. It was also from time when servers were less powerful such that duplicating HTTP parsing was an expense. HTTP parsing is potentially dangerous so safer to do in web server than library. Finally, it was from before the language web APIs (Rack, WSGI, etc) such that the code used CGI interface and FastCGI did that but with separate server.
52. tacker2000 ◴[] No.43659795[source]
PHP-FPM is powering a huge chunk of the web, starting with the large amount of Wordpress sites and then much more…
53. assimpleaspossi ◴[] No.43659851{4}[source]
My biggest customer was a national restaurant chain that thought they should have it all in house. So far, a big mistake.

My second biggest customer went out of business. Which left us with a bunch of itty-bitty businesses that I'm just too tired to be chasing after.

54. at_a_remove ◴[] No.43664531{5}[source]
I think started a little earlier, back when every site had a cgi-bin directory.

And, yeah, so much ... cruft now, and I rarely hear reasons for the tradeoff, other than "should" and "It will be great."

And if it is so great, why did it go away?

replies(1): >>43665406 #
55. mxuribe ◴[] No.43665406{6}[source]
Thanks for making me feel good knowing that i'm not the only one feeling that there's too much cruft in some areas nowadays! :-)

Simiarly, i either hear no discussion about tradeoffs, or they tend to be so vauge or weak...and it eventually boils down to "Ain't no body got time to figure out the 'right way', and this new $thing is popular, so this new way is the right way everyone...".

As far as why it went away, i frankly don;'t know...but i imagine for the same reasons other good stuff goes away: maybe contributors stopped working on it, or there is money to be made in the new ways, or the zeitgeist of the new way (due to management consultants whispering in the ear of IT senior leaders) takes over the attention of the everyday devs, etc. Then again, i suppose if one were to preserve certain local infra. in a way to use old stuff, i guess one may still be able to run things the old way...but that's an uphill battle, and likely not worth it.

56. myaccountonhn ◴[] No.43671603[source]
I just this week implemented an SCGI server, its even easier than FastCGI and the performance difference is arguably negligible.

The parser ended up being 30 lines of code.

57. myaccountonhn ◴[] No.43671651[source]
It's very easy to implement. So if you're using some niche language and want to get a web server up and running, then you can implement an SCGI (or fastcgi) parser in like 20 lines of code. Its much harder to implement the full HTTP spec.
58. smittywerben ◴[] No.43672010{4}[source]
Just pip uninstall pep 206 interface then connect execute this remote code repo that the community uses into your supply chain and pip install pep 206 that's the secure way to run the http test server in production. Like just break the source code that works by removing it because "just parse the syntax tree to override it that's the correct way" just pip install the cgi interface specification from the back alley it's better than paying Oracle to keep your code working because you can just override the interface the right way then lets pull out lincoln logs out because nobody can figure out how the fuck to install the real webserver or parse the AST of the test server to use their per-process GIL locked python interpreter and then when they've almost fixed that lets pull out the http test server too then we're ready to write some more code!

Signed, almost dead battery

59. nwmcsween ◴[] No.43676550[source]
Why "Remember"? php-fpm is probably powering millions of sites right now.