And this is why I expect HTTP/2 and HTTP/3 to be much more robust in the long term: the implementations are harder to write, and you won’t get anywhere without reading at least a some spec, whereas HTTP/1 is deceptively simple with therefore a lot of badly incorrect implementations, often with corresponding security problems.
I wish there were a standard for streaming (headphones could connect to your network via WPS, and stream some canonical URL with no configuration needed).
> This is not the same as HTTP pipelining, which I will not discuss, out of spite.
That is cause HTTP pipelining was and is a mistake and is responsible for a ton of http request smuggling vulnerabilities because the http 1.1 protocol has no framing.
Isn't "HTTP pipelining" just normal usage of HTTP/1.1?
Anyone that doesn't support this is broken. My own code definitely does not wait for responses before sending more requests, that's just basic usage of TCP.
> We're not done with our request payload yet! We sent:
> Host: neverssl.com
> This is actually a requirement for HTTP/1.1, and was one of its big selling points compared to, uh...
> AhAH! Drew yourself into a corner didn't you.
> ...Gopher? I guess?
I feel like the author must know this.. HTTP/1.0 supported but didn't require the Host header and thus HTTP/1.1 allowed consistent name-based virtual hosting on web servers.
I did appreciate the simple natures of the early protocols, although it is hard to argue against the many improvements in newer protocols. It was so easy to use nc to test SMTP and HTTP in particular.
I did enjoy the article's notes on the protocols however the huge sections of code snippets lost my attention midway.
That was an excellent, well-written, well-thought out, well presented, interesting, humorous, enjoyable read. Coincidentally I recently did a Rust crash course so it all made perfect sense - I am not an IT pro. Anyhows, thanks.
I'd like to ask you what crash course on Rust did you take, as there are quite a few out there, and it would help if someone recommends a certain course.
After the string of positive adjectives, I was expecting the second half of your comment to take a sharp turn into cynicism. Thank you for subverting my expectations by not subverting my expectations!
I will piggyback on your comment as I totally agree. I am amazed at the amount of work that must go into not just writing the article itself but all the implementations along the way. Really amazing job!
Since playing with QUIC, I've lost all interest in learning HTTP/2, it feels like something already outdated that we're collectively going to skip over soon.
I tend to agree with you there, however the thing I'm replacing does HTTP/2, and HTTP/3 is yet another can of worms as far as "production multitenant deployment" goes, so, that's what my life is right now.
As far as learning goes, I do think HTTP/2 is interesting as a step towards understanding HTTP/3 better, because a lot of the concepts are refined: HPACK evolves into QPACK, flow control still exists but is neatly separated into QUIC, I've only taken a cursory look at H3 so far but it seems like a logical progression that I'm excited to dig into deeper, after I've gotten a lot more sleep.
FWIW HTTP/3 very much builds upon / reframes HTTP/2’s semantics, so it might be useful to get a handle on /2, as I’m not sure all the /3 documentation will frame it in /1.1 terms.
HTTP1 is definitely outdated (it was expeditiously replaced by HTTP 1.1), but I'd argue ignoring HTTP/2 might be more like ignoring IPv4 because we have IPv6 now
What a great overall site. Hopping down the links I found the section on files with code examples in JS, Rust and C, plus strace, really the best short explanation I've ever found online.
This is awesome, didn't read all of it yet, but I will for sure, I use HTTP way too much and too often to ignore some of these underlying concepts, and when I try to look it up, there's always way too much abstraction and the claims aren't proven to me with a simple example, and this article is full of simple examples. Thanks Amos!
> Where every line ends with \r\n, also known as CRLF, for Carriage Return + Line Feed, that's right, HTTP is based on teletypes, which are just remote typewriters
Does it need to be pointed out that this is complete bullshit?
Well, I've definitely seen a lot of people claim (generally not word-for-word) that using a pointlessly-overlong encoding of newline that exists to cater to the design deficiencies of hardware from the nineteen-sixties is not bullshit, so... maybe? But only for rather mushy values of "need".
It's not totally right, but it's not totally wrong, either, kind of like the way the dimensions of the space shuttle booster are directly affected by the size of a pair of Roman war horses' asses.
CRLF was used verily heavily and thus got baked into a lot of different places. Namely, it conveniently sidesteps the ambiguity of "some systems use CR, others use LF" by just putting both in, and since they are whitespace, there's not much downside other than the extra byte.
Beyond that, there are many other clear and obvious connections between Hypertext Transfer Protocol and teletype machines. Many early web browsers were expected to be teletype machines [0]. So while it might be a bit of a stretch, I'd say this is far from "complete bullshit".
Is HTTP always the same protocol as HTTPS - given the same version - and ignoring the encryption from TLS?
Theoretically yes, but in practice?
I've done my share of nc testing even simpler protocols than HTTP/1.1
For some reason the migration to HTTPS scared me despite the security assurances. I could not see anything useful in wireshark anymore. I now had to trust one more layer of abstraction.
> Is HTTP always the same protocol as HTTPS - given the same version - and ignoring the encryption from TLS?
> Theoretically yes, but in practice?
Yes, that's the whole point of encapsulation. The protocol is blissfully unaware of encryption and doesn't even have to be. It has no STARTTLS mechanism either.
Your HTTPS traffic consists of a TCP handshake to establishes a TCP connection, a TLS handshake across that TCP connection to exchange keys and establish a TLS session, and the exact, same HTTP request/response traffic, inside the encrypted/authenticated TLS session.
The wonderful magic of solving a problem by layering/encapsulating.
> I could not see anything useful in wireshark anymore
For 1.1 and 2, the byte stream is the same for TCP vs TLS over TCP. For 3, it uses one stream per request over a QUIC connection which is always encrypted.
As far as i can tell the host header is pointless, because if it's ssl/tls you won't be able to read it and route it. That's what sni is for. If you aren't tls then you don't need it, unless you hit the server as an ip. But then why would you do that?
It's for one server/IP serving multiple hostnames. For instance, the same physical server at 45.76.26.79 serves both www.lukeshu.com and git.lukeshu.com with the same instance of Nginx. Once Nginx decrypts the request, it needs to know which `server { … }` block to use to generate the reply.
With TLS+SNI, this is redundant to the name from SNI. But we had TLS long before we had SNI, and we had HTTP long before we had TLS, and both of those scenarios need the `Host` header.
My whole thing is that I'm teaching Rust /while/ solving interesting, real-world problems (instead of looking at artificial code samples), so, if someone wants to write the equivalent article with Python, they should! I won't.
Joker_vD|3 years ago
As someone who had to write a couple of proxy servers, I can't express how so sadly accurate it is.
chrismorgan|3 years ago
SamuelAdams|3 years ago
The initial problem is usually easy to solve for, it’s all the edge cases and other details that makes something complex.
unknown|3 years ago
[deleted]
cookiengineer|3 years ago
Chunked transfer/content encoding problems still give me nightmares...
Donckele|3 years ago
LOL, yes same here. Can’t wait for Bluetooths b̶a̶l̶l̶s̶ baggage to be chopped.
danuker|3 years ago
I installed a web server on my phone and send files this way much faster (and Android -> Apple works):
https://f-droid.org/en/packages/net.basov.lws.fdroid/
I wish there were a standard for streaming (headphones could connect to your network via WPS, and stream some canonical URL with no configuration needed).
leinadho|3 years ago
X-Istence|3 years ago
That is cause HTTP pipelining was and is a mistake and is responsible for a ton of http request smuggling vulnerabilities because the http 1.1 protocol has no framing.
No browser supports it anymore, thankfully.
mgaunard|3 years ago
Anyone that doesn't support this is broken. My own code definitely does not wait for responses before sending more requests, that's just basic usage of TCP.
yfiapo|3 years ago
> Host: neverssl.com
> This is actually a requirement for HTTP/1.1, and was one of its big selling points compared to, uh...
> AhAH! Drew yourself into a corner didn't you.
> ...Gopher? I guess?
I feel like the author must know this.. HTTP/1.0 supported but didn't require the Host header and thus HTTP/1.1 allowed consistent name-based virtual hosting on web servers.
I did appreciate the simple natures of the early protocols, although it is hard to argue against the many improvements in newer protocols. It was so easy to use nc to test SMTP and HTTP in particular.
I did enjoy the article's notes on the protocols however the huge sections of code snippets lost my attention midway.
proto_lambda|3 years ago
The author does know this, it's a reference to a couple paragraphs above:
> [...] and the HTTP protocol version, which is a fixed string which is always set to HTTP/1.1 and nothing else.
> (cool bear) But what ab-
> IT'S SET TO HTTP/1.1 AND NOTHING ELSE.
I_complete_me|3 years ago
pohuing|3 years ago
mihneawalker|3 years ago
becquerel|3 years ago
q-base|3 years ago
unknown|3 years ago
[deleted]
Andys|3 years ago
Since playing with QUIC, I've lost all interest in learning HTTP/2, it feels like something already outdated that we're collectively going to skip over soon.
fasterthanlime|3 years ago
As far as learning goes, I do think HTTP/2 is interesting as a step towards understanding HTTP/3 better, because a lot of the concepts are refined: HPACK evolves into QPACK, flow control still exists but is neatly separated into QUIC, I've only taken a cursory look at H3 so far but it seems like a logical progression that I'm excited to dig into deeper, after I've gotten a lot more sleep.
masklinn|3 years ago
pcthrowaway|3 years ago
Joker_vD|3 years ago
Icathian|3 years ago
Plus, you know, just an awesome dev who knows his stuff. Huge fan.
mcspiff|3 years ago
juped|3 years ago
stevewatson301|3 years ago
photochemsyn|3 years ago
https://fasterthanli.me/series/reading-files-the-hard-way/pa...
rpigab|3 years ago
est|3 years ago
fasterthanlime|3 years ago
For TLS, I recommend The Illustrated TLS 1.3 Connection (Every byte explained and reproduced): https://tls13.xargs.org/
antonvs|3 years ago
Does it need to be pointed out that this is complete bullshit?
a1369209993|3 years ago
kortex|3 years ago
CRLF was used verily heavily and thus got baked into a lot of different places. Namely, it conveniently sidesteps the ambiguity of "some systems use CR, others use LF" by just putting both in, and since they are whitespace, there's not much downside other than the extra byte.
Beyond that, there are many other clear and obvious connections between Hypertext Transfer Protocol and teletype machines. Many early web browsers were expected to be teletype machines [0]. So while it might be a bit of a stretch, I'd say this is far from "complete bullshit".
[0] - http://info.cern.ch/hypertext/WWW/Proposal.html#:~:text=it%2...
tripa|3 years ago
Which part of it do you think is wrong?
unknown|3 years ago
[deleted]
sireat|3 years ago
Theoretically yes, but in practice?
I've done my share of nc testing even simpler protocols than HTTP/1.1
For some reason the migration to HTTPS scared me despite the security assurances. I could not see anything useful in wireshark anymore. I now had to trust one more layer of abstraction.
st_goliath|3 years ago
> Theoretically yes, but in practice?
Yes, that's the whole point of encapsulation. The protocol is blissfully unaware of encryption and doesn't even have to be. It has no STARTTLS mechanism either.
Your HTTPS traffic consists of a TCP handshake to establishes a TCP connection, a TLS handshake across that TCP connection to exchange keys and establish a TLS session, and the exact, same HTTP request/response traffic, inside the encrypted/authenticated TLS session.
The wonderful magic of solving a problem by layering/encapsulating.
> I could not see anything useful in wireshark anymore
Wireshark supports importing private keys for that, see: https://wiki.wireshark.org/TLS
dochtman|3 years ago
Too|3 years ago
mannyv|3 years ago
LukeShu|3 years ago
With TLS+SNI, this is redundant to the name from SNI. But we had TLS long before we had SNI, and we had HTTP long before we had TLS, and both of those scenarios need the `Host` header.
Too|3 years ago
mahdi7d1|3 years ago
mannyv|3 years ago
mannyv|3 years ago
mustak_im|3 years ago
danesparza|3 years ago
stefs|3 years ago
tinglymintyfrsh|3 years ago
mlindner|3 years ago
fasterthanlime|3 years ago
tomcam|3 years ago
cph123|3 years ago
fasterthanlime|3 years ago
rk06|3 years ago
tmountain|3 years ago
raydiatian|3 years ago
[deleted]
unknown|3 years ago
[deleted]