├── Makefile ├── .hgignore ├── package.mk └── 10-no-cowboy-dependency.patch /Makefile: -------------------------------------------------------------------------------- 1 | include ../umbrella.mk 2 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | ~$ 2 | \.beam$ 3 | ^build/ 4 | ^dist/ 5 | ^cover/ 6 | ^erl_crash.dump$ 7 | ^hash.mk$ 8 | ^erlang-rfc4627-git/ 9 | -------------------------------------------------------------------------------- /package.mk: -------------------------------------------------------------------------------- 1 | APP_NAME:=rfc4627_jsonrpc 2 | DEPS:=mochiweb-wrapper 3 | 4 | UPSTREAM_GIT:=https://github.com/rabbitmq/erlang-rfc4627.git 5 | UPSTREAM_REVISION:=5e67120216b11a2ff5d74e00a789b219d0a3bc36 6 | 7 | WRAPPER_PATCHES:=10-no-cowboy-dependency.patch 8 | 9 | ORIGINAL_APP_FILE=$(CLONE_DIR)/ebin/$(APP_NAME).app 10 | DO_NOT_GENERATE_APP_FILE=true 11 | 12 | ## The path to httpd.hrl has changed in OTP R14A and newer. Detect the 13 | ## change, and supply a compile-time macro definition to allow 14 | ## rfc4627_jsonrpc_inets.erl to adapt to the new path. 15 | ifeq ($(shell erl -noshell -eval 'io:format([list_to_integer(X) || X <- string:tokens(erlang:system_info(version), ".")] < [5,8]), halt().'),true) 16 | PACKAGE_ERLC_OPTS+=-Dinets_pre_r14a 17 | else 18 | ifeq ($(shell erl -noshell -eval 'io:format([list_to_integer(X) || X <- string:tokens(erlang:system_info(version), ".")] < [5,8,2]), halt().'),true) 19 | PACKAGE_ERLC_OPTS+=-Dinets_pre_r14b01 20 | endif 21 | endif 22 | -------------------------------------------------------------------------------- /10-no-cowboy-dependency.patch: -------------------------------------------------------------------------------- 1 | diff --git a/ebin/rfc4627_jsonrpc.app b/ebin/rfc4627_jsonrpc.app 2 | index ef9fe44..e06b46c 100644 3 | --- a/ebin/rfc4627_jsonrpc.app 4 | +++ b/ebin/rfc4627_jsonrpc.app 5 | @@ -9,7 +9,6 @@ 6 | rfc4627_jsonrpc_http, 7 | rfc4627_jsonrpc_inets, 8 | rfc4627_jsonrpc_mochiweb, 9 | - rfc4627_jsonrpc_cowboy, 10 | rfc4627_jsonrpc_registry 11 | ]}, 12 | {registered, []}, 13 | diff --git a/src/rfc4627_jsonrpc_cowboy.erl b/src/rfc4627_jsonrpc_cowboy.erl 14 | deleted file mode 100644 15 | index 2af0fd8..0000000 16 | --- a/src/rfc4627_jsonrpc_cowboy.erl 17 | +++ /dev/null 18 | @@ -1,113 +0,0 @@ 19 | -%% JSON-RPC for Cowboy 20 | -%%--------------------------------------------------------------------------- 21 | -%% @author Erik Timan 22 | -%% @author Tony Garnock-Jones 23 | -%% @author LShift Ltd. 24 | -%% @copyright 2007-2010, 2011, 2012 Tony Garnock-Jones and 2007-2010 LShift Ltd. 25 | -%% @license 26 | -%% 27 | -%% Permission is hereby granted, free of charge, to any person 28 | -%% obtaining a copy of this software and associated documentation 29 | -%% files (the "Software"), to deal in the Software without 30 | -%% restriction, including without limitation the rights to use, copy, 31 | -%% modify, merge, publish, distribute, sublicense, and/or sell copies 32 | -%% of the Software, and to permit persons to whom the Software is 33 | -%% furnished to do so, subject to the following conditions: 34 | -%% 35 | -%% The above copyright notice and this permission notice shall be 36 | -%% included in all copies or substantial portions of the Software. 37 | -%% 38 | -%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 39 | -%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 40 | -%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 41 | -%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 42 | -%% BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 43 | -%% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 44 | -%% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 45 | -%% SOFTWARE. 46 | -%%--------------------------------------------------------------------------- 47 | -%% 48 | -%% @reference the Cowboy github page 49 | -%% 50 | -%% @doc Support for serving JSON-RPC via Cowboy. 51 | -%% 52 | -%% Familiarity with writing Cowboy applications is assumed. 53 | -%% 54 | -%% == Basic Usage == 55 | -%% 56 | -%%
    57 | -%%
  • Register your JSON-RPC services as usual.
  • 58 | -%%
  • Decide on your `AliasPrefix' (see {@link rfc4627_jsonrpc_http:invoke_service_method/4}).
  • 59 | -%%
  • When a Cowboy request arrives at your application, call {@link handle/2} with your `AliasPrefix' and the request.
  • 60 | -%%
