Информация об изменениях

Сообщение Re: Базовой вопрос по Http. от 06.06.2020 0:46

Изменено 06.06.2020 1:44 vsb

Re: Базовой вопрос по Http.
Здравствуйте, Sharov, Вы писали:

S>1)Допустим имеется клиент. Пусть имеется api, когда клиент что-то заращивает у сервера http get(большой json объект с 10000 записей). Правильно ли я понимаю, что в данном случае у меня http собирает данные (копит в буфере), и когда все данные будут доступны (в памяти), мой клиент получит один обычный http get ответ?


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

S>2)Допустим имеется сервер, который получает огромный (8гб) файл от клиента. Вот у меня в api есть stream параметр (networkstream в случае дотнет). Верно, что в данном случае мой сервер получит http post, хотя его тело (т.е. 8гб), еще до конца не получено? Т.е. я получю один http post и начинаю читать содержимое, которое до конца-то может и не придти, т.е. получается что http post в данном случае может не знать свой размер.


S>Т.е. я понимаю разницу между буферизацией и потоком, но я не понимаю как 2) случае все это будет физически оформлено в один http post.


В HTTP 1.1 есть два режима передачи тела сообщения. Первый режим это когда указывается заголовок content-length. В этом случае просто передаётся тело сообщения после заголовков и всё. Этот режим удобно применять, когда длина сообщения известна заранее. Второй режим это когда заголовок content-length не указывается. В этом случае тело сообщения передаётся кусками. Каждый кусок предваряется его длиной. Конец всего сообщения маркируется куском нулевой длины.

Это то, как оно устроено на уровне байтов. Описание справедливо и для запроса и для ответа.

На уровне API всегда есть возможность читать тело в виде потока, а не целиком. Просто в первом случае будет заранее доступна длина этого потока, во втором случае не будет.

Если речь именно о загрузке файлов через браузер, то там идёт т.н. multipart encoding. Это отдельный протокол уровня выше HTTP.

S>3)Про физику процесса -- я правильно понимаю, что у меня данные копятся в буфере http, а tcp просто прокидывает chunk'и данных? И когда у меня данные закончились — все пришло, либо разрыв — то tcp манифистирует об этом http, и уже http либо оформляет стандартный запрос\ответ, либо у меня вылезает ошибка о разрыве (но в этом случае это не ошибка http, а tcp socket что-то там).


Тут ничего не понял, если честно. TCP ничего не сигнализирует. HTTP это протокол более высокого уровня и от низлежащего протокола ему нужна только "труба с байтами", больше ничего не нужно. Если в середине чтения сообщения внезапно закроется сокет, вылезет ошибка, да.
Re: Базовой вопрос по Http.
Здравствуйте, Sharov, Вы писали:

S>1)Допустим имеется клиент. Пусть имеется api, когда клиент что-то заращивает у сервера http get(большой json объект с 10000 записей). Правильно ли я понимаю, что в данном случае у меня http собирает данные (копит в буфере), и когда все данные будут доступны (в памяти), мой клиент получит один обычный http get ответ?


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

S>2)Допустим имеется сервер, который получает огромный (8гб) файл от клиента. Вот у меня в api есть stream параметр (networkstream в случае дотнет). Верно, что в данном случае мой сервер получит http post, хотя его тело (т.е. 8гб), еще до конца не получено? Т.е. я получю один http post и начинаю читать содержимое, которое до конца-то может и не придти, т.е. получается что http post в данном случае может не знать свой размер.


S>Т.е. я понимаю разницу между буферизацией и потоком, но я не понимаю как 2) случае все это будет физически оформлено в один http post.


В HTTP 1.1 есть два режима передачи тела сообщения. Первый режим это когда указывается заголовок content-length. В этом случае просто передаётся тело сообщения после заголовков и всё. Этот режим удобно применять, когда длина сообщения известна заранее. Второй режим это когда заголовок content-length не указывается. В этом случае тело сообщения передаётся кусками. Каждый кусок предваряется его длиной. Конец всего сообщения маркируется куском нулевой длины.

Это то, как оно устроено на уровне байтов. Описание справедливо и для запроса и для ответа.

На уровне API всегда есть возможность читать тело в виде потока, а не целиком. Просто в первом случае будет заранее доступна длина этого потока, во втором случае не будет.

Если речь именно о загрузке файлов через браузер, то там идёт т.н. multipart encoding. Это отдельный протокол уровня выше HTTP.

S>3)Про физику процесса -- я правильно понимаю, что у меня данные копятся в буфере http, а tcp просто прокидывает chunk'и данных? И когда у меня данные закончились — все пришло, либо разрыв — то tcp манифистирует об этом http, и уже http либо оформляет стандартный запрос\ответ, либо у меня вылезает ошибка о разрыве (но в этом случае это не ошибка http, а tcp socket что-то там).


Тут ничего не понял, если честно. TCP ничего не сигнализирует. HTTP это протокол более высокого уровня и от низлежащего протокола ему нужна только "труба с байтами", больше ничего не нужно. Если в середине чтения сообщения внезапно закроется сокет, вылезет ошибка, да.

Ну, точней, определённую связь между HTTP и TCP найти можно. В частности заголовки вроде keep-alive, чтобы переиспользовать соединения для нескольких запросов. Но в целом это можно считать скорей оптимизацией, чем фундаментальной связью.

Это всё касается HTTP 1.1 (и, возможно, 1.0, уже плохо помню различия). Что там в HTTP 2.0, не знаю. Но с точки зрения прикладного программиста, пользующегося этим всем через API, всё вышеописанное должно быть справедливо и там.