> For the complete documentation index, see [llms.txt](https://antonshevchuk.gitbook.io/php-for-beginners/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://antonshevchuk.gitbook.io/php-for-beginners/0_introduction/http.md).

# Протокол HTTP

> *О, это обязательный раздел для всех web-разработчиков, я прям настаиваю на изучении данного материала для всех-всех-всех.*

HTTP (HyperText Transfer Protocol) — это «протокол передачи гипертекста», т.е. по сути своей это текстовый протокол, и его понять не составит труда.

> *Изначально подразумевали, что по этому протоколу будет только HTML передаваться, отсель и название, а сейчас чего только не отправляют и =(^.^)= и（•*&#x3145;*•)*

Чтобы не ходить вокруг да около, давайте я вам приведу пример общения по HTTP протоколу. Вот пример запроса, каким его отправляет ваш браузер, когда вы запрашиваете страницу `http://example.com`:

```
GET / HTTP/1.1
Host: example.com
Accept: text/html
```

А вот пример ответа:

```
HTTP/1.1 200 OK
Content-Length: 1983
Content-Type: text/html; charset=utf-8

<html>
  <head>...</head>
  <body>...</body>
</html>
```

Это очень упрощенные примеры, но и тут можно увидеть из чего состоят HTTP запрос и ответ:

1. **стартовая строка** — для запроса содержит метод и путь запрашиваемой страницы, для ответа - версию протокола и код ответа
2. **заголовки** — имеют формат ключ-значение разделенные двоеточием, каждый новый заголовок пишется с новой строки
3. **тело сообщения** — непосредственно HTML либо данные отделяют от заголовков двумя переносами строки, могут отсутствовать, как в приведенном запросе

Так, вроде с протоколом разобрались - он простой, ведёт свою историю аж с 1992-го года, так что идеальным его не назовешь, но какой есть - отправили запрос - получите ответ, и всё, сервер и клиент никоим образом более не связаны. Но подобный сценарий отнюдь не единственный возможный, у нас же может быть авторизация, сервер должен каким-то образом понимать, что вот этот запрос пришёл от определенного пользователя, т.е. клиент и сервер должны общаться в рамках некой сессии. И да, для этого придумали следующий механизм:

1. При авторизации пользователя, сервер генерирует и запоминает уникальный ключ - идентификатор сессии, и сообщает его браузеру
2. Браузер сохраняет этот ключ, и при каждом последующем запросе, его отправляет

Для реализации этого механизма и были созданы [cookie](https://en.wikipedia.org/wiki/HTTP_cookie) (куки, печеньки) — простые текстовые файлы на вашем компьютере, по файлу для каждого домена (хотя некоторые браузеры более продвинутые, и используют для хранения SQLite базу данных), при этом браузер накладывает ограничение на количество записей и размер хранимых данных (для большинства браузеров это 4096 байт, см. [RFC 2109](https://tools.ietf.org/html/rfc2109) от 1997-го года)

> Т.е. если украсть cookie из вашего браузера, то можно будет зайти на вашу страничку в facebook от вашего имени? Не пугайтесь, так сделать нельзя, по крайней мере с facebook, и дальше я вам покажу один из возможных способов защиты от данного вида атаки на ваших пользователей.

Давайте теперь посмотрим как изменятся наши запрос-ответ, будь там авторизация:

**Request**

```
POST /login/ HTTP/1.1
Host: example.com
Accept: text/html

login=Username&amp;password=Userpass
```

Метод у нас изменился на POST, и в теле запроса у нас передаются логин и пароль. Если использовать метод GET, то строка запроса будет содержать логин и пароль, что не очень правильно с идеологической точки зрения, и имеет ряд побочных явлений в виде логирования (например, в том же `access.log`) и кеширования паролей в открытом виде.

**Response**

```
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: KEY=VerySecretUniqueKey

<html>
  <head>...</head>
  <body>...</body>
</html>
```

Ответ сервер будет содержать заголовок `Set-Cookie: KEY=VerySecretUniqueKey`, что заставит браузер сохранить эти данные в файлы cookie, и при следующем обращении к серверу - они будут отправлены и опознаны сервером:

**Request**

```
GET / HTTP/1.1
Host: example.com
Accept: text/html
Cookie: KEY=VerySecretUniqueKey
```

> Как можно заметить, заголовки отправляемые браузером (Request Headers) и сервером (Response Headers) отличаются, хотя есть и общие и для запросов и для ответов (General Headers)

Сервер узнал нашего пользователя по присланным cookie, и дальше предоставит ему доступ к личной информации. Так что, с сессиями в HTTP разобрались? Идём дальше.

> Эка я RFC в сотни страниц влепил в одну страничку, так же многое можно пропустить... Это да, если есть желание посмотрите на [RFC2616](https://tools.ietf.org/html/rfc2616), но пока можете не забивать этим голову.
