Разбор заголовков + MIME

При анализе MIME с помощью Erlang я могу извлечь заголовок, тело и вложение. Так что теперь мне нужно разобрать все эти части по отдельности.

Структура заголовка:

Header-tag : header-value\n

Пример:

Delivered-To: [email protected]\nReceived: by 1.gnu.geodesic.net (fdm 1.5, account "mail");\n\tFri, 03 Jul 2009 16:56:03 +0530\n

поэтому из приведенного выше примера я должен извлечь Delivered-To: [email protected] и Received: by 1.gnu.geodesic.net (fdm 1.5, account "mail");\n\tFri, 03 Jul 2009 16:56:03 +0530\n, используя какой-то способ разделения с \n. Но значение второго заголовка содержит \n\t, так что разделение на этом останавливается... Я хочу строгое разделение, которое будет разделяться только с \n.

Заранее спасибо.


person Abhimanyu    schedule 03.07.2009    source источник


Ответы (2)


Между прочим, заголовки MIME (почти?) такие же, как заголовки HTTP, поэтому вы можете использовать встроенное в Erlang декодирование HTTP: (данные должны быть двоичными, а не строковыми)

3> erlang:decode_packet(httph, <<"Delivered-To: [email protected]\nReceived: by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530\n">>, []).
{ok,{http_header,0,"Delivered-To",undefined,
                 "[email protected]"},
    <<"Received: by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530\n">>}
4> Rest = element(3, v(-1)).

Правильно, получил первый заголовок в записи http_header, а остальные данные.

<<"Received: by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530\n">>
5> erlang:decode_packet(httph, Rest, []).
{more,undefined}

Но поскольку декодер не может знать, продолжается ли строка заголовка на следующей строке, не видя следующей строки, это не работает. Нам нужно добавить последнюю пустую строку:

6> erlang:decode_packet(httph, <<Rest/binary, "\r\n">>, []).
{ok,{http_header,0,"Received",undefined,
                 "by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530"},
    <<"\r\n">>}

И когда это все, что осталось, мы получаем http_eoh:

7> erlang:decode_packet(httph, <<"\r\n">>, []).
{ok,http_eoh,<<>>}

Надеюсь, это поможет…

person legoscia    schedule 06.07.2009

Вы имеете в виду что-то вроде этого?

split(String) ->
  split(String, [], []).


split([], [], Result) ->
  lists:reverse(Result);

split([], Buffer, [{Key}|Result]) ->
  split([], [], [{Key, lists:reverse(Buffer)}|Result]);

split("\n\t" ++ String, Buffer, Result) ->
  split(String, "\t\n" ++ Buffer, Result);

split("\n" ++ String, Buffer, [{Key}|Result]) ->
  split(String, [], [{Key, lists:reverse(Buffer)}|Result]);

split(": " ++ String, Buffer, Result) ->
  split(String, [], [{lists:reverse(Buffer)}|Result]);

split([C|String], Buffer, Result) ->
  split(String, [C|Buffer], Result).

Вот результат для вашего заголовка ввода:

> split("Delivered-To: [email protected]\nReceived: by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530\n").
[{"Delivered-To","[email protected]"},
 {"Received",
  "by 1.gnu.geodesic.net (fdm 1.5, account \"mail\");\n\tFri, 03 Jul 2009 16:56:03 +0530"}]
person Zed    schedule 27.07.2009