Skip to content

HTTPS clone URL

Subversion checkout URL

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