Erlang/OTP Forums

Author Message

<  Advanced Erlang/OTP  ~  Yaws FORM action as "module:function"...

seancharles
Posted: Sun Aug 12, 2007 2:19 pm Reply with quote
User Joined: 18 Jul 2007 Posts: 57
With respect to a problem I am still having I realised that you *can* use a function :module in a form action without having to modify yaws. The simple answer is to set up an appmod and then use the url in the action as shown below.

This is my favourite yaws 'hack' so far and the more I use yaws the more I like it. I LIKE IT!

All you do is put in a line in your server config, myself I used /f for forms, /p for pages and /a for any web API functionality I am exposing, so a form could be:
Code:

<form action="/f/contact:validate" method="post">

and you can then pass any extra data to your handler by putting more stuff after the module:function, like so:
Code:

<form action="/f/contact:validate/any/data/1/2/3/you/want!" method="post">

So, having set up an appmod line, you need the handler and here's mine, it lets yaws handle any errors if you specify a non-existant module.function pair:

Code:

-module(form_poster).
-author("sean.charles@objitsu.com").
-include("/usr/local/lib/yaws/include/yaws_api.hrl").
-compile([export_all]).


reload()->ok.

%% -------------------------------------------------------------------
%% A generic form post that allows you to call a module:function once
%% you add this your config file:
%%
%%    appmods = <f,form_poster>
%%
%% Then in a form you put the action as:
%%
%%    <form action="/f/module:function/anything/you/like" ... >
%%
out( A ) ->
    [ Action | Data ] = string:tokens( A#arg.appmoddata, "/" ),
    %%
    %% Assume that the FIRST value is the module:function to call, if
    %% anything breaks, shovel out a 404 (later!)
    %%
    [ Module | Function ] = string:tokens( Action, ":" ),
    AMod = list_to_atom( Module ),
    AFun = list_to_atom( hd(Function)),
    AMod:AFun( A ).


It works like a charm!

It still falls down with respect to my previous posting here but I thought it might be useful to share the method, yaws is full of hidden treasures like this... it provides really useful features and then you can go and play Lego with it!

Rock on!
Smile[/url]

Now back to the original problem! Life!
View user's profile Send private message
Mazen
Posted: Mon Aug 13, 2007 7:43 am Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Yes that thing is really cool but how do you tackle the security aspect? What if I would call /f/init:stop ? I think you already thought about this but I'm just letting everyone else know if they read this Smile A good way would be to have a list of allowed "services" what you can call.

One details....

instead of
Code:

[ Module | Function ] = string:tokens( Action, ":" ),
...
AFun = list_to_atom(hd(Function)),


you should patternmatch on
Code:
[Module,Function] = ...

instead

More readable, you can remove the hd() call and you program more offensivly which is a good thing Smile.

Also I would propose a highlevel catch when you make the Amod:AFun() call. This is so that you can beautify the return value incase you want to show this on a webpage.


Really nice work though Smile I am impressed! Very Happy
View user's profile Send private message
Mazen
Posted: Mon Aug 13, 2007 7:44 am Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Just noticed your 404 comment Razz My bad Very Happy
View user's profile Send private message
martin
Posted: Mon Aug 13, 2007 9:00 am Reply with quote
User Joined: 06 Aug 2006 Posts: 11
There is an over all issue here tho that you aught to think about, list_to_atom. It creates a security whole more sublime than the init:* erlang:* etc. By doing list to atom on any strings that satisfy STRING:STRING you can simply write a script that hits that url with random junk in STRING:STRING meaning you exhaust the atom limitation.

This same issue can be seen in any place where list_to_atom is used over a unknown set of strings. see erlang:list_to_existing_atom

--
Martin
http://www.erlang-consulting.com
View user's profile Send private message
seancharles
Posted: Mon Aug 13, 2007 11:26 am Reply with quote
User Joined: 18 Jul 2007 Posts: 57
I am a devious bar-steward Martin!
Smile

I already thought of that, that's why in the *real* code I have right now, all module:function calls I receive MUST be in a list (a mnesia table actually) of valid modules that make up my system.

That way, anything not recognised just generates a 404. I have the same approach for my /f /p and /a (forms, pages and actions) modules ie if it ain't on the list it don't get in.

When my system is live I think I may well invite some of you guys to give it a good kicking and see where it hurts! It would be good fun all round I think.

My attitude to development these days, (for the last ten years at least in fact) is that errors are the norm... for a process to run to completion is considered exceptional! So, kung-fu readiness at every step, expect the unexpected and only when you can walk along the rice paper and lift the big f***-off cauldron with your bare forearms can you release your product and leave the monastery. LOL.

Thanks for your feedback, useful as ever.
This is a great forum
Smile
Sean
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum