Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

159 lines (128 sloc) 7.173 kB
% ==========================================================================================================
% MISULTIN - Example: Running Misultin from a gen_server.
%
% >-|-|-(°>
%
% Copyright (C) 2009, Roberto Ostinelli <roberto@ostinelli.net>
% All rights reserved.
%
% BSD License
%
% Redistribution and use in source and binary forms, with or without modification, are permitted provided
% that the following conditions are met:
%
% * Redistributions of source code must retain the above copyright notice, this list of conditions and the
% following disclaimer.
% * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
% the following disclaimer in the documentation and/or other materials provided with the distribution.
% * Neither the name of the authors nor the names of its contributors may be used to endorse or promote
% products derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
% TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
% ==========================================================================================================
-module(misultin_gen_server).
-behaviour(gen_server).
% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
% API
-export([start_link/1, stop/0]).
% records
-record(state, {
port
}).
% macros
-define(SERVER, ?MODULE).
% ============================ \/ API ======================================================================
% Function: {ok,Pid} | ignore | {error, Error}
% Description: Starts the server.
start_link(Port) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).
% Function: -> ok
% Description: Manually stops the server.
stop() ->
gen_server:cast(?SERVER, stop).
% ============================ /\ API ======================================================================
% ============================ \/ GEN_SERVER CALLBACKS =====================================================
% ----------------------------------------------------------------------------------------------------------
% Function: -> {ok, State} | {ok, State, Timeout} | ignore | {stop, Reason}
% Description: Initiates the server.
% ----------------------------------------------------------------------------------------------------------
init([Port]) ->
% trap_exit -> this gen_server needs to be supervised
process_flag(trap_exit, true),
% start misultin & set monitor
misultin:start_link([{port, Port}, {loop, fun(Req) -> handle_http(Req) end}]),
erlang:monitor(process, misultin),
{ok, #state{port = Port}}.
% ----------------------------------------------------------------------------------------------------------
% Function: handle_call(Request, From, State) -> {reply, Reply, State} | {reply, Reply, State, Timeout} |
% {noreply, State} | {noreply, State, Timeout} |
% {stop, Reason, Reply, State} | {stop, Reason, State}
% Description: Handling call messages.
% ----------------------------------------------------------------------------------------------------------
% handle_call generic fallback
handle_call(_Request, _From, State) ->
{reply, undefined, State}.
% ----------------------------------------------------------------------------------------------------------
% Function: handle_cast(Msg, State) -> {noreply, State} | {noreply, State, Timeout} | {stop, Reason, State}
% Description: Handling cast messages.
% ----------------------------------------------------------------------------------------------------------
% manual shutdown
handle_cast(stop, State) ->
{stop, normal, State};
% handle_cast generic fallback (ignore)
handle_cast(_Msg, State) ->
{noreply, State}.
% ----------------------------------------------------------------------------------------------------------
% Function: handle_info(Info, State) -> {noreply, State} | {noreply, State, Timeout} | {stop, Reason, State}
% Description: Handling all non call/cast messages.
% ----------------------------------------------------------------------------------------------------------
% handle info when misultin server goes down -> take down misultin_gen_server too [the supervisor will take everything up again]
handle_info({'DOWN', _, _, {misultin, _}, _}, State) ->
{stop, normal, State};
% handle_info generic fallback (ignore)
handle_info(_Info, State) ->
{noreply, State}.
% ----------------------------------------------------------------------------------------------------------
% Function: terminate(Reason, State) -> void()
% Description: This function is called by a gen_server when it is about to terminate. When it returns,
% the gen_server terminates with Reason. The return value is ignored.
% ----------------------------------------------------------------------------------------------------------
terminate(_Reason, _State) ->
% stop misultin
misultin:stop(),
terminated.
% ----------------------------------------------------------------------------------------------------------
% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
% Description: Convert process state when code is changed.
% ----------------------------------------------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
% ============================ /\ GEN_SERVER CALLBACKS =====================================================
% ============================ \/ INTERNAL FUNCTIONS =======================================================
% ---------------------------- \/ misultin requests --------------------------------------------------------
handle_http(Req) ->
% get params depending on method
Method = Req:get(method),
case Method of
'GET' ->
Args = Req:parse_qs();
'POST' ->
Args = Req:parse_post()
end,
% build an XML with all parameters and values
BuildXml = fun({Param, Value}, Acc) ->
[lists:flatten(io_lib:format("<param><name>~s</name><value>~s</value></param>", [Param, Value]))|Acc]
end,
Xml = lists:flatten(lists:reverse(lists:foldl(BuildXml, [], Args))),
% output
Req:ok([{"Content-Type", "text/xml"}], "<misultin_test><method>~s</method>~s</misultin_test>", [Method, Xml]).
% ---------------------------- /\ misultin requests --------------------------------------------------------
% ============================ /\ INTERNAL FUNCTIONS =======================================================
Jump to Line
Something went wrong with that request. Please try again.