Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added DIME support as per patch from Anders Nygren

git-svn-id: https://erlyaws.svn.sourceforge.net/svnroot/erlyaws/trunk/yaws@1235 9fbdc01b-0d2c-0410-bfb7-fb27d70d8b52
  • Loading branch information...
commit b06d1766b1f7360b760168d188ba94686a25f206 1 parent fe70f74
Claes Wikstrom authored
3  src/Makefile
View
@@ -37,7 +37,8 @@ MODULES=yaws \
haxe yaws_rpc \
yaws_soap_srv yaws_soap_lib \
authmod_gssapi \
- yaws_appmod_cgi
+ yaws_appmod_cgi \
+ yaws_dime
EBIN_FILES=$(MODULES:%=../ebin/%.$(EMULATOR)) ../ebin/yaws.app
151 src/yaws_dime.erl
View
@@ -0,0 +1,151 @@
+%%%-------------------------------------------------------------------
+%%% File : dime.erl
+%%% Author : Anders Nygren <>
+%%% @copyright 2008 Telexpertise de Mexico, S.A. de C.V.
+%%% @version {@vsn}
+%%% @author Anders Nygren <anders.nygren@txm.com.mx>
+%%% @doc
+%%%<pre>
+%%% 0 1 2 3
+%%% 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | |M|M|C| | | |
+%%% | VERSION |B|E|F| TYPE_T| RESRVD| OPTIONS_LENGTH |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | ID_LENGTH | TYPE_LENGTH |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | DATA_LENGTH |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | /
+%%% / OPTIONS + PADDING /
+%%% / |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | /
+%%% / ID + PADDING /
+%%% / |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | /
+%%% / TYPE + PADDING /
+%%% / |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%% | /
+%%% / DATA + PADDING /
+%%% / |
+%%% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+%%%<pre>
+%%%
+%%% Created : 7 Apr 2008 by Anders Nygren <>
+%%%-------------------------------------------------------------------
+-module(yaws_dime).
+
+%% API
+-export([encode/2,
+ decode/1,
+ pad_len/1]).
+
+
+-include_lib("kernel/include/file.hrl").
+
+-define(VERSION1, 1).
+-define(T_UNCHANGED, 0).
+-define(T_MEDIA_TYPE, 1).
+-define(T_ABS_URI, 2).
+-define(T_UNKNOWN, 3).
+-define(T_NONE, 4).
+-define(SOAP_URI, "http://schemas.xmlsoap.org/soap/envelope").
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function:
+%% Description:
+%%--------------------------------------------------------------------
+encode(Req, []) ->
+ encode_part(1, 1, 0, ?T_ABS_URI, <<"">>, <<"">>, <<?SOAP_URI>>, Req);
+encode(Req, As) ->
+ [encode_part(1, 0, 0, ?T_ABS_URI, <<"">>, <<"">>, <<?SOAP_URI>>, Req)|
+ encode_attachments(As)].
+
+encode_attachments([{attachment, Id, Type, File}]) ->
+ encode_part(0, 1, 0, ?T_ABS_URI, <<"">>, Id, Type, File);
+encode_attachments([{attachment, Id, Type, File} | As]) ->
+ [encode_part(0, 0, 0, ?T_ABS_URI, <<"">>, Id, Type, File)|
+ encode_attachments(As)].
+
+encode_part(MB, ME, CF, TypeT, Opts, ID, Type, Data) ->
+ Opts_len = size_of(Opts),
+ Opts_pad = pad_len(Opts_len),
+ Id_len = size_of(ID),
+ Id_pad = pad_len(Id_len),
+ Type_len = size_of(Type),
+ Type_pad = pad_len(Type_len),
+ Data_len = size_of(Data),
+ Data_pad = pad_len(Data_len),
+ Data1 = get_data(Data),
+ <<?VERSION1:5, MB:1, ME:1, CF:1, TypeT:4, 0:4,
+ Opts_len:1/big-integer-unit:16,
+ Id_len:1/big-integer-unit:16,
+ Type_len:1/big-integer-unit:16,
+ Data_len:1/big-integer-unit:32,
+ Opts:Opts_len/binary-unit:8, 0:Opts_pad/integer-unit:8,
+ ID:Id_len/binary-unit:8, 0:Id_pad/integer-unit:8,
+ Type:Type_len/binary-unit:8, 0:Type_pad/integer-unit:8,
+ Data1:Data_len/binary-unit:8, 0:Data_pad/integer-unit:8>>.
+
+pad_len(Len) ->
+ case Len rem 4 of
+ 0 ->
+ 0;
+ N ->
+ 4-N
+ end.
+
+size_of(X) when is_list(X) ->
+ length(X);
+size_of(X) when is_binary(X)->
+ size(X);
+size_of({file, File}) ->
+ {ok,R} = file:read_file_info(File),
+ R#file_info.size.
+
+get_data({file, File}) ->
+ {ok, Data} = file:read_file(File),
+ Data;
+get_data(Data) ->
+ Data.
+%%--------------------------------------------------------------------
+%% @doc Decode a DIME encoded message.
+%%--------------------------------------------------------------------
+decode(Msg) ->
+ decode_recs(Msg,[]).
+
+decode_recs(<<>>, Acc) ->
+ Acc;
+decode_recs(Msg, Acc) ->
+ case decode_rec(Msg) of
+ {_ME=0, Opts, ID, Type, Data, More} ->
+ decode_recs(More, [{Opts, ID, Type, Data}|Acc]);
+ {_ME=1, Opts, ID, Type, Data, _More} ->
+ lists:reverse([{Opts, ID, Type, Data}|Acc])
+ end.
+
+decode_rec(<<?VERSION1:5, _MB:1, ME:1, _CF:1, _Type_T:4, _Res:4,
+ Opt_Len:1/big-integer-unit:16,
+ ID_Len:1/big-integer-unit:16,
+ Type_Len:1/big-integer-unit:16,
+ Data_Len:1/big-integer-unit:32,
+ Rest/binary>>) ->
+ Opt_pad = pad_len(Opt_Len),
+ Id_pad = pad_len(ID_Len),
+ Type_pad = pad_len(Type_Len),
+ Data_pad = pad_len(Data_Len),
+ <<Opts:Opt_Len/binary-unit:8, _:Opt_pad/binary-unit:8,
+ ID:ID_Len/binary-unit:8, _:Id_pad/binary-unit:8,
+ Type:Type_Len/binary-unit:8, _:Type_pad/binary-unit:8,
+ Data:Data_Len/binary-unit:8, _:Data_pad/binary-unit:8,
+ More/binary >> = Rest,
+ {ME, Opts, ID, Type, Data, More}.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
36 src/yaws_rpc.erl
View
@@ -109,17 +109,23 @@ parse_request(Args) -> % {{{
end. % }}}
handle_payload(Args, Handler, Type) -> % {{{
- Payload = binary_to_list(Args#arg.clidata),
-% ?Debug("rpc plaintext call ~p ~n", [Payload]),
-
RpcType = recognize_rpc_type(Args),
-
% haXe parameters are URL encoded
- DecodedStr = case RpcType of
- haxe -> yaws_api:url_decode(Payload);
- json -> yaws_api:url_decode(Payload);
- _ -> Payload
- end,
+ {Payload,DecodedStr} =
+ case RpcType of
+ T when T==haxe; T==json ->
+ PL = binary_to_list(Args#arg.clidata),
+ %% ?Debug("rpc plaintext call ~p ~n", [PL]),
+ {PL, yaws_api:url_decode(PL)};
+ soap_dime ->
+ [{_,_,_,Req}|As]=yaws_dime:decode(Args#arg.clidata),
+ {Args#arg.clidata,
+ {binary_to_list(Req),As}};
+ _ ->
+ PL = binary_to_list(Args#arg.clidata),
+ {PL, PL}
+ %% ?Debug("rpc plaintext call ~p ~n", [PL])
+ end,
case decode_handler_payload(RpcType, DecodedStr) of
{ok, DecodedPayload, ID} ->
% ?Debug("client2erl decoded call ~p ~n", [DecodedPayload]),
@@ -133,8 +139,12 @@ handle_payload(Args, Handler, Type) -> % {{{
%%% "X-Haxe-Remoting" HTTP header, then the "SOAPAction" header,
%%% and if those are absent we assume the request is JSON.
recognize_rpc_type(Args) ->
- OtherHeaders = ((Args#arg.headers)#headers.other),
- recognize_rpc_hdr([{X,Y,yaws:to_lower(Z),Q,W} || {X,Y,Z,Q,W} <- OtherHeaders]).
+ case (Args#arg.headers)#headers.content_type of
+ "application/dime" -> soap_dime;
+ _ ->
+ OtherHeaders = ((Args#arg.headers)#headers.other),
+ recognize_rpc_hdr([{X,Y,yaws:to_lower(Z),Q,W} || {X,Y,Z,Q,W} <- OtherHeaders])
+ end.
recognize_rpc_hdr([{_,_,"x-haxe-remoting",_,_}|_]) -> haxe;
recognize_rpc_hdr([{_,_,"soapaction",_,_}|_]) -> soap;
@@ -231,7 +241,7 @@ get_expire(M, F) ->
_ -> false
end.
-callback_fun(M, F, Args, Payload, SessionValue, soap) ->
+callback_fun(M, F, Args, Payload, SessionValue, RpcType) when RpcType==soap; RpcType==soap_dime ->
fun() -> yaws_soap_srv:handler(Args, {M,F}, Payload, SessionValue) end;
callback_fun(M, F, Args, Payload, SessionValue, _RpcType) ->
fun() -> M:F(Args#arg.state, Payload, SessionValue) end.
@@ -313,6 +323,8 @@ decode_handler_payload(haxe, [$_, $_, $x, $= | HaxeStr]) ->
decode_handler_payload(haxe, _HaxeStr) ->
{error, missing_haxe_prefix};
+decode_handler_payload(soap_dime, Payload) ->
+ {ok, Payload, undefined};
decode_handler_payload(soap, Payload) ->
{ok, Payload, undefined}.
13 src/yaws_soap_srv.erl
View
@@ -154,6 +154,19 @@ code_change(_OldVsn, State, _Extra) ->
%%% Internal functions
%%--------------------------------------------------------------------
+request(State, {M,F} = Id, {Req, Attachments}, SessionValue, Action) ->
+ {ok, Model} = get_model(State, Id),
+ case catch yaws_soap_lib:parseMessage(Req, Model) of
+ {ok, Header, Body} ->
+ %% call function
+ result(Model, catch apply(M, F, [Header, Body,
+ Action, SessionValue,
+ Attachments]));
+ {error, Error} ->
+ cli_error(Error);
+ OtherError ->
+ srv_error(io_lib:format("Error parsing message: ~p", [OtherError]))
+ end;
request(State, {M,F} = Id, Payload, SessionValue, Action) ->
{ok, Model} = get_model(State, Id),
Umsg = (catch erlsom_lib:toUnicode(Payload)),
Please sign in to comment.
Something went wrong with that request. Please try again.