YAWS、CORS:如何定义 OPTIONS 应该 return?
YAWS, CORS: How to define what OPTIONS should return?
我需要让 CORS 工作。似乎 jquery $ajax 进行了 OPTIONS 调用,这应该 return 必要的 CORS headers。我所有的 GET 和 POST 都已经这样做了,但似乎还不够。在 NGINX 中,你会做这样的事情:
location / {
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin "http://example.com";
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
}
如何在 YAWS 中执行相同的操作?
处理 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
,代码会创建一个响应记录并设置响应 headers,将它们格式化为字符串,然后创建 Reply
值,该值是一个 iolist
,其中包含HTTP 响应状态行,格式化的 HTTP 响应 headers,以及 "\r\n\r\n"
来标记 HTTP 响应的结束。然后它根据收到请求的套接字类型使用 ssl:send/2
或 gen_tcp:send/2
直接发送回复。最后它 returns done
告诉 Yaws 对于该请求没有更多的工作要做。对于 OPTIONS
以外的任何 HTTP 方法,代码 returns continue
告诉 Yaws 执行其正常调度。
要部署调度程序,请编译代码并将生成的光束文件放在 Yaws 加载路径中。然后修改 Yaws 配置的服务器部分以包含设置:
dispatchmod = options_dispatcher
这告诉 Yaws 服务器有一个 dispatchmod 应该作为该服务器的请求调度流的一部分被调用。然后 start/restart Yaws 或使用
yaws --hup --id ID
告诉 运行 Yaws 实例重新加载其配置。
我需要让 CORS 工作。似乎 jquery $ajax 进行了 OPTIONS 调用,这应该 return 必要的 CORS headers。我所有的 GET 和 POST 都已经这样做了,但似乎还不够。在 NGINX 中,你会做这样的事情:
location / {
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin "http://example.com";
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
}
如何在 YAWS 中执行相同的操作?
处理 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
,代码会创建一个响应记录并设置响应 headers,将它们格式化为字符串,然后创建 Reply
值,该值是一个 iolist
,其中包含HTTP 响应状态行,格式化的 HTTP 响应 headers,以及 "\r\n\r\n"
来标记 HTTP 响应的结束。然后它根据收到请求的套接字类型使用 ssl:send/2
或 gen_tcp:send/2
直接发送回复。最后它 returns done
告诉 Yaws 对于该请求没有更多的工作要做。对于 OPTIONS
以外的任何 HTTP 方法,代码 returns continue
告诉 Yaws 执行其正常调度。
要部署调度程序,请编译代码并将生成的光束文件放在 Yaws 加载路径中。然后修改 Yaws 配置的服务器部分以包含设置:
dispatchmod = options_dispatcher
这告诉 Yaws 服务器有一个 dispatchmod 应该作为该服务器的请求调度流的一部分被调用。然后 start/restart Yaws 或使用
yaws --hup --id ID
告诉 运行 Yaws 实例重新加载其配置。