@CNNRNN

Как разобрать HTTP запрос?

Здравствуйте!
Разбор http запросов я понимаю так.
1) создаем буфер куда записываем данные из сети
// массив с размером 1024 байт
let mut buffer = [0; 1024];
// тут я читаю данные из сети и записываю в массив (buffer)
 stream.read(&mut buffer).unwrap();

2) затем извлекаем из массива данные
И тут у меня 2 вопроса.
1) Что делать если размер запроса больше чем размер буфера?
1.1) Нужно будет читать пока не найдется CRLF в буфере ?
1.2) для этого мне нужно пройтись по буферу и искать CRLF . если его нет то очистить буфер и продолжать читать ?
2) Как отделять один http запрос от другого ?
Если есть возможность можно ссылку дать, где с нуля опишут этот процесс и без библиотек. пойдет любой язык)
Спасибо!
  • Вопрос задан
  • 268 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
Что делать если размер запроса больше чем размер буфера?
Читать в цикле. read вообще не гарантирует, что заполнит буфер полностью, но больше его размера он точно за раз не прочитает. А еще он возвращает io::Result<usize>, в котором сообщает, сколько реально байт было прочитано.
1.1) Нужно будет читать пока не найдется CRLF в буфере ?
Пока read не вернет Ok(0), ну или ошибку. Хотя с ошибкой не все так однозначно, согласно доке может вылететь Err(io::ErrorKind::Interrupted) при котором стоит повторить попытку чтения. Вообще CRLF будет после каждого заголовка, а когда заголовки закончатся будет 2 CRLF подряд, а потом еще может быть тело запроса, а может и не быть.
1.2) для этого мне нужно пройтись по буферу и искать CRLF . если его нет то очистить буфер и продолжать читать ?
нет, нужно распарсить то что пришло, куда-то сохранить, а потом продолжить чтение.
2) Как отделять один http запрос от другого ?
Если у нас не keep-alive, то каждый запрос будет в отдельном соединении, но keep-alive наступает только если обе стороны прислали заголовок Connection: keep-alive Можете сделать по простому, и отвечать с заголовком Connection: close, все равно в учебном проекте производительность у Вас будет никакая. Но если хотите все же заморочиться, то правило тоже не сложное - следующий запрос начинается в следующем же байте, где закончился текущий. Размер тела запроса в байтах можно узнать из заголовка Content-Length, а если его нет, то можете считать, что его значение 0.

Что следует почитать для Вашей задумки:
1. Спеку http
2. Исходники hyper
3. Исходники actix-web
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы