View difference between Paste ID: yasSZka2 and tT5W5PH8
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}}.