Using the default Erlang installation what is the minimum code needed to produce a "Hello world" producing web server?
-
How is this different from http://stackoverflow.com/questions/2084639/sinatra-style-web-framework-for-erlang ? – Zed Feb 07 '10 at 16:58
-
1@Zed, Zubair is asking for a minimal "hello world" server--it has a single "page" because it is minimal. The question you linked to asks how to make a functional Web app (one-page, but responds to a variety of requests in different ways). I assume the latter will be ajax-y. – jyoungdev Dec 06 '12 at 13:53
6 Answers
Taking "produce" literally, here is a pretty small one. It doesn't even read the request (but does fork on every request, so it's not as minimal possible).
-module(hello).
-export([start/1]).
start(Port) ->
spawn(fun () -> {ok, Sock} = gen_tcp:listen(Port, [{active, false}]),
loop(Sock) end).
loop(Sock) ->
{ok, Conn} = gen_tcp:accept(Sock),
Handler = spawn(fun () -> handle(Conn) end),
gen_tcp:controlling_process(Conn, Handler),
loop(Sock).
handle(Conn) ->
gen_tcp:send(Conn, response("Hello World")),
gen_tcp:close(Conn).
response(Str) ->
B = iolist_to_binary(Str),
iolist_to_binary(
io_lib:fwrite(
"HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: ~p\n\n~s",
[size(B), B])).

- 1,572
- 11
- 15
-
3See `{packet, http}` for `Options` of `gen_tcp:listen` for decoding HTTP headers. – Pindatjuh Jun 27 '11 at 23:05
-
1I was looking at this code, and even though it looks clean, I found an issue. When testing it with Apache Bench, I get a `apr_socket_recv: Connection reset by peer (104)`. it works fine when accessing in a browser, or using curl. Do you have any idea why this is? – Martin Kristiansen Jun 05 '12 at 10:50
-
1
-
1@FelixLange Thanks for this answer Felix.. Could you please explain the code written. It will be very helpful for erlang enthusiasts like me :-) – Exception Feb 17 '13 at 05:56
-
The last `iolist_to_binary/1` in `response/1` is unnecessary. – Hynek -Pichi- Vychodil Jun 15 '15 at 10:01
-
if we starting server only once then why we need to `spawn spawn(fun () -> {ok, Sock} = gen_tcp:listen(Port, [{active, false}]), loop(Sock) end).` it is understandable at handler to give every request a new process. if we want to start one server at a time still we need to spawn above tcp:listen – siddhesh Aug 17 '16 at 11:13
For a web server using only the built in libraries check out inets http_server. When in need of some more power but still with simplicity you should check out the mochiweb library. You can google for loads of example code.

- 8,084
- 8
- 48
- 62

- 5,372
- 1
- 23
- 22
Do you actually want to write a web server in Erlang, or do you want an Erlang web server so that you can create dynamic web content using Erlang?
If the latter, try YAWS. If the former, have a look at the YAWS source code for inspiration

- 6,902
- 28
- 39
-
2I want to make dynamic content, but just wanted to know the bare minimum needed for a web server. I looked at the Yaws source code and my first impression was that alot of code was needed. – yazz.com Feb 05 '10 at 12:10
Another way, similar to the gen_tcp
example above but with less code and already offered as a suggestion, is using the inets library.
%%%
%%% A simple "Hello, world" server in the Erlang.
%%%
-module(hello_erlang).
-export([
main/1,
run_server/0,
start/0
]).
main(_) ->
start(),
receive
stop -> ok
end.
run_server() ->
ok = inets:start(),
{ok, _} = inets:start(httpd, [
{port, 0},
{server_name, "hello_erlang"},
{server_root, "/tmp"},
{document_root, "/tmp"},
{bind_address, "localhost"}
]).
start() -> run_server().
Keep in mind, this exposes your /tmp
directory.
To run, simply:
$ escript ./hello_erlang.erl

- 143
- 1
- 6
For a very easy to use webserver for building restful apps or such check out the gen_webserver behaviour: http://github.com/martinjlogan/gen_web_server.

- 326
- 1
- 7
Just one fix for Felix's answer and it addresses the issues Martin is seeing. Before closing a socket, all data being sent from the client should be received (using for example do_recv
from gen_tcp description).
Otherwise there's a race condition for the browser/proxy sending the HTTP request being quick enough to send the http request before the socket is closed.

- 825
- 10
- 15