WEBVTT

1
00:00:01.200 --> 00:00:08.663
The last film said every part of a page is a URL, fetched over HTTP, with a label.

2
00:00:08.967 --> 00:00:12.042
This time, open the envelope.

3
00:00:12.242 --> 00:00:17.279
Every HTTP message has three parts, and only three.

4
00:00:17.362 --> 00:00:18.719
A first line.

5
00:00:18.802 --> 00:00:20.042
Some headers.

6
00:00:20.125 --> 00:00:23.316
And a body, which may be empty.

7
00:00:23.516 --> 00:00:30.852
In a request, the first line says what you want: a method, a path, and the protocol version.

8
00:00:31.062 --> 00:00:36.448
GET /image.html.

9
00:00:36.648 --> 00:00:41.580
In a response, the first line says how it went, with a status code.

10
00:00:41.605 --> 00:00:42.730
200.

11
00:00:42.941 --> 00:00:45.121
404.

12
00:00:45.321 --> 00:00:49.313
Headers are name and value pairs, one per line.

13
00:00:49.454 --> 00:00:51.391
Then a blank line.

14
00:00:51.416 --> 00:00:53.017
Then the body.

15
00:00:53.100 --> 00:00:55.931
That is the whole format.

16
00:00:56.131 --> 00:01:01.075
Call it the Law of Three: three things in, three things out.

17
00:01:01.286 --> 00:01:07.205
Learn those three parts and you can read any conversation on the web.

18
00:01:07.405 --> 00:01:17.260
Fun fact: HTTP/2 and HTTP/3 pack those parts into binary frames to move them faster.

19
00:01:17.564 --> 00:01:22.473
The three parts, and what they mean, are unchanged.

20
00:01:23.173 --> 00:01:28.152
Ask Demo Company for a page, and the body is HTML.

21
00:01:28.293 --> 00:01:32.413
Ask for the cat photo, and the request looks the same.

22
00:01:32.624 --> 00:01:35.222
Only the path changed.

23
00:01:35.422 --> 00:01:38.671
The response has the same three parts too.

24
00:01:38.754 --> 00:01:40.157
A status line.

25
00:01:40.368 --> 00:01:45.370
Headers, including Content-Type: image/webp.

26
00:01:45.581 --> 00:01:51.047
And a body of forty-two thousand bytes that mean nothing to a human.

27
00:01:51.247 --> 00:01:54.242
HTTP never looks inside the body.

28
00:01:54.242 --> 00:01:57.294
It moves the bytes and carries the label.

29
00:01:57.505 --> 00:02:06.176
That indifference is why one protocol can deliver pages, pictures, fonts, video, and data.

30
00:02:06.376 --> 00:02:08.940
Even failure has the same shape.

31
00:02:09.244 --> 00:02:15.987
Ask for an image that isn't there, and you get a 404 first line, headers, and a body.

32
00:02:16.384 --> 00:02:22.233
The body is a short text message, sent from a URL that ends in .webp.

33
00:02:22.433 --> 00:02:24.892
The address promised a picture.

34
00:02:25.103 --> 00:02:26.982
The label says text.

35
00:02:27.007 --> 00:02:30.071
The browser believes the label.

36
00:02:30.771 --> 00:02:32.673
So who decides the label?

37
00:02:32.814 --> 00:02:36.737
The server does, and it has two ways to do it.

38
00:02:36.936 --> 00:02:41.392
For a file on disk, the server looks up the file's extension in a table.

39
00:02:41.534 --> 00:02:46.640
.html maps to text/html.

40
00:02:46.735 --> 00:02:51.377
.css maps to text/css.

41
00:02:51.518 --> 00:02:54.697
That is the only moment the extension matters.

42
00:02:54.898 --> 00:02:58.240
For a program, there is no file to look up.

43
00:02:58.544 --> 00:03:02.628
The code that builds the response has to state the type itself.

44
00:03:02.770 --> 00:03:12.474
A URL can end in .php, or in nothing at all, and still answer with HTML, JSON, or an image.

45
00:03:12.673 --> 00:03:16.491
So you can't judge a response by its URL.

46
00:03:16.702 --> 00:03:21.054
The extension is a note the server left for itself.

