Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 102 lines (93 sloc) 4.076 kB
47e5a7c @klacke JSON ajax code from Gaspar Chilingarov, I added docs describing an ex…
authored
1 %% Copyright (C) 2006 Gaspar Chilingarov <nm@web.am>
2 %% Gurgen Tumanyan <barbarian@armkb.com>
3 %% All rights reserved.
4 %%
5 %%
6 %% Redistribution and use in source and binary forms, with or without
7 %% modification, are permitted provided that the following conditions
8 %% are met:
9 %%
10 %% 1. Redistributions of source code must retain the above copyright
11 %% notice, this list of conditions and the following disclaimer.
12 %% 2. Redistributions in binary form must reproduce the above
13 %% copyright notice, this list of conditions and the following
14 %% disclaimer in the documentation and/or other materials provided
15 %% with the distribution.
16 %%
17 %% THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 %% OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 %% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 %% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 %% GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 %% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 %% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 %% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 -module(jsonrpc).
30 -author("Gaspar Chilingarov <nm@web.am>, Gurgen Tumanyan <barbarian@armkb.com>").
31 -vsn("2").
32 -export([call/3]).
33 -export([s/2]). % extract element from proplist
34
35 %%%
36 %%% call function calls json-rpc method on remote host
37 %%%
38 %%% URL - remote server url (may use https)
39 %%% Options - option list to be passed to http:request (ssl options ot timeout, for example)
40 %%% Payload -> {call, MethodName, Args} tuple
41 %%% MethodName -> atom
42 %%% Args -> list
43 %%%
44 call(URL, Options, Payload) -> % {{{
45 try
46 {ok, CallPayloadDeep} = encode_call_payload(Payload),
47 CallPayload = lists:flatten(CallPayloadDeep),
48 {ok, Response} = http:request(post,
49 {URL,[{"Content-length",length(CallPayload)}],"application/x-www-form-urlencoded",CallPayload},
50 Options, []),
51
52 RespBody= if (size(Response) == 2) or (size(Response) == 3) -> element(size(Response), Response) end,
53 decode_call_payload(RespBody)
54 catch
55 error:Err->
56 error_logger:error_report([{'json_rpc:call', error}, {error, Err}, {stack, erlang:get_stacktrace()}]),
57 {error,Err}
58 end. % }}}
59
60 %%%
61 %%% json-rpc.org defines such structure for making call
62 %%%
63 %%% {"method":"methodname", "params": object, "id": integer}
64 encode_call_payload({call, Method, Args}) when is_atom(Method) and is_list(Args) -> % {{{
65 ID = element(3, erlang:now()), % id makes sense when there are many requests in same
66 % communication channel and replies can come in random order
67 % here it can be changed to something less expensive
68 Struct = json:encode({struct, [{method, atom_to_list(Method)},
69 {params, {array, Args}},
70 {id, ID}]}),
71 {ok, Struct}. % }}}
72
73 %%%
74 %%% decode response structure
75 %%%
76 %%% {"id":requestID,"result":object,"error":error_description}
77 decode_call_payload(JSonStr) -> %{{{
78 {ok, JSON} = json:decode_string(JSonStr),
79 Result = s(JSON, result),
80 Error = s(JSON, error),
81 % ID = s(JSON, id), % ignored for now
82 if
83 (Error =/= undefined) -> {error, Error};
84 true -> {ok,{response,[Result]}} % make it compliant with xmlrpc response
85 end. %}}}
86
87 %%% lookup element in proplist
88 %%% XXX: are there ready implementation in erlang std library?
89 s ({struct, List}, ElemName) -> % {{{
90 s(List, ElemName);
91
92 s(List, ElemName) when is_list(List) ->
93 case lists:keysearch(ElemName,1,List) of
94 {value,{ElemName,Val}} ->
95 Val;
96 _ ->
97 undefined
98 end.
99 % }}}
100
101 % vim: tabstop=4 ft=erlang
Something went wrong with that request. Please try again.