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