Skip to content
Newer
Older
100644 204 lines (180 sloc) 8.4 KB
a4c1476 @baphled Added units for reimplementing CWIGA along with the implementation code.
authored Mar 28, 2009
1 %%----------------------------------------------------------------
2 %%% @author Yomi Colledge <yomi@boodah.net>
3 %%% @doc Web interface for Chatterl
4 %%%
5 %%% Chatterl Web Gateway, allowing Web based clients to interact
6 %%% with Chatterl over a RESTful API.
7 %%%
8 %%% Allows Chatterl to interface with any web-based interface
9 %%% Using JSON and XML, sending the requests off to the chatterl_serv
10 %%% module.
11 %%%
12 %%% All calls to CWIGA will only be allowed via a specified IP, which
13 %%% will be defined with the configuration file.
14 %%% @end
15 %%% @copyright 2008-2009 Yomi Colledge
16 %%%---------------------------------------------------------------
17 -module(cwiga).
18
19 -behaviour(gen_server).
20
21 %% API
22 -export([start_link/1,stop/0]).
23
24 -define(APP, "CWIGA").
25 %% gen_server callbacks
26 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
27 terminate/2, code_change/3]).
28
29 -define(SERVER, ?MODULE).
30 -record(state, {}).
31
32 %%====================================================================
33 %% API
34 %%====================================================================
35 %%--------------------------------------------------------------------
36 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
37 %% Description: Starts the server
38 %%--------------------------------------------------------------------
39 start_link(Port) ->
40 gen_server:start_link({global, ?SERVER}, ?MODULE, [Port], []).
41
42 stop() ->
43 gen_server:call({global, ?SERVER}, stop, infinity).
44
45 dispatch_requests(Req) ->
46 [Path|Ext] = string:tokens(Req:get(path),"."),
47 Method = Req:get(method),
48 Post = Req:parse_post(),
49 io:format("~p request for ~p with post: ~p~n", [Method, Path, Post]),
50 Response = handle(Method, Path, get_content_type(Ext), Post),
51 Req:respond(Response).
52
c30144e @baphled Refacting POST handle calls, also refactored status accordingly so su…
authored Mar 28, 2009
53 handle('POST',"/groups/send/" ++ Group,ContentType,Post) ->
54 [{"client",Sender},{"msg",Message}] = Post,
55 Response = chatterl_mid_man:group_send(ContentType,{Group,Sender,Message}),
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
56 handle_response(Response,ContentType);
90ecc71 @baphled Refactored groups & mid_man so that messages are only sent if the cli…
authored Mar 28, 2009
57 handle('POST',"/groups/join/" ++ Group,ContentType,Post) ->
58 [{"client",Client}] = Post,
59 Response = chatterl_mid_man:group_join(ContentType,{Group,Client}),
60 handle_response(Response,ContentType);
aa48def @baphled General refactoring and cleanup, will finish implementing post relate…
authored Mar 28, 2009
61 handle('POST',"/groups/leave/" ++ Group,ContentType,Post) ->
62 [{"client",Client}] = Post,
63 Response = chatterl_mid_man:group_leave(ContentType,{Group,Client}),
64 handle_response(Response,ContentType);
1c0f3d1 @baphled Implemented connect & disconnect functionality for CWIGA
authored Mar 28, 2009
65 handle('GET',"/users/connect/" ++ Client,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
66 handle_response(chatterl_mid_man:connect(ContentType,Client),ContentType);
1c0f3d1 @baphled Implemented connect & disconnect functionality for CWIGA
authored Mar 28, 2009
67 handle('GET',"/users/disconnect/" ++ Client,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
68 handle_response(chatterl_mid_man:disconnect(ContentType,Client),ContentType);
2d32186 @baphled Added more get functionality to CWIGA, will finish off later.
authored Mar 28, 2009
69 handle('GET',"/users/list/" ++ Group,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
70 handle_response(chatterl_mid_man:user_list(ContentType,Group),ContentType);
494591e @baphled Adding list users units and implementation code for the reimplementat…
authored Mar 28, 2009
71 handle('GET',"/users/list",ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
72 handle_response(chatterl_mid_man:user_list(ContentType),ContentType);
2d32186 @baphled Added more get functionality to CWIGA, will finish off later.
authored Mar 28, 2009
73 handle('GET',"/users/poll/" ++ Client,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
74 handle_response(chatterl_mid_man:user_poll(ContentType,Client),ContentType);
0eab948 @baphled Completed CWIGA GET calls, will do PUT's (create,login,send calls) to…
authored Mar 28, 2009
75 handle('GET',"/users/groups/" ++ Client,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
76 handle_response(chatterl_mid_man:user_groups(ContentType,Client),ContentType);
0eab948 @baphled Completed CWIGA GET calls, will do PUT's (create,login,send calls) to…
authored Mar 28, 2009
77 handle('GET',"/groups/poll/" ++ Group,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
78 handle_response(chatterl_mid_man:group_poll(ContentType,Group),ContentType);
2d32186 @baphled Added more get functionality to CWIGA, will finish off later.
authored Mar 28, 2009
79 handle('GET',"/groups/list",ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
80 handle_response(chatterl_mid_man:group_list(ContentType),ContentType);
0eab948 @baphled Completed CWIGA GET calls, will do PUT's (create,login,send calls) to…
authored Mar 28, 2009
81 handle('GET',"/groups/info/" ++ Group,ContentType,_Post) ->
ae90a96 @baphled Refactored CWIGA to take advantage of the new handle_responses/2 method
authored Mar 28, 2009
82 handle_response(chatterl_mid_man:group_info(ContentType,Group),ContentType);
494591e @baphled Adding list users units and implementation code for the reimplementat…
authored Mar 28, 2009
83 handle(_,Path,ContentType,_) ->
a4c1476 @baphled Added units for reimplementing CWIGA along with the implementation code.
authored Mar 28, 2009
84 Response = message_handler:get_response_body(ContentType,
85 message_handler:build_carrier("error", "Unknown command: " ++Path)),
90ecc71 @baphled Refactored groups & mid_man so that messages are only sent if the cli…
authored Mar 28, 2009
86 error(Response,ContentType).
1c0f3d1 @baphled Implemented connect & disconnect functionality for CWIGA
authored Mar 28, 2009
87
a4c1476 @baphled Added units for reimplementing CWIGA along with the implementation code.
authored Mar 28, 2009
88 %%====================================================================
89 %% gen_server callbacks
90 %%====================================================================
91
92 %%--------------------------------------------------------------------
93 %% Function: init(Args) -> {ok, State} |
94 %% {ok, State, Timeout} |
95 %% ignore |
96 %% {stop, Reason}
97 %% Description: Initiates the server
98 %%--------------------------------------------------------------------
99 init([Port]) ->
100 process_flag(trap_exit, true),
101 mochiweb_http:start([{port, Port}, {loop, fun dispatch_requests/1}]),
102 erlang:monitor(process,mochiweb_http),
103 {ok, #state{}}.
104
105 %%--------------------------------------------------------------------
106 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
107 %% {reply, Reply, State, Timeout} |
108 %% {noreply, State} |
109 %% {noreply, State, Timeout} |
110 %% {stop, Reason, Reply, State} |
111 %% {stop, Reason, State}
112 %% Description: Handling call messages
113 %%--------------------------------------------------------------------
114 handle_call(stop, _From, State) ->
115 io:format("Processing shut down ~s~n", [?APP]),
116 {stop, normal, stopped, State};
117 handle_call(_Request, _From, State) ->
118 Reply = ok,
119 {reply, Reply, State}.
120
121 %%--------------------------------------------------------------------
122 %% Function: handle_cast(Msg, State) -> {noreply, State} |
123 %% {noreply, State, Timeout} |
124 %% {stop, Reason, State}
125 %% Description: Handling cast messages
126 %%--------------------------------------------------------------------
127 handle_cast(_Msg, State) ->
128 {noreply, State}.
129
130 %%--------------------------------------------------------------------
131 %% Function: handle_info(Info, State) -> {noreply, State} |
132 %% {noreply, State, Timeout} |
133 %% {stop, Reason, State}
134 %% Description: Handling all non call/cast messages
135 %%--------------------------------------------------------------------
136 handle_info({'DOWN', _Ref, _Process, {mochiweb_http, Host}, Reason}, State) ->
137 io:format("Unable to start mochiweb on ~s:~nReason: ~s~n",[Host,Reason]),
138 {stop,normal,State};
139 handle_info(_Info, State) ->
140 {noreply, State}.
141
142 %%--------------------------------------------------------------------
143 %% Function: terminate(Reason, State) -> void()
144 %% Description: This function is called by a gen_server when it is about to
145 %% terminate. It should be the opposite of Module:init/1 and do any necessary
146 %% cleaning up. When it returns, the gen_server terminates with Reason.
147 %% The return value is ignored.
148 %%--------------------------------------------------------------------
149 terminate(_Reason, _State) ->
150 io:format("Shutting down ChatterlWeb on: ~s...~n",[node(self())]),
151 mochiweb_http:stop(),
152 ok.
153
154 %%--------------------------------------------------------------------
155 %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
156 %% Description: Convert process state when code is changed
157 %%--------------------------------------------------------------------
158 code_change(_OldVsn, State, _Extra) ->
159 {ok, State}.
160
161 %%--------------------------------------------------------------------
162 %%% Internal functions
163 %%--------------------------------------------------------------------
164
165 %%--------------------------------------------------------------------
166 %% @private
167 %% @doc
168 %%
169 %% Gets the content type, used to help CWIGA to determine what format
170 %% to respond in.
171 %% @spec get_content_type(Type) -> string()
172 %%
173 %% @end
174 %%--------------------------------------------------------------------
175 get_content_type(Type) ->
176 case Type of
177 ["json"] ->
178 ["text/json"];
179 ["xml"] ->
180 ["text/xml"];
181 _ -> ["text/json"]
182 end.
90ecc71 @baphled Refactored groups & mid_man so that messages are only sent if the cli…
authored Mar 28, 2009
183
184 check_json_response(Json) ->
185 {struct,[{<<"chatterl">>,{struct,[{<<"response">>,{struct,[Response]}}]}}]} = mochijson2:decode(Json),
186 Response.
187
188 error(Response,ContentType) ->
189 {404, [{"Content-Type", ContentType}], list_to_binary(Response)}.
190
191 failure(Response,ContentType) ->
192 {501, [{"Content-Type", ContentType}], list_to_binary(Response)}.
193
194 success(Response,ContentType) ->
195 {200, [{"Content-Type", ContentType}], list_to_binary(Response)}.
196
197
198 handle_response(Response,ContentType) ->
199 case check_json_response(Response) of
200 {<<"failure">>,_} -> failure(Response,ContentType);
201 {<<"success">>,_} -> success(Response,ContentType);
202 {<<"error">>,_} -> error(Response,ContentType)
203 end.
Something went wrong with that request. Please try again.