-
Notifications
You must be signed in to change notification settings - Fork 4
/
14 HTTP2.html
369 lines (268 loc) · 13.2 KB
/
14 HTTP2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/white.css">
<style type="text/css">.reveal p { text-align: left; }</style>
<style type="text/css">.reveal blockquote { font-size: 50%; }</style>
<style type="text/css">.reveal table { font-size: 70%; }</style>
<style type="text/css">.reveal p img { border: 0px; }</style>
<style type="text/css">.reveal p.small { font-size: 80%; }</style>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-markdown>
# HTTP/2 и HTTP/3
Протоколы Интернет, лекция 14
</section>
<section data-markdown>
### План
* стандарты HTTP в IETF
* HTTP/2
* QUIC (Quick UDP Internet Connections)
</section>
<section data-markdown>
### Зачем?
Ускорить загрузку страниц
![](images/http-speed-rtt.svg)
</section>
<section data-markdown>
![](images/http2-caniuse.png)
[caniuse.com/#search=http2](https://caniuse.com/#search=http2)
</section>
<section data-markdown>
### Использование
![](images/http2-percentage.png)
[almanac.httparchive.org/en/2019/http2](https://almanac.httparchive.org/en/2019/http2)
</section>
<section data-markdown>
### Стандарты HTTP
Напомним, HTTP/1.1 изначально описан в RFC 2616, обновлен в RFC 7230-7239
![](images/http-refactor.png)
</section>
<section data-markdown>
### SPDY - ранний HTTP/2
Доработка RFC в IETF - это очень долго
Google экспериментировал с собственным протоколом под названием SPDY
* заявили, что этот протокол ускоряет загрузку веб-страниц, что является важнейшей функцией HTTP
* в 2009 анонсировали первую версию, а в 2010 - SPDY v2
</section>
<section data-markdown>
### Стандарты HTTP/2
После 18 черновиков в течение чуть более двух лет появился RFC 7540 — HTTP/2
RFC 7540 (HTTP/2) и RFC 7541 (HPACK) - Май 2015
![](images/http2-rfc.png)
</section>
<section data-markdown>
### Что не поменялось?
* HTTP/2 - те же схемы URI, http и https
* те же порты по умолчанию — 80/tcp и 443/tcp
- надо уметь определять, поддерживает ли сервер HTTP/2
* HTTP/2 не меняет семантику приложения
- все ключевые концепции – методы, коды ответа, заголовки – остаются теми же
Меняется процесс доставки
</section>
<section data-markdown>
### Что принципиально нового?
И почему не HTTP/1.2 ?
Несовместимость по формату (Binary Framing)
![](images/http2-binary-framing.svg)
</section>
<section data-markdown>
### Что принципиально нового?
* одно TCP-соединение
* Request → Stream
- Мультиплексирование
- Приоритеты
* Бинарная упаковка во фреймы
- управление потоком
- посылки с сервера
* Сжатие заголовков (HPACK)
</section>
<section data-markdown>
### Потоки, сообщения и фреймы
* одно TCP-соединение, любое количество двунаправленных потоков
* у потока - уникальный идентификатор и необязательная информация о приоритете
* сообщение HTTP (запрос или ответ) состоит из одного или нескольких кадров
* кадр - это наименьшая единица связи, данные определенного типа - заголовки HTTP, полезная нагрузка и т.д.
* кадры разных потоков могут чередоваться и повторно собираться (идентификатор потока в заголовке кадра)
</section>
<section data-markdown>
![](images/http2-streams-messages-frames.svg)
</section>
<section data-markdown>
### Установка HTTP соединения
Браузеры реализуют HTTP/2 только над HTTPS
```
GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: (base64 of HTTP/2 SETTINGS payload)
```
в зависимости от поддержки сервером, ответы
```
HTTP/1.1 200 OK
Content-Length: 243
Content-Type: text/html
```
```
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c
[ HTTP/2 connection ...
```
</section>
<section data-markdown>
### Установка HTTPS соединения
Требуется поддержка переключения с обычного TLS на HTTP/2
Расширение TLS – APLN (Application-Layer Protocol Negotiation)
```
$ openssl s_client -connect www.google.com:443 -nextprotoneg ''
CONNECTED(00000003)
Protocols advertised by server: grpc-exp, h2, http/1.1
```
Как отлаживаться ?
Использовать [вот такие](https://blog.cloudflare.com/tools-for-debugging-testing-and-using-http-2/) инструменты
</section>
<section data-markdown>
### Что дальше?
Сразу после согласования протокола с каждой стороны посылается строка (Connection Preface)
```
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
```
Затем – настройки соединения (SETTINGS, тип фрейма 4)
</section>
<section data-markdown>
### Фрейм
начинается с одинакового 9-байтового заголовка
для простоты разбора первой идёт длина
![](images/http2-frame.png)
Технически максимальная длина фрейма — $2^{24} B = 16 𝑀𝐵$
Но для фреймов DATA без дополнительного согласования длина фрейма — $2^{14} B = 16 𝐾𝐵$
</section>
<section data-markdown>
| Тип фрейма | Применение |
|---------------|-----------------------------------------------------------------|
| DATA | transport HTTP message bodies |
| HEADERS | communicate header fields for a stream |
| PRIORITY | communicate sender-advised priority of a stream |
| RST_STREAM | signal termination of a stream |
| SETTINGS | communicate configuration parameters for the connection |
| PUSH_PROMISE | signal a promise to serve the referenced resource |
| PING | measure the roundtrip time and perform "liveness" checks |
| GOAWAY | inform the peer to stop creating streams for current connection |
| WINDOW_UPDATE | implement flow stream and connection flow control |
| CONTINUATION | continue a sequence of header block fragments |
</section>
<section data-markdown>
Пример фрейма с заголовками
![](images/http2-frame-dump.webp)
</section>
<section data-markdown>
### Сжатие заголовков
* Текст сжимается по Хаффману
* Предыдущие значения индексируются
* Словарь общий на протяжении всего соединения
![](images/http2-hpack.webp)
</section>
<section data-markdown>
### Сжатие заголовков
Контекст сжатия HPACK состоит из статической и динамической таблицы
Статическая - определена в спецификации
* список общих полей заголовка HTTP, которые могут использовать все соединения
- допустимые имена заголовков
Динамическая таблица изначально пуста
* обновляется на основе обмениваемых значений в конкретном соединении
</section>
<section data-markdown>
### Мультиплексирование
В одном TCP-соединении – несколько потоков данных
Порядок фреймов внутри потоков важен
* HEADERS должны послаться до DATA
Поток номер 0 – стартовый, управляющий
Потоки, инициированные клиентом должны иметь нечётный номер
Инициированные сервером – чётный номер
</section>
<section data-markdown>
### Мультиплексирование
![](images/http2-multiplexing.svg)
Позволяет избавиться от блокировки, шардинга домена и т.д.
</section>
<section data-markdown>
### Приоритетность потоков
Каждый поток может иметь вес - число (1-256)
У потока можно установить зависимость от другого
Например, суммарная скорость должна распределиться между файлами style.css ("A") и logo.jpg ("B")
Или photo-1.jpg ("D") нужно доставить раньше photo-2.jpg ("C")
Потоковые зависимости и веса выражают транспортные предпочтения, а не требования
</section>
<section data-markdown>
### Приоритетность потоков
![](images/http2-stream-prioritization.svg)
</section>
<section data-markdown>
### Server Push
Зная структуру сайта, сервер может заранее послать дополнительные файлы (без запроса)
* клиент может отказаться (RST_STREAM) или обработать как обычно – кешировать и пр.
![](images/http2-push.svg)
</section>
<section data-markdown>
## HTTP/3 и QUIC
</section>
<section data-markdown>
### Еще один протокол?
Google экспериментировал и до 2015 года выпустил ещё версии SPDY v3 и v3.1
Также начали работать над протоколом gQUIC (Google QUIC), первый черновик которого опубликовали в начале 2012 года
QUIC - Quick UDP Internet Connections
Отход от транспорта TCP, на который традиционно полагался HTTP
</section>
<section data-markdown>
### QUIC и IETF
![](images/http3-rfc.png)
</section>
<section data-markdown>
### Название
В 2012 году: «HTTP/2.0 означает только то, что формат не совместим по транспорту с HTTP/1.х»
IETF последовал этому прецеденту
Во время конференции IETF 103 всё-таки был достигнут консенсус о переименовании «HTTP over QUIC» в HTTP/3
</section>
<section data-markdown>
### Собирая все воедино
HTTP/3 — это просто новый синтаксис HTTP, который работает на IETF QUIC, мультиплексированном и безопасном транспорте на основе UDP
На данный момент QUIC еще не является стандартом — его активно пишут
Именно сам стандарт QUIC, потому что в рабочей группе документов ещё восемь штук
</section>
<section data-markdown>
### Особенности
QUIC – это протокол, который реализован поверх UDP в user space
* Google и другие не хотят ждать, пока ОС обновятся
QUIC Connection ID против IP-адреса
Где пригодится? Беспроводная сеть или мобильное устройство, Youtube и ВКС
</section>
<section data-markdown>
# Вопросы ?
В следующий раз - развернём "свой интернет", с DNS, почтой и веб-сервером
</section>
</div>
</div>
<script src="js/reveal.js"></script>
<script>
Reveal.initialize({
hash: true,
slideNumber: true,
center: false,
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/math/math.js', async: true },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true }
]
});
</script>
</body>
</html>