Erlang 请求处理

发布于 2024-10-09 04:12:25 字数 614 浏览 4 评论 0原文

我正在学习 erlang,并且正在尝试构建一个 Http Server 以更好地了解 erlang 的工作原理,我能够收到请求:

<<"GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\ r\n连接:保持活动状态\r\n缓存控制:max-age=0\r\n接受:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8, image/png,/;q=0.5\r\n用户代理:Mozilla/5.0(X11;U;Linux i686;en-US)AppleWebKit/534.3(KHTML,如 Gecko)Chrome/6.0 .472.51 Safari/534.3\r\n接受编码:gzip,deflate,sdch\r\n接受语言:en-US,en;q=0.8\r\n接受字符集:ISO-8859-1,utf-8; q=0.7,*;q=0.3\r\n\r\n">>

但我不太确定如何开始模式匹配,或者想知道是否必须构建 FSM 或其他东西来跟踪当前的解析和状态。有没有一种简单的方法可以使用模式匹配来提取标题和正文,也许可以在 \r\n 上分割?我不想使用像 mochiweb 这样的东西,因为我正在努力学习基础知识。

I am learning erlang, and am trying to build an Http Server to better learn about how erlang works, I am able to get the request:

<<"GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.51 Safari/534.3\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n">>

but I'm not exactly sure how to begin pattern matching, or am wondering if I'm going to have to build a FSM or something to keep track of the current parses and the state. Is there a simple method to extract headers and body using pattern matching, maybe splitting on \r\n? I'd prefer not to use something like mochiweb, since I am trying to learn fundamentals.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

埋葬我深情 2024-10-16 04:12:25

非常简单的解决方案:检查 inet:setopts/2{packet, http_bin} 选项。

更复杂的解决方案:

您需要解析二进制文件。大致如下:

-module(foo).
-compile(export_all).

x() ->
    <<"GET /hello/world/ HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.51 Safari/534.3\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n">>.

parse(<<"GET ", R/binary>>) ->
    parse_get(R).

parse_get(Bin) ->
    [Path, R] = binary:split(Bin, [<<" ">>]),
    {{get, Path}, R}.

基本技巧是您希望将解析器视为 binary() -> {parse(), binary()} 其中二进制输出是剩余的要解析的内容。这为您的组合器解析器或递归下降做好了很好的准备。另一种方法是将二进制文件转换为列表并对其进行处理,但速度会慢得多。在这种情况下,看看二进制模块,它可以为您完成很多繁重的工作。

另一种选择是检查 Yaws 或 Mochiweb 应用程序,它们已经执行此操作并引诱它们执行的操作。

Dead simple solution: check inet:setopts/2 and the {packet, http_bin} option.

The more involved solution:

You need to parse the binary. Something along the lines of:

-module(foo).
-compile(export_all).

x() ->
    <<"GET /hello/world/ HTTP/1.1\r\nHost: 127.0.0.1:8000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.51 Safari/534.3\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n">>.

parse(<<"GET ", R/binary>>) ->
    parse_get(R).

parse_get(Bin) ->
    [Path, R] = binary:split(Bin, [<<" ">>]),
    {{get, Path}, R}.

The basic trick is that you want to see a parser as binary() -> {parse(), binary()} where the binary output is the remaining things to parse. This sets you up nicely for a combinator-parser or a recursive descent. An alternative is to convert the binary to a list and work on that, but it is going to be considerably slower. Look at the binary modules which can do a lot of heavylifting for you in this case.

Another alternative is to check either the Yaws or the Mochiweb applications which already has to do this and lure out what they do.

零崎曲识 2024-10-16 04:12:25

要解析 HTTP 请求,您可以使用 erlang:decode_packet/3

To parse HTTP requests you can use erlang:decode_packet/3.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文