“I Could Rewrite Curl”
daniel.haxx.se
daniel.haxx.se
Curl though, is a very wide breadth project. It currently supports the following protocols: DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP.
Each one of those is a massive undertaking of protocol/spec management, edge case handling, cross compatibility, hacks, and much much more to make them work. Then to put a stable C api on top of it all to be a cross language toolkit is a MASSIVE undertaking.
But, again, the "idiots" who posted those comments, aren't talking about any of this. Perhaps they shouldn't care to. Most folks I know don't even know about the other protocols curl supports and have only interfaced with curl through its http. Frankly there are nicer http cli's out there with less code that _can_ be written in a weekend (assuming they piggy back on a http lib).
What Daniel Stenberg achieved is giving the world a fantastic, reliable, cross protocol, cross platform and cross language network library that can be used as the foundation for many projects. I'm sure few of those cited would claim they could do that.
Woah. This is genuienly impressive.
The simplest solution would have been to give up the instant I started reading the catched traffic. I gave up after about 40 minutes of trying to figure out where to start.
> "Most folks I know don't even know about the other protocols curl supports and have only interfaced with curl through its http."
Just curious if you could elaborate on this one specifically and why you found it especially interesting.
(this is actually something I'm very worried about, it used to be easy to cobble together a very basic HTTP client, not anymore with the new HTTP protocol versions, and all the bells and whistles).
As a silver lining: I have been less worried recently seeing that most of the adoption of http/2-3 (at least their odd features) have been at the edge. Most developers are still writing http/1 endpoints and leaving the edge to optionally up-convert them for transport efficiency.
Using the multi interface it's relatively trivial (a few hundred lines of C) to fetch using hundreds or thousands of concurrent connections. There's even some courtesy opts for rate limiting per host.
It's so good he/they built c-ares for asynchronous DNS lookups, IIRC something that wasn't so readily available in years gone by.
You're surprised by him being salty? I can't imagine what it's like to be on the receiving end of the water torture of people continually belittling the work you have done over 20 years and given to the community.
One of which, curl(1), is a constant ass-and-life saver for me personally and professionally. Of course the library itself ends up being used by me as well (in C, ++ and tcl). curl to me is in the league of sqlite aka "absolutely gorgeous and more often than not all you need"
100%, that's why we see so many smaller projects pop up (on GitHub and the like) that support basically just this. No shade to those projects, improving the UI for this subset is a worthy cause, it's just not anything near cURL.
I'm no expert on open source management but Daniel has for years been a positive and steady force working on curl.
This is him publishing the direct criticisms he's receiving as "thanks" for his efforts and it guts me he's got to put up with these ignorant comments.
I can see the advantages of standardizing on a complex, powerful tool for simple use cases. For one thing, it may be the only way to standardize: simple versions are too easy to write, and therefore you get dozens of competitors, none of whom are popular enough to shake out their edge case bugs.
It's also nice not to have to find, install, and learn a new tool when you stray over that 90% boundary.
With software dependencies, I think the advantages of small, simple libraries win out over generality. Supporting powerful use cases makes an API more complex and often means that simple, 90% use cases require weird incantations to make them work. Here I think of the times I've had to get into the guts of Jackson despite never doing anything remotely exotic with JSON. The 95% of your codebase that can be simple should be simple, so you can devote your attention to the things that need to be complex.
But nobody is forced to use curl? People use it because it’s convenient, shoot them selves in the foot and then lash out at the author the tool for their own choices. Where’s the fault?
I like curl, but this isn't true. When you're SSH-ing onto a box, you often don't have permissions to install your favorite CLI tool, and even if you do have said permissions it's inconvenient to have to install it each time you SSH onto the box (not a major inconvenience, mind you). Moreover, in many cases you need to run a script or some other software that depends directly on curl.
In general the "nobody is forced to use it" arguments rarely pan out (I remember this was a canned argument from C++ folks circa 2011: "C++ is the best language because it has every feature and if you don't like some features, you aren't forced to use them!").
If you want to use something else. You have to install it on the host. Every box comes with bash, but we still install other languages and frameworks on the host so we can run out applications with tools that make sense.
If you want a different tool, make it part of your default install.
Doesn't stop anyone else from using a power saw or charging batteries. If you need propane, bring it.
If you don't get to choose anything on the host, why are you concerned what other people use? If you install your own apps, add that lib you want?
Counter-example: Jenkins. It does what you ask of it, its base install is "naked" and only contains the minimum functionality in the core.
Everything then becomes a plugin. Git. GitHub. Branch for multi-branch pipelines. Credentials management. And on and on and on.
Now you have stay on top of maintaining the plugins in addition to the core. Also, many plugins require other plugins so just to do some basic stuff like set up a multi-branch pipeline from a GitHub repo you're suddenly staring down the barrel of dozens and dozens of bespoke plugins with varying levels of quality and support.
A monolithic application like curl is a dream to me by comparison. Everything is tested in every release. Sub-components are kept up to date by the maintainer. No plugins fighting each other's plugins.
From afar it's easy to see the praise simplicity and modularization but honestly monoliths can be undervalued too.
For example, VSCode plugins are great because VSCode is thriving, and Emacs packages are a crapshoot because many of the programmers who wrote them have moved on. Eventually VSCode plugins will be like Emacs packages.
curl is a utility, like power.
you don't worry about electricity not being able to power your TV because it was designed for light bulbs, it just works.
Sad.
No surprise but curl can do that too!
If a project is only going to ever use http, why would I need to bundle in all of the others?
Genuinely curious what the advantages are
It also let's you do all this dynamically, so switching protocols on the fly is trivial.
> If a project is only going to ever use http, why would I need to bundle in all of the others?
Your project might only ever think to use http, but my project might appreciate having one client for any URL, instead of having to parse URLs myself and decide on separate clients based on a part of it.
Can anyone recommend a good alternative for the base case?
That said, I still will reach for cURL even when simpler options exist because it's ubiquitous. Same thing with Bash, grep, and sed.
I fall firmly into "those 98%" you mention.
Dlang's stdlib (only) implementation for making network requests is quite literally a direct "curl" wrapper:
https://dlang.org/phobos/std_net_curl.html
You've changed on my mind on this being an odd design decision.
Baking in libcurl for the user (or optionally allowing them to dynamically link) if they want networking was maybe the most sane/pragmatic choice you could have made for a new language.
We can't because modern software handles cases that those didn't. For example, rendering and editing text seems straightforward until you look closer. Text Rendering Hates You (https://gankra.github.io/blah/text-hates-you/) and Text Editing Hates You Too (https://lord.io/blog/2019/text-editing-hates-you-too/) are two amazing reads that analyze this in detail. They explain the hidden complexity to the vast majority of us who never knew. We simply slapped down a <textarea> or <EditText> and called it a day.
If we tried to reimplement this stuff from scratch, we would likely start with a simple implementation, then tack on bits when we tried to handle issues like right-to-left layouts, Unicode, emoji, anti-aliasing, text overlapping and so on. All this before getting into implementing features that Dennis Ritchie didn't have to, like supporting plugins, releasing on multiple operating systems, accessibility or even syntax highlighting. Problems already known to and tackled by existing text editors today.
If you look at work outside of your area of expertise and you feel like starting a sentence like "why don't you just ...", then reconsider. If the person you're talking to is halfway competent (they probably are), they've already considered what you're about to say. "Have you considered using less memory/CPU or removing this feature that I personally don't need?" Why yes, we have.
(This is from a post I wrote earlier - Software Isn’t Bloated - https://blog.nindalf.com/posts/software-isnt-bloated/)
One can write a lot of things in 100 lines if it doesn't have to meet higher standards than a basic chat app tutorial in the "getting started" section of a programming language.
I'd argue that even a basic chat app is massively complex, only that all the really complex parts have already been solved. I once tried to write one on the LOWEST level I could. Realized after a month that there were not enough hours left in my life to finish it.
[...] [my wife] was gone a month to California and I allocated a week each to the shell, to the operating system, the shell, the editor, and the assembler, to reproduce itself [...]
[1] https://www.princeton.edu/~hos/mike/transcripts/thompson.htm
Ah, darn. That'll teach me to comment without refreshing the page first. I refer you to the earlier DonHopkins post.
https://en.wikipedia.org/wiki/Collaborative_real-time_editor
>History of key products: The first instance of a collaborative real-time editor was demonstrated by Douglas Engelbart in 1968, in The Mother of All Demos. Widely available implementations of the concept took decades to appear.
https://news.ycombinator.com/item?id=21757797
Vis-à-vis mamelons, Ted Selker (who invented the Trackpoint) actually build a prototype Thinkpad keyboard with TWO Trackpoints, which he loved to show at his New Paradigms for Using Computers workshop at IBM Almaden Research Lab.
While I'm not sure if this video of the 1995 New Paradigms for Using Computers workshop actually shows a dual-nippled Thinkpad, it does include a great talk by Doug Engelbart (14:22), and quite a few other interesting people! (James Gosling of Sun Microsystems talks about capabilities of Sun's new web browser HotJava, at 24:36! A classic!)
https://www.youtube.com/watch?v=oD9NUWDCyHI
The multi-Trackpoint keyboard was extremely approachable and attractive, and everybody who saw them instantly wanted to get their hands on them and try them out! (But you had to keep them away from babies.) He made a lot of different prototypes over time, but unfortunately IBM never shipped a Thinkpad with two nipples.
That was because OS/2 (and every other contemporary operating system and window system and application) had no idea how to handle two cursors at the same time, so it would have required rewriting all the applications and gui toolkits and window systems from the ground up to support dual trackpoints.
The failure to inherently support multiple cursors by default was one of Doug Engelbart's major disappointments about mainstream non-collaborative user interfaces, because collaboration was the whole point of NLS/Augment, so multiple cursors weren't a feature so much as a symptom.
Bret Victor discussed it in a few words on Doug Engelbart that he wrote on the day of his death:
http://worrydream.com/Engelbart/
>Say you bring up his 1968 demo on YouTube and watch a bit. At one point, the face of a remote collaborator, Bill Paxton, appears on screen, and Engelbart and Paxton have a conversation.
>"Ah!", you say. "That's like Skype!"
>Then, Engelbart and Paxton start simultaneously working with the document on the screen.
>"Ah!", you say. "That's like screen sharing!"
>No. It is not like screen sharing at all.
>If you look closer, you'll notice that there are two individual mouse pointers. Engelbart and Paxton are each controlling their own pointer.
>"Okay," you say, "so they have separate mouse pointers, and when we screen share today, we have to fight over a single pointer. That's a trivial detail; it's still basically the same thing."
>No. It is not the same thing. At all. It misses the intent of the design, and for a research system, the intent matters most.
>Engelbart's vision, from the beginning, was collaborative. His vision was people working together in a shared intellectual space. His entire system was designed around that intent.
>From that perspective, separate pointers weren't a feature so much as a symptom. It was the only design that could have made any sense. It just fell out. The collaborators both have to point at information on the screen, in the same way that they would both point at information on a chalkboard. Obviously they need their own pointers.
>Likewise, for every aspect of Engelbart's system. The entire system was designed around a clear intent.
>Our screen sharing, on the other hand, is a bolted-on hack that doesn't alter the single-user design of our present computers. Our computers are fundamentally designed with a single-user assumption through-and-through, and simply mirroring a display remotely doesn't magically transform them into collaborative environments.
>If you attempt to make sense of Engelbart's design by drawing correspondences to our present-day systems, you will miss the point, because our present-day systems do not embody Engelbart's intent. Engelbart hated our present-day systems.
Arguably the only "single user" devices should be things like the mouse itself, as multiple people can see the same screen (and maybe even use the same keyboard).
Some games implemented this to allow two-player on the same machine - each would get a joystick or "their half" of the keyboard.
Given a program that supported multiple trackpoints, two people could use the two Trackpoints on each side of the keyboard, just like you describe with keys.
Now we have multitouch APIs on mobile devices, at least. But they're not a good match for supporting multi-mouse/trackpoint, since they only support tracking fingers while they're touching the screen, not pointing around without pressing like a mouse/trackpoint does.
This type of mentality is also rampant in the world of entrepreneurship - Theranos et.al
Sure, it's good to get new eyes on some problem, but it's the hubris that can kill.
You get development efforts with massive scope people brush off as nothing. I've worked with a lot of these sort of groups where someone entrepreneurial understands enough to think they can simplify and improve something. Then they get a developer, two, or small team that agree. They start the undertaking or even worse, do the work under contract for someone else where they have contractual deliverables. Some way in they start to realize just how shortsighted and cavalier they were about brushing off uncertainties they either knew or didn't know about. "It can't be that hard! It's just software, it's all virtual! We don't need a bunch of capital! We just need a little bit of math! ... "
All those uncertainties start to become quantities and they realize the absolute pit they dug themselves into. At that point they look for someone to swoop in and cleanup their mess. Usually it takes careful reading of the contract deliverables with liberal interpretation of what is stated and how those things can be minimally met. You really need people familiar with the types of software and systems involved and needed to achieve your goals to narrow down these uncertainties. If you don't then you're digging your own grave.
This is why I always try to look back as far as I can in a source's history to see how it started. It at least gives me a sense of the amount of work it takes to get from simple to mature.
I have a chunk of code for implementing pointers, cursors, button clicks, and drag-and-drop in games. It's some of the gnarliest code I've ever written. It's also some of the most resistent code to "good design patterns" I've ever seen. I've written it and tweaked it and rewritten it and thrown it away and started from scratch and it always comes out the same. When you're dealing with things that have to meet long-established user expectations, it's always going to be full of little edge cases that you can't abstract away.
We also saw this with COVID. Plenty of people with no knowledge in infectious disease stating that the public solution was stupid and wrong but instead the obvious, simple and effective solution would be to "just do ....".
Personally if that happens at work and somebody (often managers) tells us to solve a difficult problem by "why don't you just..." I usually tell them the code is available and they "can just do it" themselves. So far I have never had any takers.
I run into this problem with my manager a lot, who knows just enough to get himself in trouble. There's probably a term for it, but I call it the "complexity trap". He sees a problem, thinks he has an "aha!" moment, and tells me about a simple solution, and asks me to implement it. This solution, of course, disregards most of the complexity inherent in the problem.
Complex problems require equally complex solutions, and if the solution is simple, it disregards the complexity of the problem, either shoveling down the ladder of abstraction, or hoping for some future state where it's not as complex.
It has the effect of short circuiting the complexity of the problem, because it defines all the corner cases in a compact form.
Interface with sloppy spaghetti systems can usually be hidden away at the edges of the system. The main problem is that less experienced engineers invariably come in and say, “A ha! I have a special corner case that doesn’t fit the abstraction.” and then try to add copy paste methods, boundary violations, and so on.
As long as there’s someone that diligently guards against such things, it works out OK. Results vary wildly after those people leave.
HP printer drivers are a famous example of the sort of complexity reduction I’m talking about. They used to copy the entire source tree for each printer (font rasterizer, dithering algorithms, and all), then assign a full time team to maintain it.
Eventually they had many thousands of full time engineers maintaining the result, and print quality was still terrible across the product line.
The open source drivers reverse engineered the printers, and factored out as much common logic as possible. The printer specific code was then reduced to just implementing the wire protocol and device geometry stuff. At that point, they had better output than HP, with 1% the developer resources.
Someone at HP did the same thing internally, reimplemented all the drivers in a unified way, and was promptly promoted to the executive team.
I agree, though this is generally limited to singular problems, and usually becomes harder to implement the higher up the abstraction train you go. I've found this especially true in business logic, where you don't know what the requirements or even end goal is; by the time you're ready to apply some nice mathematical based optimizations at a high abstraction level, doing so often requires a lot of work exposing all of the information you need from lower abstraction layers. All comes down to planning.
> As long as there’s someone that diligently guards against such things, it works out OK. Results vary wildly after those people leave.
This is specifically why I mentioned my manager haha, who will both come up with crazy edge cases that in many cases don't even apply, and will come up with "aha!" solutions to problems that ignore major edge cases. Perks of not working for a software company.
Very interesting history on the HP printer drivers, thanks for sharing that. I do remember some of the evolution that they went through, from the Linux perspective, and it was amazing how that tangled mess just started to magically work, circa 2008 if I remember right.
https://www.joelonsoftware.com/2000/04/06/things-you-should-...
"Back to that two page function. Yes, I know, it’s just a simple function to display a window, but it has grown little hairs and stuff on it and nobody knows why. Well, I’ll tell you why: those are bug fixes. One of them fixes that bug that Nancy had when she tried to install the thing on a computer that didn’t have Internet Explorer. Another one fixes that bug that occurs in low memory conditions. Another one fixes that bug that occurred when the file is on a floppy disk and the user yanks out the disk in the middle. That LoadLibrary call is ugly but it makes the code work on old versions of Windows 95."
Here's the magic in that trick: we have, collectively, amassed a heap of knowledge on HTTP and its behavior in the wild; this was made possible by curl, in the first place. Once this is handwaved away, of course it's easy to do. "Look at me, [standing on the shoulders of giants,] I have a really great view from up here!"
(*small print: and this is speaking about the happy path, where client, its stack, network, server stack, and server all align perfectly; this happens pretty much never)
Most time - when reimplementing stuff - is not spent coding, or even debugging, but on research.
Every so often (less so in recent years) I come across a bad homespun implementation of an HTTP client embedded in a larger project. Usually, a few lines of code to open a socket and POST some data to a hard coded URL. I always replace these with curl, usually over the objections of the original programmer.
The problem with HTTP (v1) is that it seems very simple to write a cut down client. But your simple client better handle proxies, various encodings, chunked bodies, redirects, HTTPs (with all the machinery that implies), and a whole host of annoying little features that the client is not in control of.
"But I don't need to implement talking through a proxy, we don't use one"
You don't use one now, but in 6 months you might. Or your client's might install one without your knowledge.
It is actually pretty simple to write an HTTP server (I wouldn't advise it) because the server controls a lot of the conversation. But clients are best left to either the OS or curl.
Self-promotion time: https://sheep.horse/2019/3/using_libcurl_effectively_and_saf...
What usually trips me up is the syntax: `curl -O http://host/file` (goes to stdout without -O) instead of `wget http://host/file` (goes to file without -O)
Of course now I feel really icky if im ever forced to use wget. And curl’s feature of defaulting to stdout is of course a perfect thing and makes way more sense than the alternative (for many reasons).
Too many people in our field just take the first thing that works and they won't bother to actually look at it.
I could totally see myself doing this
5 years ago I was partner in a startup, we got some money from government right about the time I said I have to take a few months off to do consulting and make some money, my partner said I want to use money to make app I said no for various reasons but he went ahead and did app.
So I was helping them to do the app a couple hours every night - while consulting 8+ hours a day. Anyway the guy making app was using postman, I'd never used postman. He had a problem with the a part of the API not working.
I sent him a curl request to post a two line json document to the api and showed it got the correct response back.
His response - I'm not a curl expert or anything, it would really help me out if you downloaded and installed postman and tried to make it work!
My response - I'm not a curl expert or anything, I showed you it worked in curl because that is basically the default and should establish it is possible to do. You figure out how to do it in your tool.
I'm a fan of postman for some things, it sure is easier to modify and re-run http requests over and over in some cases. But on the whole if you're trying to debug an issue, dropping down to curl solves so many problems and is pretty easy to share with anyone no matter their OS for the most part.
I don't need "do-everything" in cURL sense
Insomnia/Postmans works for all of my cases
"pre-installed" - so what? I do develop on my own PC, not someone's else. There's 0 problem with installing those tools at first install on my PC.
If I will have to use cURL, then I will use it, but I don't need it day2day.
>scriptable tool to interact with web APIs.
That's definitely good thing, but $my_lang has decent HTTP Wrappers
Additionally both of those tools generate cURL.
On curl: https://hackerone.com/curl?type=team says "All rewards in our program are graciously donated by our sponsors." with a link to https://curl.se/sponsors.html, and that probably works well for a large project like curl.
See also: The Door Problem - https://lizengland.com/blog/2014/04/the-door-problem/
alias mycurl='curl'
/s* redis - I can do it, listen socket, serve from hashmap
* uber - how come this app is so huge, I can make it in 2 weekends (google map + api + database)
* cURL - easy, use my fancy library (it already implements HTTP stack) and rewrite it
....
import pycurlI bet at least a subset of people who think they could reimplement curl easily, think of curl as a CLI tool to make HTTP requests. It's just a little bit of python/requests or node/fetch code to cover some basics for that. I think these people simply aren't aware that their programming language's built-in libraries often call in to libcurl for the dirty work.
PycURL is a Python interface to libcurl.
The people saying they could rewrite it are really saying "I could rewrite Curl (using an an existing HTTP library) so that 99.99% of the use cases work" which is probably true.
If you think you can build a curl replacement in 100 lines of code, do it, and open source it so a other randos on the Internet can complain about it.
And then there are those who use all the API features and realize it's a complex program.
But the missing link is that even the first use case has many complex edge-cases that aren't obvious at first.
curl is for weird stuff like "POST" requests or other protocols.
At first it was simple. I was making Windows apps and Windows has an API for HTTP requests. Just call wininet with the url, and it handles everything. No need to use someone's library if there is a standard OS API. And it is fully integrated in Windows, you get the default proxy settings and user-defined HTTPS certificates. It even shares cookies with the internet explorer (which I did not want, so I wrote my own cookie parser)
Then I made a linux port. Suddenly there is no API. But I also avoid C, since it is unsafe, while Delphi/Pascal has memory safe strings and arrays. So I needed a HTTP Pascal library. There are several libraries, which also support other protocols I have never heard of. Then I used the synapse library. It is really causing a lot of problems. Incomplete cookie handling, no gzip encoding, OpenSSL messing everything up...
Then I made an Android port. The standard stable system library was Apache HttpComponents, so I use that. Shortly after, Google makes a new Android version, and removes Apache HttpComponents. Then I had to find a new library.
In hindsight all the porting were useless projects. I should have told people to use WINE and be done with it. A stable API is much better than a library. Or write my own HTTP client from the start, which would have been much easier than switching libraries all the time. Especially if I have to implement half of it (header parsing, OpenSSL interfacing) anyways when the libraries do not work properly
Many employers let you expense $50-100/month without much effort so get a handful of friends and it has a bigger impact than one corporate contributor.
[0] Twitter, Facebook, etc...
I sometimes think this but then I remember all the edge-cases in even the most basic real world code.
And even that is not as straightforward as one might think. I did it it C, Unix, TCP sockets, nothing unusual, but when you start putting significant load, you start getting errors left and right and you have to handle them properly. These are all documented, but easy to overlook.
Now that one is actually tricky. I'd probably enjoy a mediocre amateur production more than a mediocre Hollywood production. It's a bit like the uncanny valley idea - it's easier to look at something meh than at something you know is a bit off from being good.
Once one has gotten burned sufficiently by undocumented convoluted code I think there's an understanding that starts forming on how to make choices in libraries and structuring code. The problem is devs that jump around from greenfield to greenfield project and never get to experience that pain.
https://www.bitquabit.com/post/one-which-i-call-out-hacker-n...
Of all the libraries I have ever used, Curl is the one I used the most and found the most useful. I have never had the idea to rewrite it or even use another library to replace it.
I'm not afraid to say that I love Curl!
But on a second look I'm quite certain it wasn't the wording or the sentiment, but the beige background color that I hadn't consciously noticed before.
Apologies for all the ego driven comments, people we should relax and keep doing fun and useful stuff.
I have, for personal gratification, attempted (with varied success) to reimplement several utilities. The experiences were quite eye-opening, seeing how well designed the "standard" utilities are, and identifying new ways to improve my code.
Not everything needs to come through the browser.
It just happens to get a free pass over port 80.
It's a short-term gain, but quite inefficient in the long run. ZeroMQ is a perfectly valid replacement for HTTP in internal networks. There's no reason for everything to be human readable.
Simply filling the space with a solid color is not only easier but infinitely stronger.
https://fs.blog/2020/03/chestertons-fence/
tl;dr Don't remove something until you understand why it's there. Your needs or experience are not everyone's.
[0] https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
[1] http://johnsalvatier.org/blog/2017/reality-has-a-surprising-...
(Unless you're saying "let's pretend to reimplement curl by wrapping around curl behind the scenes," which is delightfully tautological.)
Extra two days just for good measure.
Shameless plug: This kind of posts was the reason I wrote about it recently too [1]
1 - https://world.hey.com/joaoqalves/i-could-build-this-during-t...
I never used Curl or looked at the source code, I don't know about the specifics, but rewriting a simpler copycat from scratch is not always a bad idea.
I've done that a few times, to prove a point or because the original was bad and too difficult to maintain.
Ongoing maintenance of this nature is something often ignored by the "I could rewrite that, easy" folks.
Which is the exact problem of "I could rewrite this in a weekend!" scenario with curl, right?
Writing an HTTP 1 client in a weekend is doable and Rust is probably a better language today than C is (with some caveats obviously). Is having that opinion enough to to be publicly humiliated on Mr Stenberg's blog, I sure hope not.
What is the level of clout at which point you should be forbidden from commenting on criticism people direct at you on public forums?