47
00:03:21.754 --> 00:03:23.403
Now break it on purpose.

48
00:03:23.403 --> 00:03:27.813
Take one HTML file and serve it three ways.

49
00:03:28.012 --> 00:03:33.014
Labeled text/html, the browser renders a page.

50
00:03:33.016 --> 00:03:37.681
Labeled text/plain, it shows you the source, tags and all.

51
00:03:37.788 --> 00:03:45.216
Labeled application/octet-stream, which just means bytes, it offers to download the file.

52
00:03:45.416 --> 00:03:47.875
Same bytes, three outcomes.

53
00:03:47.901 --> 00:03:50.406
Nothing in the file changed.

54
00:03:50.607 --> 00:03:55.702
Leave the label off, and the browser guesses from the first few bytes.

55
00:03:55.727 --> 00:04:01.031
That's sniffing, and a guess is something an attacker can steer.

56
00:04:01.231 --> 00:04:07.081
So servers send one more header, X-Content-Type-Options: nosniff.

57
00:04:07.477 --> 00:04:14.488
With it, a script or a stylesheet that carries the wrong label is refused outright.

58
00:04:14.688 --> 00:04:17.774
One more header can overrule the type.

59
00:04:17.916 --> 00:04:25.112
Content-Disposition: attachment says save this, don't show it, whatever it is.

60
00:04:25.811 --> 00:04:28.758
The law runs in both directions.

61
00:04:28.841 --> 00:04:35.213
When you submit a form, the browser builds a request with the same three parts.

62
00:04:35.414 --> 00:04:38.059
The first line says POST.

63
00:04:38.200 --> 00:04:41.774
A header labels the body as form data.

64
00:04:41.858 --> 00:04:45.095
And the body holds what you typed.

65
00:04:45.295 --> 00:04:54.976
When a script asks an API for data, the answer comes back the same way, labeled application/json.

66
00:04:55.175 --> 00:05:00.758
A request can even say which labels it would like, with the Accept header.

67
00:05:01.061 --> 00:05:08.478
One URL can then answer with HTML for a browser and JSON for a program.

68
00:05:09.179 --> 00:05:11.348
Here is the part people miss.

69
00:05:11.489 --> 00:05:14.309
None of these lists is closed.

70
00:05:14.508 --> 00:05:16.840
You can mint your own media type.

71
00:05:17.051 --> 00:05:23.701
A whole family of names is set aside for it, starting with application/vnd.

72
00:05:24.005 --> 00:05:30.412
Label your responses with it, and any program that knows the name knows what to do.

73
00:05:30.612 --> 00:05:32.921
The address side is open too.

74
00:05:33.131 --> 00:05:42.522
A native app registers a URL scheme with the operating system, and from then on a link with that scheme opens the app.

75
00:05:42.919 --> 00:05:46.051
That's all a Spotify link is doing.

76
00:05:46.252 --> 00:05:50.232
A web page can do the same thing in Chrome and Firefox.

77
00:05:50.374 --> 00:05:57.047
One call, registerProtocolHandler, asks the browser to send a scheme to your site.

78
00:05:57.351 --> 00:06:02.899
Custom ones start with web+, and the user has to say yes.

79
00:06:03.098 --> 00:06:07.984
An address, a label, and something registered to handle it.

80
00:06:08.195 --> 00:06:15.658
Anyone can add to all three, which is how the web keeps growing without asking permission.

81
00:06:16.359 --> 00:06:20.769
So when something on a page looks wrong, don't start with the code.

82
00:06:20.980 --> 00:06:23.068
Read the conversation.

83
00:06:23.267 --> 00:06:27.282
First line: what was asked, and how did it go?

84
00:06:27.679 --> 00:06:30.452
Headers: what label came back?

85
00:06:30.755 --> 00:06:33.923
Body: is it what the label claims?

86
00:06:34.123 --> 00:06:35.538
Try it yourself.

87
00:06:35.841 --> 00:06:41.099
Open the Network panel, click any request, and find the three parts.

88
00:06:41.182 --> 00:06:46.544
Then open the media type lab on Demo Company, and change the label.

89
00:06:46.744 --> 00:06:49.552
Three things in, three things out.

90
00:06:49.635 --> 00:06:52.942
Everything else on the web is built from that.
