Friday, September 14, 2007

Mochiweb - an erlang based webserver toolkit

Yesterday I asked on the erlang mailing list if somebody knows about a fast and simple HTTP server in Erlang, specifically suited to dynamic requests. And I got an answer from Bob Ippolito, providing even more than I was looking for: an easy extendable and highly configurable webserver toolkit, which contains everthing from static file serving to URL and multipart decoding to JSON handling. Below a sample Bob provided to show how to build a webserver using mochiweb:

-module(c4_http).
-export([start/0, loop/2, stop/0]).
-define(DEFAULTS, [{name, ?MODULE},
{port, 9952}]).

start() ->
DocRoot = filename:dirname(filename:dirname(code:which(?MODULE))),
code:add_patha(filename:join([DocRoot, "mochiweb-c4", "ebin"])),
Loop = fun (Req) -> ?MODULE:loop(Req, DocRoot) end,
{ok, Pid} = c4_adder_otp:start(),
register(c4_hit_counter, Pid),
mochiweb_http:start([{loop, Loop} | ?DEFAULTS]).

stop() ->
c4_adder_otp:stop(c4_hit_counter),
mochiweb_http:stop(?MODULE).

loop(Req, DocRoot) ->
"/" ++ Path = Req:get(path),
Hits = c4_adder_otp:add(1, c4_hit_counter),
case Req:get(method) of
M when M =:= 'GET'; M =:= 'HEAD' ->
case Path of
"timer" ->
Response = Req:ok({"text/plain", chunked}),
timer(Response);
"static" ->
Req:ok({"text/plain", "static response"});
"hits" ->
Req:ok({"text/plain",
io_lib:format("Hits: ~p~n", [Hits])});
"nodes" ->
Req:ok({"text/plain",
io_lib:format("~p~n", [nodes()])});
"dump" ->
Req:ok({"text/plain",
io_lib:format("~p~n", [Req:dump()])});
_ ->
Req:serve_file(Path, DocRoot)
end;
_ ->
Req:respond({501, [], ""})
end.

timer(Req) ->
Req:write_chunk(io_lib:format("The time is: ~p~n",
[calendar:local_time()])),
timer:sleep(1000),
timer(Req).
Bob mentioned in the post, that he will eventually "propperly open source it", in the meantime, sources, examples and slides (Erlang introduction) can be found here.

Wednesday, September 12, 2007

ErlyVideo - RTMP / Flash streaming server

I resurrected my attempt of implementing a RTMP / Flash streaming server and turned it into an open source project: ErlyVideo. When I originally wrote that code, sometime last year, it mainly served as practical example for learning Erlang. Streaming actually worked, I could record and playback audio and video from the flashplayer, but the code was ugly, the TCP server was blocking and worst of all, the RTMP protocol is a proprietary thing from Adobe, so I did a clean room implementation, step by step, trial and error, without actually knowing the protocol when I started, so it had to end up in a mess.
Now I cleaned it up a bit and turned it into a non-blocking OTP server application, but it is still just a proof of concept ...