SHOW:
|
|
- or go back to the newest paste.
| 1 | -module(webserver). | |
| 2 | -export([start/1, loop/1]). | |
| 3 | ||
| 4 | -include("debug.hrl").
| |
| 5 | ||
| 6 | start(_) -> | |
| 7 | Port = 8080, | |
| 8 | {ok, Sock} = gen_tcp:listen(Port, [{active, false}, {packet, line}, {reuseaddr, true}]),
| |
| 9 | loop(Sock). | |
| 10 | ||
| 11 | loop(Sock) -> | |
| 12 | case gen_tcp:accept(Sock) of | |
| 13 | {ok, ConnSock} ->
| |
| 14 | spawn(fun () -> handle(ConnSock) end); | |
| 15 | Err -> | |
| 16 | error({webserver_sock_accept,Err})
| |
| 17 | end, | |
| 18 | receive | |
| 19 | code_change -> | |
| 20 | ?MODULE:loop(Sock); | |
| 21 | Unknown -> | |
| 22 | error({unhandled, Unknown})
| |
| 23 | after 0 -> | |
| 24 | loop(Sock) | |
| 25 | end. | |
| 26 | ||
| 27 | handle(Conn) -> | |
| 28 | Timeout = 20000 + (erlang:crc32(pid_to_list(self())) band 8191), | |
| 29 | Got = get_request(Conn), | |
| 30 | % ?DEBUG("Got request: ~p", [Got]),
| |
| 31 | {ok, {IP,_Port}} = inet:peername(Conn),
| |
| 32 | flood_activity(IP, Got, 1), | |
| 33 | send_request_to_lua(Got), | |
| 34 | Reply = handle_loop(Conn, IP, Timeout, Got), | |
| 35 | gen_tcp:send(Conn, create_response(Reply)), | |
| 36 | gen_tcp:close(Conn), | |
| 37 | exit('replied').
| |
| 38 | ||
| 39 | handle_loop(Conn, IP, Timeout, Got) -> | |
| 40 | receive | |
| 41 | {flooding,_FloodInfo} ->
| |
| 42 | "<h2>Flooding attempt detected from this address, sorry...<p>Please leave for a few minutes, otherwise you'll be kept locked out.</h2>"; | |
| 43 | {http_reply, Body} -> Body;
| |
| 44 | {flood_activity, Score} ->
| |
| 45 | flood_activity(IP, Got, Score), | |
| 46 | handle_loop(Conn, IP, Timeout, Got); | |
| 47 | Dunno -> | |
| 48 | error({websocket_dunno, Dunno})
| |
| 49 | after Timeout -> | |
| 50 | luaserver ! {webserver, self(), connection_aborted},
| |
| 51 | "IDLE" | |
| 52 | end. | |
| 53 | ||
| 54 | get_request(Conn) -> | |
| 55 | RevParts = get_request(Conn, []), | |
| 56 | lists:concat(lists:reverse(RevParts)). | |
| 57 | ||
| 58 | get_request(Conn, RevParts) -> | |
| 59 | Part = gen_tcp:recv(Conn, 0, 5000), | |
| 60 | case Part of | |
| 61 | {ok,"\r\n"} -> %konec requestu
| |
| 62 | RevParts; | |
| 63 | {ok, Bytes} ->
| |
| 64 | get_request(Conn, [Bytes | RevParts]); | |
| 65 | - | {error, _Err} ->
|
| 65 | + | {error, Err} ->
|
| 66 | luaserver ! {webserver, self(), connection_aborted},
| |
| 67 | gen_tcp:close(Conn), | |
| 68 | - | exit(socket_error); |
| 68 | + | logger:log([socket], {socket_error, Err}),
|
| 69 | exit(normal); | |
| 70 | - | ?DEBUG("?? Webserver socket got: ~p", [Any]),
|
| 70 | + | |
| 71 | - | throw(unknown_socket_data) |
| 71 | + | logger:log([socket,critical], {unknown_from_socket, Any}), %Really shouldn't happen
|
| 72 | exit(normal) | |
| 73 | end. | |
| 74 | ||
| 75 | send_request_to_lua(String) -> | |
| 76 | luaserver ! {webserver, self(), new_connection, String}.
| |
| 77 | ||
| 78 | create_response(Str) -> | |
| 79 | string_to_response(Str). | |
| 80 | ||
| 81 | string_to_response(Str) -> | |
| 82 | B = iolist_to_binary(Str), | |
| 83 | iolist_to_binary( | |
| 84 | io_lib:fwrite( | |
| 85 | "HTTP/1.0 200 OK\nContent-Type: text/html\nAccess-Control-Allow-Origin: *\nContent-Length: ~p\n\n~s", | |
| 86 | [size(B), B])). | |
| 87 | ||
| 88 | flood_activity(IP, Request, Score) -> | |
| 89 | floodbot ! {self(), {flood_activity, Score, IP, Request}}. |