diff options
Diffstat (limited to 'apps/mochiweb/src/mochiweb_http.erl')
-rw-r--r-- | apps/mochiweb/src/mochiweb_http.erl | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/apps/mochiweb/src/mochiweb_http.erl b/apps/mochiweb/src/mochiweb_http.erl deleted file mode 100644 index f1821f40..00000000 --- a/apps/mochiweb/src/mochiweb_http.erl +++ /dev/null @@ -1,152 +0,0 @@ -%% @author Bob Ippolito <bob@mochimedia.com> -%% @copyright 2007 Mochi Media, Inc. - -%% @doc HTTP server. - --module(mochiweb_http). --author('bob@mochimedia.com'). --export([start/0, start/1, stop/0, stop/1]). --export([loop/2, default_body/1]). --export([after_response/2, reentry/1]). - --define(IDLE_TIMEOUT, 30000). - --define(MAX_HEADERS, 1000). --define(DEFAULTS, [{name, ?MODULE}, - {port, 8888}]). - -set_default({Prop, Value}, PropList) -> - case proplists:is_defined(Prop, PropList) of - true -> - PropList; - false -> - [{Prop, Value} | PropList] - end. - -set_defaults(Defaults, PropList) -> - lists:foldl(fun set_default/2, PropList, Defaults). - -parse_options(Options) -> - {loop, HttpLoop} = proplists:lookup(loop, Options), - Loop = fun (S) -> - ?MODULE:loop(S, HttpLoop) - end, - Options1 = [{loop, Loop} | proplists:delete(loop, Options)], - set_defaults(?DEFAULTS, Options1). - -stop() -> - mochiweb_socket_server:stop(?MODULE). - -stop(Name) -> - mochiweb_socket_server:stop(Name). - -start() -> - start([{ip, "127.0.0.1"}, - {loop, {?MODULE, default_body}}]). - -start(Options) -> - mochiweb_socket_server:start(parse_options(Options)). - -frm(Body) -> - ["<html><head></head><body>" - "<form method=\"POST\">" - "<input type=\"hidden\" value=\"message\" name=\"hidden\"/>" - "<input type=\"submit\" value=\"regular POST\">" - "</form>" - "<br />" - "<form method=\"POST\" enctype=\"multipart/form-data\"" - " action=\"/multipart\">" - "<input type=\"hidden\" value=\"multipart message\" name=\"hidden\"/>" - "<input type=\"file\" name=\"file\"/>" - "<input type=\"submit\" value=\"multipart POST\" />" - "</form>" - "<pre>", Body, "</pre>" - "</body></html>"]. - -default_body(Req, M, "/chunked") when M =:= 'GET'; M =:= 'HEAD' -> - Res = Req:ok({"text/plain", [], chunked}), - Res:write_chunk("First chunk\r\n"), - timer:sleep(5000), - Res:write_chunk("Last chunk\r\n"), - Res:write_chunk(""); -default_body(Req, M, _Path) when M =:= 'GET'; M =:= 'HEAD' -> - Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()}, - {parse_cookie, Req:parse_cookie()}, - Req:dump()]]), - Req:ok({"text/html", - [mochiweb_cookies:cookie("mochiweb_http", "test_cookie")], - frm(Body)}); -default_body(Req, 'POST', "/multipart") -> - Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()}, - {parse_cookie, Req:parse_cookie()}, - {body, Req:recv_body()}, - Req:dump()]]), - Req:ok({"text/html", [], frm(Body)}); -default_body(Req, 'POST', _Path) -> - Body = io_lib:format("~p~n", [[{parse_qs, Req:parse_qs()}, - {parse_cookie, Req:parse_cookie()}, - {parse_post, Req:parse_post()}, - Req:dump()]]), - Req:ok({"text/html", [], frm(Body)}); -default_body(Req, _Method, _Path) -> - Req:respond({501, [], []}). - -default_body(Req) -> - default_body(Req, Req:get(method), Req:get(path)). - -loop(Socket, Body) -> - inet:setopts(Socket, [{packet, http}]), - request(Socket, Body). - -request(Socket, Body) -> - case gen_tcp:recv(Socket, 0, ?IDLE_TIMEOUT) of - {ok, {http_request, Method, Path, Version}} -> - headers(Socket, {Method, Path, Version}, [], Body, 0); - {error, {http_error, "\r\n"}} -> - request(Socket, Body); - {error, {http_error, "\n"}} -> - request(Socket, Body); - _Other -> - gen_tcp:close(Socket), - exit(normal) - end. - -reentry(Body) -> - fun (Req) -> - ?MODULE:after_response(Body, Req) - end. - -headers(Socket, Request, Headers, _Body, ?MAX_HEADERS) -> - %% Too many headers sent, bad request. - inet:setopts(Socket, [{packet, raw}]), - Req = mochiweb:new_request({Socket, Request, - lists:reverse(Headers)}), - Req:respond({400, [], []}), - gen_tcp:close(Socket), - exit(normal); -headers(Socket, Request, Headers, Body, HeaderCount) -> - case gen_tcp:recv(Socket, 0, ?IDLE_TIMEOUT) of - {ok, http_eoh} -> - inet:setopts(Socket, [{packet, raw}]), - Req = mochiweb:new_request({Socket, Request, - lists:reverse(Headers)}), - Body(Req), - ?MODULE:after_response(Body, Req); - {ok, {http_header, _, Name, _, Value}} -> - headers(Socket, Request, [{Name, Value} | Headers], Body, - 1 + HeaderCount); - _Other -> - gen_tcp:close(Socket), - exit(normal) - end. - -after_response(Body, Req) -> - Socket = Req:get(socket), - case Req:should_close() of - true -> - gen_tcp:close(Socket), - exit(normal); - false -> - Req:cleanup(), - ?MODULE:loop(Socket, Body) - end. |