Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 213 lines (188 sloc) 8.057 kB
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
1 %% Copyright (C) 2003 Joakim Grebenö <jocke@gleipnir.com>.
2 %% All rights reserved.
3 %%
4 %% Copyright (C) 2006 Gaspar Chilingarov <nm@web.am>
5 %% Gurgen Tumanyan <barbarian@armkb.com>
6 %% All rights reserved.
7 %%
8 %%
9 %% Redistribution and use in source and binary forms, with or without
10 %% modification, are permitted provided that the following conditions
455578a @vinoski major trailing whitespace cleanup
vinoski authored
11 %% are met:
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
12 %%
13 %% 1. Redistributions of source code must retain the above copyright
455578a @vinoski major trailing whitespace cleanup
vinoski authored
14 %% notice, this list of conditions and the following disclaimer.
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
15 %% 2. Redistributions in binary form must reproduce the above
16 %% copyright notice, this list of conditions and the following
17 %% disclaimer in the documentation and/or other materials provided
18 %% with the distribution.
19 %%
20 %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 -module(yaws_xmlrpc).
0be3c7e @klacke untabified all of yaws
authored
33 %%-author('jocke@gleipnir.com').
455578a @vinoski major trailing whitespace cleanup
vinoski authored
34 -author("Gaspar Chilingarov <nm@web.am>, Gurgen Tumanyan <barbarian@armkb.com>").
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
35 -export([handler/2]).
36 -export([handler_session/2, handler_session/3]).
37
0be3c7e @klacke untabified all of yaws
authored
38 %%-define(debug, 1).
39 %%-include("../../yaws/src/yaws_debug.hrl").
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
40
1aad2b4 Corrected reference to yaws_api.hrl so that they now compile properly.
Tobbe Tornquist authored
41 -include("../include/yaws_api.hrl").
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
42
43
455578a @vinoski major trailing whitespace cleanup
vinoski authored
44 %%% ######################################################################
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
45 %%% public interface
46 %%%
47
48 %%%
49 %%% use XMLRPC handler which can automagically start sessions if we need
50 %%%
51 handler_session(Args, Handler) ->
52 handler_session(Args, Handler, 'SID').
53
54 %%%
55 %%% allow overriding session Cookie name
56 %%%
57 handler_session(Args, Handler, SID_NAME) when is_atom(SID_NAME) ->
58 handler_session(Args, Handler, atom_to_list(SID_NAME));
59
60 handler_session(Args, Handler, SID_NAME) ->
61 handler(Args, Handler, {session, SID_NAME}).
62
63 %%%
64 %%% xmlrpc:handler compatible call
65 %%% no session support will be available
66 handler(Args, Handler) ->
67 handler(Args, Handler, simple).
68
69
455578a @vinoski major trailing whitespace cleanup
vinoski authored
70 %%% ######################################################################
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
71 %%% private functions
72 %%%
73
74 %%% we should be called from yaws page or module
6e96a14 @klacke indendation cleanup
authored
75 handler(Args, Handler, Type) when is_record(Args, arg) ->
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
76 case parse_request(Args) of
0be3c7e @klacke untabified all of yaws
authored
77 ok ->
78 handle_payload(Args, Handler, Type);
79 {status, StatusCode} -> %% cannot parse request
80 send(Args, StatusCode)
6e96a14 @klacke indendation cleanup
authored
81 end.
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
82
83 -define(ERROR_LOG(Reason),
0be3c7e @klacke untabified all of yaws
authored
84 error_logger:error_report({?MODULE, ?LINE, Reason})).
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
85
86 %%%
87 %%% check that request come in reasonable protocol version and reasonable method
88 %%%
0be3c7e @klacke untabified all of yaws
authored
89 parse_request(Args) -> %% {{{
455578a @vinoski major trailing whitespace cleanup
vinoski authored
90 case {(Args#arg.req)#http_request.method,
0be3c7e @klacke untabified all of yaws
authored
91 (Args#arg.req)#http_request.version} of
92 {'POST', {1,0}} ->
93 %% ?Debug("HTTP Version 1.0~n", []),
94 ok;
95 {'POST', {1,1}} ->
96 %% ?Debug("HTTP Version 1.1~n", []),
97 ok;
98 {'POST', _HTTPVersion} -> {status, 505};
99 {_Method, {1,1}} -> {status, 501};
100 _ -> {status, 400}
101 end. %% }}}
102
6e96a14 @klacke indendation cleanup
authored
103 handle_payload(Args, Handler, Type) ->
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
104 Payload = binary_to_list(Args#arg.clidata),
0be3c7e @klacke untabified all of yaws
authored
105 %% ?Debug("xmlrpc encoded call ~p ~n", [Payload]),
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
106 case xmlrpc_decode:payload(Payload) of
0be3c7e @klacke untabified all of yaws
authored
107 {ok, DecodedPayload} ->
108 %% ?Debug("xmlrpc decoded call ~p ~n", [DecodedPayload]),
109 eval_payload(Args, Handler, DecodedPayload, Type);
110 {error, Reason} ->
206b4d9 @vinoski delete chatty messages, make yaws_server upgrade-friendly (Klarna)
vinoski authored
111 ErrMsg = xmlrpc_http:handle_xmlprc_error(Payload, Reason),
112 send(Args, 400, ErrMsg, [])
6e96a14 @klacke indendation cleanup
authored
113 end.
0be3c7e @klacke untabified all of yaws
authored
114
115 %%%%%%
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
116 %%% call handler/3 and provide session support
6e96a14 @klacke indendation cleanup
authored
117 eval_payload(Args, {M, F}, Payload, {session, CookieName}) ->
455578a @vinoski major trailing whitespace cleanup
vinoski authored
118 {SessionValue, Cookie} =
119 case yaws_api:find_cookie_val(CookieName,
0be3c7e @klacke untabified all of yaws
authored
120 (Args#arg.headers)#headers.cookie) of
121 [] -> % have no session started, just call handler
122 {undefined, undefined};
123 Cookie2 -> %% get old session data
124 case yaws_api:cookieval_to_opaque(Cookie2) of
125 {ok, OP} ->
126 yaws_api:cookieval_to_opaque(Cookie2),
127 {OP, Cookie2};
128 {error, _ErrMsg} -> %% cannot get corresponding session
129 {undefined, undefined}
130 end
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
131 end,
6e96a14 @klacke indendation cleanup
authored
132
0be3c7e @klacke untabified all of yaws
authored
133 case catch M:F(Args#arg.state, Payload, SessionValue) of
134 {'EXIT', Reason} ->
135 ?ERROR_LOG({M, F, {'EXIT', Reason}}),
136 send(Args, 500);
137 {error, Reason} ->
138 ?ERROR_LOG({M, F, Reason}),
139 send(Args, 500);
140 {false, ResponsePayload} ->
141 %% do not have updates in session data
142 encode_send(Args, 200, ResponsePayload, []);
455578a @vinoski major trailing whitespace cleanup
vinoski authored
143 {true, _NewTimeout, NewSessionValue, ResponsePayload} ->
0be3c7e @klacke untabified all of yaws
authored
144 %% be compatible with xmlrpc module
145 CO = case NewSessionValue of
146 undefined when Cookie == undefined -> []; %% nothing to do
147 undefined -> %% rpc handler requested session delete
455578a @vinoski major trailing whitespace cleanup
vinoski authored
148 yaws_api:delete_cookie_session(Cookie), [];
0be3c7e @klacke untabified all of yaws
authored
149 %% XXX: may be return set-cookie with empty val?
150 _ -> %% any other value will stored in session
151 case SessionValue of
455578a @vinoski major trailing whitespace cleanup
vinoski authored
152 undefined ->
153 %% got session data and should start
0be3c7e @klacke untabified all of yaws
authored
154 %% new session now
155 Cookie1 = yaws_api:new_cookie_session(
156 NewSessionValue),
157 yaws_api:setcookie(
455578a @vinoski major trailing whitespace cleanup
vinoski authored
158 CookieName, Cookie1, "/");
0be3c7e @klacke untabified all of yaws
authored
159 %% return set_cookie header
455578a @vinoski major trailing whitespace cleanup
vinoski authored
160 _ ->
0be3c7e @klacke untabified all of yaws
authored
161 yaws_api:replace_cookie_session(
162 Cookie, NewSessionValue),
163 [] %% nothing to add to yaws data
164 end
165 end,
166 encode_send(Args, 200, ResponsePayload, CO)
6e96a14 @klacke indendation cleanup
authored
167 end;
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
168
169 %%%
170 %%% call handler/2 without session support
171 %%%
6e96a14 @klacke indendation cleanup
authored
172 eval_payload(Args, {M, F}, Payload, simple) ->
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
173 case catch M:F(Args#arg.state, Payload) of
0be3c7e @klacke untabified all of yaws
authored
174 {'EXIT', Reason} ->
175 ?ERROR_LOG({M, F, {'EXIT', Reason}}),
176 send(Args, 500);
177 {error, Reason} ->
178 ?ERROR_LOG({M, F, Reason}),
179 send(Args, 500);
180 {false, ResponsePayload} ->
181 encode_send(Args, 200, ResponsePayload, []);
182 {true, _NewTimeout, _NewState, ResponsePayload} ->
183 encode_send(Args, 200, ResponsePayload, [])
6e96a14 @klacke indendation cleanup
authored
184 end.
0be3c7e @klacke untabified all of yaws
authored
185
186
6e96a14 @klacke indendation cleanup
authored
187 encode_send(Args, StatusCode, Payload, AddOn) ->
0be3c7e @klacke untabified all of yaws
authored
188 %% ?Debug("xmlrpc decoded response ~p ~n", [Payload]),
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
189 case xmlrpc_encode:payload(Payload) of
0be3c7e @klacke untabified all of yaws
authored
190 {ok, EncodedPayload} ->
191 %% ?Debug("xmlrpc encoded response ~p ~n", [EncodedPayload]),
192 send(Args, StatusCode, EncodedPayload, AddOn);
193 {error, Reason} ->
194 ?ERROR_LOG({xmlrpc_encode, payload, Payload, Reason}),
195 send(Args, 500)
6e96a14 @klacke indendation cleanup
authored
196 end.
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
197
6e96a14 @klacke indendation cleanup
authored
198 send(Args, StatusCode) -> send(Args, StatusCode, "", []).
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
199
200 send(Args, StatusCode, Payload, AddOnData) when not is_list(AddOnData) ->
201 send(Args, StatusCode, Payload, [AddOnData]);
202
203 %%%
204 %%% generate valid yaws response
205 send(_Args, StatusCode, Payload, AddOnData) ->
206 A = [
455578a @vinoski major trailing whitespace cleanup
vinoski authored
207 {status, StatusCode},
208 {content, "text/xml", Payload},
0be3c7e @klacke untabified all of yaws
authored
209 {header, {content_length, lists:flatlength(Payload) }}
210 ] ++ AddOnData,
6e96a14 @klacke indendation cleanup
authored
211 A.
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
212
Something went wrong with that request. Please try again.