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} -> | |
66 | luaserver ! {webserver, self(), connection_aborted}, | |
67 | gen_tcp:close(Conn), | |
68 | exit(socket_error); | |
69 | Any -> | |
70 | ?DEBUG("?? Webserver socket got: ~p", [Any]), | |
71 | throw(unknown_socket_data) | |
72 | end. | |
73 | ||
74 | send_request_to_lua(String) -> | |
75 | - | true = is_pid(whereis(luaserver)), |
75 | + | luaserver ! {webserver, self(), new_connection, String}. |
76 | - | whereis(luaserver) ! {webserver, self(), new_connection, String}. |
76 | + | |
77 | create_response(Str) -> | |
78 | string_to_response(Str). | |
79 | ||
80 | string_to_response(Str) -> | |
81 | B = iolist_to_binary(Str), | |
82 | iolist_to_binary( | |
83 | io_lib:fwrite( | |
84 | "HTTP/1.0 200 OK\nContent-Type: text/html\nAccess-Control-Allow-Origin: *\nContent-Length: ~p\n\n~s", | |
85 | [size(B), B])). | |
86 | ||
87 | flood_activity(IP, Request, Score) -> | |
88 | floodbot ! {self(), {flood_activity, Score, IP, Request}}. |