Recommend Me


Jeudi 16 octobre 2008

Tiny Tiny Erlang Web Server

  1. % Copyright (c) 2008 Gregoire Lejeune
  2. %  
  3. % Permission is hereby granted, free of charge, to any person obtaining a copy
  4. % of this software and associated documentation files (the "Software"), to
  5. % deal in the Software without restriction, including without limitation the
  6. % rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. % sell copies of the Software, and to permit persons to whom the Software is
  8. % furnished to do so, subject to the following conditions:
  9. %  
  10. % The above copyright notice and this permission notice shall be included in
  11. % all copies or substantial portions of the Software.
  12. %    
  13. % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  16. % THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  17. % IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. % CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19.  
  20. -module(rserver).
  21. -author(’gregoire.lejeune@free.fr’).
  22. -compile(export_all).
  23.  
  24. -define(RSERVER_VERSION, "0.0.2").
  25.  
  26. start(Port, DocRoot) ->
  27.   {ok, ListenSocket} = gen_tcp:listen(Port, [binary, {packet, 0}, {active, false}]),
  28.   io:format("** RServer version ~s Started (port ~p | root ~p)~n", [?RSERVER_VERSION, Port, DocRoot]),
  29.   loop(ListenSocket, DocRoot).
  30. start() ->
  31.   case file:consult("rserver.conf") of
  32.     {ok, C} ->
  33.       io:format("** Read config from ./rserver.conf~n"),
  34.       [{port, P},{rootdir, D}] = C,
  35.       start(P, D);
  36.     {error, _} ->
  37.       case file:consult(string:concat(os:getenv("HOME"), "/rserver.conf")) of
  38.         {ok, C} ->
  39.           io:format("** Read config from $HOME/rserver.conf~n"),
  40.           [{port, P},{rootdir, D}] = C,
  41.           start(P, D);
  42.         {error, _} ->
  43.           io:format("Error: no configuration file found!")
  44.       end
  45.   end.
  46.  
  47. loop(ListenSocket, DocRoot) ->
  48.   case gen_tcp:accept(ListenSocket) of
  49.     {ok, Socket} ->
  50.       spawn(fun() ->
  51.         handle_connection(Socket, DocRoot)
  52.       end),
  53.       loop(ListenSocket, DocRoot);
  54.     {error, Reason} ->
  55.       io:format("Error: ~p~n", [Reason])
  56.   end.
  57.  
  58. handle_connection(Socket, DocRoot) ->
  59.   try communication(Socket, DocRoot)
  60.   catch
  61.     error:Reason ->
  62.       {gen_tcp:send(Socket, io_lib:format("Error: ~p~n", [Reason]))}
  63.   end,
  64.   ok = gen_tcp:close(Socket).
  65.  
  66. communication(Socket, DocRoot) ->
  67.   {ok, Binary} = gen_tcp:recv(Socket, 0),
  68.   {ok, [R|Z]} = regexp:split( binary_to_list(Binary), "\r\n" ),
  69.   {ok, [M,F,P]} = regexp:split( R, " " ),
  70.   case F =:= "/" of
  71.     true -> File = string:concat(DocRoot, "/index.html");
  72.     false -> File = string:concat(DocRoot, F)
  73.   end,
  74.   {WD, JJ, MD, AA, HH, MN, SS} = get_local_time(),
  75.   case file:read_file(File) of
  76.     {ok, Html} ->
  77.       io:format("~p - - [~s, ~p ~s ~p ~p:~p:~p GMT] \"~s ~s ~s\" 200 ~p~n", ["IP", WD, JJ, MD, AA, HH, MN, SS, M, F, P, string:len(binary_to_list(Html))]),
  78.       gen_tcp:send(Socket, io_lib:format("HTTP/1.1 200 OK~nDate: ~s, ~p ~s ~p ~p:~p:~p GMT~nServer: Rserver/1.0.0~n~n~s", [WD, JJ, MD, AA, HH, MN, SS, binary_to_list(Html)]));
  79.     {error, _} ->
  80.       io:format("[~s, ~p ~s ~p ~p:~p:~p GMT] 404 Error : ~s ~s not found~n", [WD, JJ, MD, AA, HH, MN, SS, M, F]),
  81.       gen_tcp:send(Socket, io_lib:format("HTTP/1.1 404 Not Found~nDate: ~s, ~p ~s ~p ~p:~p:~p GMT~nServer: Rserver/1.0.0~n~n~s", [WD, JJ, MD, AA, HH, MN, SS, "<html><body>404 error</body></html>"]))
  82.   end.  
  83.  
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%
  85.  
  86. day(0) -> "Mon";
  87. day(1) -> "Tue";
  88. day(2) -> "Wed";
  89. day(3) -> "Thu";
  90. day(4) -> "Fri";
  91. day(5) -> "Sat";
  92. day(6) -> "Sun".
  93.  
  94. month(1) -> "Jan";
  95. month(2) -> "Feb";
  96. month(3) -> "Mar";
  97. month(4) -> "Apr";
  98. month(5) -> "May";
  99. month(6) -> "Jun";
  100. month(7) -> "Jul";
  101. month(8) -> "Aug";
  102. month(9) -> "Sep";
  103. month(10) -> "Oct";
  104. month(11) -> "Nov";
  105. month(12) -> "Dec".
  106.  
  107. get_local_time() ->
  108.   D = calendar:local_time(),
  109.   [{{AA,MM,JJ},{HH,MN,SS}}] = calendar:local_time_to_universal_time_dst(D),
  110.   WD = day(calendar:day_of_the_week(AA, MM, JJ)),
  111.   MD = month(MM),
  112.   {WD, JJ, MD, AA, HH, MN, SS}.
• • •

Un commentaire »

  1. [...] J’ai fait quelques modifications dans mon mini serveur HTTP. [...]

    Ping par greg.rubyfr.net»Blog Archive » Tiny Tiny Erlang Web Server v0.2.0 — Jeudi 16 octobre 2008 @ 23:16

RSS des commentairesTrackBack URI

Laisser un commentaire

You must be logged in to post a comment.

Powered by: WordPress • Template adapted from the Simple Green' Wench theme - RSS