Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Hi #1

Closed
wants to merge 3 commits into from

3 participants

@vkamensky

Please review my commit which fixing the following situation: script is crashing in case of pequest->params is missing.

@tonyg
Owner

Why do you want this change? Wouldn't it be just as easy to pass in [] where required instead of undefined?

This 'undefined' is provided by rfc4627_jsonrpc_http:parse_jsonrpc/5 when no params are specified in POST request:
https://github.com/mrspark/erlang-rfc4627/blob/9fb45432f9bc274690694f0a6933e354b3545955/src/rfc4627_jsonrpc_http.erl#L151
We may fix it there then.

Owner

Hmm, interesting. Reading the 1.1 JSON-RPC spec, it's hard to know what to do. So first off, I think you're right to fix it in rfc4627_jsonrpc_http:parse_jsonrpc/5, but the question then becomes: what should be done? My guess is that absent parameters should be treated like [], exactly as you suggested in this commit. The spec says that params is optional, but then says that if it has a value other than an array or object, the server must reject the request with an error, which seems a bit contradictory.

Let's then support parameterless invocations. Fixed in mrspark/erlang-rfc4627@0080fdd

Owner

Thanks! Applied.

@tonyg
Owner

By the way, thank you for the changes! Most appreciated. I've merged the last two from this list; if you'd like to argue for the first one ("fixing empty params error"), please open another pull request with it. Thanks again.

@tonyg tonyg closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 8, 2011
  1. fixing empty params error

    valeriy authored
Commits on Mar 17, 2011
  1. @evolchek
Commits on Mar 19, 2011
  1. @evolchek

    response type fixed

    evolchek authored
This page is out of date. Refresh to see the latest.
View
21 src/rfc4627_jsonrpc.erl
@@ -164,11 +164,6 @@
%% implementing process at all, the function object could process
%% the request without sending any messages at all.
%%
-%% At the moment, the `rfc4627_jsonrpc' service registry
-%% only allows registration of `gen_server'-based
-%% pid-style services; this restriction will be lifted in a future
-%% release.
-%%
%% To build a service descriptor object with a function handler
%% instead of a pid, call `rfc4627_jsonrpc:service/5'
%% instead of `rfc4627_jsonrpc:service/4':
@@ -180,7 +175,8 @@
%% my_handler(ProcedureNameBin, RequestInfo, Args) -> jsonrpc_response()
%% '''
%%
-%% The resulting service descriptor can be used directly with {@link
+%% The resulting service descriptor can be registered with {@link
+%% register_service/1} as well as used directly with {@link
%% invoke_service_method/8}.
%%
%% @type service() = #service{}. A service description record, as
@@ -220,7 +216,7 @@
-export([start/0, start_link/0]).
--export([lookup_service/1, register_service/2]).
+-export([lookup_service/1, register_service/1, register_service/2]).
-export([gen_object_name/0, system_describe/2]).
-export([jsonrpc_post/3, jsonrpc_post/4, invoke_service_method/8, expand_jsonrpc_reply/2]).
-export([error_response/2, error_response/3, service/4, service/5, proc/2]).
@@ -242,12 +238,18 @@ start_link() ->
lookup_service(Service) ->
gen_server:call(?SERVICE, {lookup_service, Service}).
+%% @spec (service()) -> ok
+%% @doc Registers a JSON-RPC service.
+%%
+%% The name of the service is contained within its service record.
+register_service(ServiceDescription) ->
+ gen_server:call(?SERVICE, {register_service, ServiceDescription}).
+
%% @spec (pid(), service()) -> ok
%% @doc Registers a JSON-RPC service.
%%
%% The name of the service is contained within its service record.
register_service(Pid, ServiceDescription) ->
- %%error_logger:info_msg("Registering ~p as ~p", [Pid, ServiceDescription]),
gen_server:call(?SERVICE, {register_service, Pid, ServiceDescription}).
%% @spec () -> string()
@@ -498,7 +500,6 @@ invoke_service(post, Handler, RequestInfo, ServiceProc, Args, Timeout) ->
invoke_service1(Handler, RequestInfo, ServiceProc, Args, Timeout).
invoke_service1(Handler, RequestInfo, #service_proc{name = Name, params = Params}, Args, Timeout) ->
- %%error_logger:info_msg("JSONRPC invoking ~p:~p(~p)", [Handler, Name, Args]),
case catch run_handler(Handler, Name, RequestInfo, coerce_args(Params, Args), Timeout) of
{'EXIT', {{function_clause, _}, _}} ->
error_response(404, "Undefined procedure", Name);
@@ -515,6 +516,8 @@ run_handler({pid, Pid}, Name, RequestInfo, CoercedArgs, Timeout) ->
run_handler({function, F}, Name, RequestInfo, CoercedArgs, _Timeout) ->
F(Name, RequestInfo, CoercedArgs).
+coerce_args(_Params, undefined) ->
+ [];
coerce_args(_Params, Args) when is_list(Args) ->
Args;
coerce_args(Params, {obj, Fields}) ->
View
2  src/rfc4627_jsonrpc_inets.erl
@@ -161,7 +161,7 @@ do_rpc(#mod{init_data = #init_data{peername = {PeerPort, PeerName}},
{proceed, [{response, {response,
[{code, 200},
{content_length, integer_to_list(length(ResultEnc))},
- {content_type, "text/plain"}%rfc4627:mime_type()}
+ {content_type, rfc4627:mime_type()}
| Headers],
ResultEnc}} | OldData]}
end.
View
14 src/rfc4627_jsonrpc_mochiweb.erl
@@ -99,8 +99,20 @@ handle(AliasPrefix, Req) ->
no_match ->
no_match;
{ok, ResultEnc, ResponseInfo} ->
+
+ DefaultType = rfc4627:mime_type(),
+
+ RespType = case Req:accepts_content_type(DefaultType) of
+ true -> DefaultType;
+ false ->
+ case Req:accepts_content_type("text/plain") of
+ true -> "text/plain";
+ false -> DefaultType
+ end
+ end,
+
{obj, ResponseHeaderFields} =
rfc4627:get_field(ResponseInfo, "http_headers", {obj, []}),
Headers = [{K, binary_to_list(V)} || {K,V} <- ResponseHeaderFields],
- {ok, {200, Headers ++ [{"Content-type", "text/plain"}], ResultEnc}}
+ {ok, {200, Headers ++ [{"Content-type", RespType}], ResultEnc}}
end.
View
4 src/rfc4627_jsonrpc_registry.erl
@@ -64,6 +64,10 @@ handle_call({lookup_service, Service}, _From, State) ->
{reply, ServiceRec, State}
end;
+handle_call({register_service, ServiceDescription = #service{name = Name}}, _From, State) ->
+ ets:insert(?TABLE_NAME, {{service, Name}, ServiceDescription}),
+ {reply, ok, State};
+
handle_call({register_service, Pid, ServiceDescription = #service{name = Name}}, _From, State) ->
SD = ServiceDescription#service{handler = {pid, Pid}},
erlang:monitor(process, Pid),
Something went wrong with that request. Please try again.