Erlang gen_tcp:recv http_request abs_path

时间:2015-05-13 22:31:50

标签: erlang gen-tcp

我在Erlang中编写接受HTTP请求的代码。我有工作代码,如下所示。

我遇到的问题是我不确定gen_tcp:recv的返回结果。

我使用

创建一个侦听套接字并接受套接字
{ok, ListenSock}=gen_tcp:listen(Port, [list,{active, false},{packet,http}])
{ok, Sock}=gen_tcp:accept(ListenSock),

我使用

接受GET请求(或任何其他)
{ok, {http_request, Method, Path, Version}} = gen_tcp:recv(Sock, 0),
handle_get(Sock, Path);

然后,要获取url参数(CGI参数,例如?foo=1&bar=2),我必须将Path与结构{abs_path, RelativePath}匹配。

handle_get(Sock, ReqPath) ->
    {abs_path, RelPath} = ReqPath,
    Parameters = string:substr(RelPath, string:str(RelPath, "?") + 1),

我正在阅读Erlang关于gen_tcp的文档,更具体地说是recv方法,我发现the page describing HttpPacket

页面上的语法清楚地显示Path中的HttpPacket,以及HttpRequest类型中的HttpUri,可以有多种HttpRequest = {http_request, HttpMethod, HttpUri, HttpVersion} HttpUri = '*' | {absoluteURI, http | https, Host :: HttpString, Port :: inet:port_number() | undefined, Path :: HttpString} | {scheme, Scheme :: HttpString, HttpString} | {abs_path, HttpString} | HttpString

curl

我知道我必须支持这些可能的情况,但我不确定。我也想知道如何测试这些案例。我尝试在Firefox中使用RESTClientgen_tcp:recv,并且两者都abs_path返回{abs_path, HttpString}

所以要明确,如何确定请求是否包含{scheme, Scheme :: HttpString, HttpString}{absoluteURI,...}start(Port)-> {ok, ListenSock}=gen_tcp:listen(Port, [list,{active, false},{packet,http}]), loop(ListenSock). loop(ListenSock) -> {ok, Sock}=gen_tcp:accept(ListenSock), spawn(?MODULE, handle_request, [Sock]), loop(ListenSock). %% Takes a TCP socket and receives %% http://erlang.org/doc/man/erlang.html#decode_packet-3 handle_request(Sock) -> {ok, {http_request, Method, Path, _Version}} = gen_tcp:recv(Sock, 0), case (Method) of 'GET' -> handle_get(Sock, Path); _ -> send_unsupported_error(Sock) end. handle_get(Sock, ReqPath) -> {abs_path, RelPath} = ReqPath, Parameters = string:substr(RelPath, string:str(RelPath, "?") + 1), %% Debugging ParsedParms = httpd:parse_query(Parameters), io:fwrite("Full Path: ~p~nParameters: ~p~n", [RelPath, ParsedParms]), %% End Debugging send_accept(Sock). ,我是否需要支持所有请求?

完整列表

size

1 个答案:

答案 0 :(得分:1)

您可以使用支持网络的简单客户端(例如我的系统上的netcat(/usr/bin/nc)来发送您喜欢的任何形式的请求。例如,以下连接到侦听localhost端口8000的Web服务器,并发送GET请求,其中路径是URL(请注意$表示shell提示符):< / p>

$ nc localhost 8000
GET http://stackoverflow.com HTTP/1.1

$

nc程序从其标准输入读取。请确保在GET行后输入两次以正确指示HTTP标头的结尾。这导致服务器返回gen_tcp:recv调用:

{absoluteURI,http,"stackoverflow.com",undefined,"/"}

同样,以下内容将返回gen_tcp:recv的路径,该路径不是{abs_path, ...}元组,而只是"../foo"

$ nc localhost 8000
GET ../foo HTTP/1.1

$

您可以在文本文件中轻松设置这些测试变体,并使用stdin重定向将其输入nc