Разбор заголовков HTTP

У меня появился новый интерес к созданию небольшого эффективного веб-сервера на C, и у меня возникли некоторые проблемы с синтаксическим анализом методов POST из заголовка HTTP. Кто-нибудь может посоветовать, как обрабатывать получение пар имя / значение из «опубликованных» данных?

POST /test HTTP/1.1
Host: test-domain.com:7017
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://test-domain.com:7017/index.html
Cookie: __utma=43166241.217413299.1220726314.1221171690.1221200181.16; __utmz=43166241.1220726314.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

field1=asfd&field2=a3f3f3
// ^-this

Я не вижу ощутимого способа получить прибыль в целом и убедиться, что она работает каждый раз. Я не поклонник жесткого кодирования в чем-либо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
18
0
31 216
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете получить пары имя / значение, выполнив поиск новой строки новой строки или, более конкретно, \ r \ n \ r \ n (после этого начнется тело сообщения).

Затем вы можете просто разделить список с помощью &, а затем разделить каждую из этих возвращаемых строк между парами = для имени / значения.

См. HTTP 1.1 RFC.

Ах, спасибо. Я заметил, что прямо перед строкой пар имя / значение был лишний пробел, но не складывал два и два вместе.

Chuck Callebs 17.09.2008 07:56

@rofly: не вычисляйте два и два, просто прочтите стандарт (RFC 2616). Это в разделе 4.1.

bortzmeyer 23.12.2008 00:06

Просто имейте в виду, что есть несовместимые клиенты, которые используют "интересный" конец заголовков, например '\ n \ n' или '\ n \ r \ n'.

Wade 19.05.2011 07:11

Обратите внимание, что есть и другие типы контента, кроме application / x-www-form-urlencoded. Это может быть любой тип, например json популярен.

Per Johansson 13.07.2012 21:06

Вам нужно продолжать синтаксический анализ потока как заголовков, пока вы не увидите пустую строку. Остальное - это данные POST.

Вам нужно написать небольшой парсер для данных поста. Вы можете использовать подпрограммы библиотеки C, чтобы делать что-то быстрое и грязное, например index, strtok и sscanf. Если у вас есть место для этого в вашем определении «маленький», вы можете сделать что-то более сложное с библиотекой регулярных выражений или даже с flex и bison.

По крайней мере, я думаю, что это своего рода ответ на ваш вопрос.

Если у вас есть Content-Length в заголовке, вы знаете, сколько байтов нужно прочитать сразу после пустой строки. Если по какой-либо причине (GET или POST) Content-Length отсутствует в заголовке, это означает, что после пустой строки (crlf) читать нечего.

Несмотря на IETF RFC, вот более конкретный ответ. Предполагая, что вы понимаете, что всегда есть лишний /r/n после строки Content-Length в заголовке, вы сможете выполнить работу по изоляции его в переменной char* с именем data. Вот с чего мы начинаем.

char *data = "f1=asfd&f2=a3f3f3";
char f1[100], 
char f2[100];
sscanf(data, "%s&%s", &f1, &f2); // get the field tuples

char f1_name[50];
char f1_data[50];
sscanf(f1, "%s=%s", f1_name, f1_data);  

char f2_name[50];
char f2_data[50];
sscanf(f2, "%s=%s", f2_name, f2_data);  

Другие вопросы по теме