61 | -%% 62 | -%% It's as simple as that - if the request's URI path matches the 63 | -%% `AliasPrefix', it will be decoded and the JSON-RPC service it names 64 | -%% will be invoked. 65 | - 66 | --module(rfc4627_jsonrpc_cowboy). 67 | - 68 | --export([handle/2]). 69 | - 70 | -normalize(X) when is_atom(X) -> 71 | - string:to_lower(atom_to_list(X)); 72 | -normalize(X) when is_binary(X) -> 73 | - string:to_lower(binary_to_list(X)); 74 | -normalize(X) when is_list(X) -> 75 | - string:to_lower(X). 76 | - 77 | -%% @spec (string(), #http_req{}) -> no_match | {ok, #http_req{}} 78 | -%% 79 | -%% @doc If the request matches `AliasPrefix', the corresponding 80 | -%% JSON-RPC service is invoked, and an `{ok, #http_req{}}' is returned; 81 | -%% otherwise, `no_match' is returned. 82 | -%% 83 | -%% Call this function from your Cowboy HTTP handler's `handle' 84 | -%% function, as follows: 85 | -%% 86 | -%% ``` 87 | -%% Req2 = case rfc4627_jsonrpc_cowboy:handle("/rpc", Req) of 88 | -%% no_match -> 89 | -%% handle_non_jsonrpc_request(Req); 90 | -%% {ok, Reponse} -> 91 | -%% Response 92 | -%% end 93 | -%% ''' 94 | -%% 95 | -%% where `handle_non_jsonrpc_request' does the obvious thing for 96 | -%% non-JSON-RPC requests. 97 | -handle(AliasPrefix, Req) -> 98 | - {BinaryPath, _} = cowboy_req:path(Req), 99 | - Path = binary_to_list(BinaryPath), 100 | - {QSVals, _} = cowboy_req:qs_vals(Req), 101 | - QueryObj = {obj, [{binary_to_list(K), V} || {K,V} <- QSVals]}, 102 | - {Hdrs, _} = cowboy_req:headers(Req), 103 | - HeaderObj = {obj, [{normalize(K), V} || {K,V} <- Hdrs]}, 104 | - {PeerAddr, _} = cowboy_req:peer_addr(Req), 105 | - Peer = list_to_binary(inet_parse:ntoa(PeerAddr)), 106 | - {Method, _} = cowboy_req:method(Req), 107 | - RequestInfo = {obj, [{"http_method", Method}, 108 | - {"http_query_parameters", QueryObj}, 109 | - {"http_headers", HeaderObj}, 110 | - {"remote_peername", Peer}, 111 | - {"scheme", <<"http">>}]}, 112 | - {ok, Body, _} = cowboy_req:body(Req), 113 | - 114 | - case rfc4627_jsonrpc_http:invoke_service_method(AliasPrefix, 115 | - Path, 116 | - RequestInfo, 117 | - Body) of 118 | - no_match -> 119 | - no_match; 120 | - {ok, ResultEnc, ResponseInfo} -> 121 | - {obj, ResponseHeaderFields} = 122 | - rfc4627:get_field(ResponseInfo, "http_headers", {obj, []}), 123 | - StatusCode = 124 | - rfc4627:get_field(ResponseInfo, "http_status_code", 200), 125 | - Headers = [{list_to_binary(K), V} || {K,V} <- ResponseHeaderFields], 126 | - RespType = [{<<"Content-Type">>, rfc4627:mime_type()}], 127 | - cowboy_req:reply(StatusCode, 128 | - Headers ++ RespType, 129 | - ResultEnc, 130 | - Req) 131 | - end. 132 | --------------------------------------------------------------------------------