Один из способов справиться с OPTIONS
запросом является использование Yaws dispatchmod, который похож на Yaws appmod, но Yaws называет его до выполнения любого другого обращения с запросом. Вот модуль пример отправки на основе информации в вашем вопросе:
-module(options_dispatcher).
-export([dispatch/1]).
-include_lib("yaws_api.hrl").
dispatch(Arg) ->
Req = yaws_api:arg_req(Arg),
case yaws_api:http_request_method(Req) of
'OPTIONS' ->
Vsn = yaws_api:http_request_version(Req),
Resp = #http_response{
version=Vsn,
status=200,
phrase=yaws_api:code_to_phrase(200)},
HdrVals = [{"Access-Control-Allow-Origin", "http://example.com"},
{"Access-Control-Allow-Methods", "GET, OPTIONS"},
{"Access-Control-Allow-Headers", "Authorization"},
{"Access-Control-Allow-Credentials", "true"},
{"Content-Length", "0"},
{"Content-Type", "text/plain"}],
Headers = lists:foldl(fun({H,V}, Hdrs) ->
yaws_api:set_header(Hdrs, H, V)
end, #headers{}, HdrVals),
HdrStrings = yaws_api:reformat_header(Headers),
Reply = [yaws_api:reformat_response(Resp), "\r\n",
string:join(HdrStrings, "\r\n"), "\r\n\r\n"],
Sock = yaws_api:arg_clisock(Arg),
case yaws_api:get_sslsocket(Sock) of
{ok, SslSock} ->
ssl:send(SslSock, Reply);
undefined ->
gen_tcp:send(Sock, Reply)
end,
done;
_ ->
continue
end.
Этот код получает Yaws #arg{}
запись, так же как appmod, за исключением уведомления о том, что dispatchmod должен экспортировать dispatch/1
функцию в то время как appmod должен экспортировать out/1
функция. Оттуда он извлекает информацию запроса и проверяет метод HTTP-запроса. Если это OPTIONS
, код создает запись ответа и устанавливает заголовки ответов, форматирует их как строки, а затем создает значение Reply
, которое представляет собой iolist
, содержащее строку состояния ответа HTTP, отформатированные заголовки HTTP-ответа и "\r\n\r\n"
, чтобы отметить конец HTTP-ответа. Затем он использует либо ssl:send/2
, либо gen_tcp:send/2
, исходя из того, какой тип сокета получил запрос, чтобы отправить ответ напрямую. Наконец, он возвращает done
, чтобы рассказать Yaws, что больше нет работы для этого запроса. Для любого метода HTTP, отличного от OPTIONS
, код возвращает continue
, чтобы сказать, что Yaws выполняет обычную диспетчеризацию.
Чтобы развернуть диспетчер, скомпилируйте код и поместите полученный файл луча в путь загрузки Yaws. Затем измените серверную часть вашего Yaws конфигурации, чтобы включить параметр:
dispatchmod = options_dispatcher
Это говорит фрамбезии, что сервер имеет dispatchmod, который должен быть вызван как часть потока отправки запроса на этот сервер. Затем либо запустить/перезапустить торможение, либо использовать
yaws --hup --id ID
, чтобы сообщить запущенному экземпляру Yaws, чтобы перезагрузить его конфигурацию.
Я вижу код типа «handle (« OPTIONS », A) ->», должен ли я сделать appmod, чтобы перехватывать OPTIONS? Или я могу легко добавить набор заголовков по умолчанию? – mattias