-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_esi.erl
127 lines (108 loc) · 4.18 KB
/
my_esi.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
% filename: my_esi.erl
-module(my_esi).
-export([start/0, stop/0, testValid/0, track/3]).
-include_lib("inets/include/httpd.hrl").
-import(mochijson, [decode/1]).
-define(SUCCESS, "1").
-define(FAILURE, "0").
-define(PROPERTIES_KEY, "properties").
-define(TOKEN_KEY, "token").
-define(EVENT_KEY, "event").
-define(DATA_PREFIX, "data=").
-define(IP_PREFIX, "ip=").
-define(REDIRECT_PREFIX, "redirect=").
-define(IMG_PREFIX, "img=").
-define(CALLBACK_PREFIX, "callback=").
-define(VERBOSE_PREFIX, "verbose=").
-define(OPTIONAL_PREFIXES, [?IP_PREFIX, ?REDIRECT_PREFIX, ?IMG_PREFIX, ?CALLBACK_PREFIX, ?VERBOSE_PREFIX]).
start() ->
inets:start(),
inets:start(httpd, [{port, 8080}, {server_name, "localhost"}, {server_root, "."}, {document_root, "."}, {modules,[mod_esi]}, {erl_script_alias, {"/esi", [my_esi, io]}}]).
stop() ->
[inets:stop(element(1, X), element(2, X)) || X <- inets:services()],
inets:stop().
testValid() -> isValid("data=ew0KICAgICJldmVudCI6ICJTaWduZWQgVXAiLA0KICAgICJwcm9wZXJ0aWVzIjogew0KICAgICAgICAiZGlzdGluY3RfaWQiOiAiMTM3OTMiLA0KICAgICAgICAidG9rZW4iOiAiZTNiYzQxMDAzMzBjMzU3MjI3NDBmYjhjNmY1YWJkZGMiLA0KICAgICAgICAiUmVmZXJyZWQgQnkiOiAiRnJpZW5kIg0KICAgIH0NCn0=").
hasKey(List, Key) when is_list(List) ->
case length(List) /= 0 of
true ->
[Head|Tail] = List,
case hasKey(Head, Key) of
true -> true;
false -> hasKey(Tail, Key)
end;
false -> false
end;
hasKey(Tuple, Key) when is_tuple(Tuple) ->
tuple_size(Tuple) == 2 andalso element(1, Tuple) == Key;
hasKey(false, _Key) ->
false.
writeToFile(Request) -> file:write_file("./log.txt", io_lib:fwrite("~p.\n\n", [Request]), [append]).
getOutermostTuple(Input) ->
Base64Encoded = string:substr(Input, string:str(Input, ?DATA_PREFIX) + string:len(?DATA_PREFIX)),
try
Base64Decoded = base64:decode_to_string(Base64Encoded),
mochijson:decode(Base64Decoded)
catch
_:_ -> false
end.
getOutermostList(OutermostTuple) ->
case is_tuple(OutermostTuple) andalso tuple_size(OutermostTuple) == 2 of
true -> {_, Request} = OutermostTuple, Request;
false -> false
end.
getEventTuple(OutermostList) ->
case is_list(OutermostList) andalso length(OutermostList) == 2 of
true -> [EventTuple|_] = OutermostList, EventTuple;
false -> false
end.
getPropertiesTuple(OutermostList) ->
case is_list(OutermostList) andalso length(OutermostList) == 2 of
true ->
[_|OuterPropList] = OutermostList,
[PropTuple|_] = OuterPropList,
PropTuple;
false -> false
end.
getDataTuple(PropTuple) ->
case is_tuple(PropTuple) andalso tuple_size(PropTuple) == 2 of
true -> {_, DataTuple} = PropTuple, DataTuple;
false -> false
end.
getDataList(DataTuple) ->
case is_tuple(DataTuple) andalso tuple_size(DataTuple) == 2 of
true -> {_, DataList} = DataTuple, DataList;
false -> false
end.
getSeparatedParameters(Input) -> string:tokens(Input, "&").
removePrefix(Input, Prefix) ->
string:substr(Input, string:str(Input, Prefix) + string:len(Prefix)).
getOptionalResponse([]) -> ?SUCCESS;
getOptionalResponse(List) ->
[Option|_] = List,
getOptionalResponse(Option, ?OPTIONAL_PREFIXES).
getOptionalResponse(_Option, []) -> ?SUCCESS;
getOptionalResponse(IP, ?IP_PREFIX) -> IP;
getOptionalResponse(Redirect, ?REDIRECT_PREFIX) -> Redirect;
getOptionalResponse(Img, ?IMG_PREFIX) -> Img;
getOptionalResponse(Callback, ?CALLBACK_PREFIX) -> Callback;
getOptionalResponse(Verbose, ?VERBOSE_PREFIX) -> Verbose;
getOptionalResponse(Option, Prefixes) ->
[Prefix|Tail] = Prefixes,
case string:str(Option, Prefix) == 1 of
true -> getOptionalResponse(removePrefix(Option, Prefix), Prefix);
false -> getOptionalResponse(Option, Tail)
end.
isValid(Input) ->
[Data|Optional] = getSeparatedParameters(Input),
OutermostTuple = getOutermostTuple(Data),
OutermostList = getOutermostList(OutermostTuple),
EventTuple = getEventTuple(OutermostList),
PropertiesTuple = getPropertiesTuple(OutermostList),
DataList = getDataList(getDataTuple(PropertiesTuple)),
case hasKey(EventTuple, ?EVENT_KEY) andalso hasKey(PropertiesTuple, ?PROPERTIES_KEY) andalso hasKey(DataList, ?TOKEN_KEY) of
true -> writeToFile(OutermostTuple), getOptionalResponse(Optional);
false -> ?FAILURE
end.
track(SessionID, _Env, Input) ->
Result = isValid(Input),
mod_esi:deliver(SessionID, Result).