Hi,

just for keeping the reference and cc: to duda mailing list.

On Sat, Sep 22, 2012 at 3:17 AM, Paul Read <[email protected]> wrote:
> I ran the example:
>
> dudac/dudac -f -w duda-examples/001_hello_world/
>
> and in my browser:
> http://192.168.1.39:2001/hello/
>
> And it worked :-)
>
> But how?
> I can't see how asking for '/hello' causes the page to be displayed when the
> command map->static    references "cb_hello"     - what is the 'cb_'
>
> How does the magic happen please?

Let me explain in brief steps how it works internally:

- When Monkey starts, it looks for the plugins.load configuration
file. On that one it will catch up the duda plugin "monkey-duda.so",
which is a shared library.
- When Duda plugin is loaded, it looks for two configuration files,
the first one is conf/plugins/duda/duda.conf, where it specify the
location of the web services and packages. The second file is the
virtual host file "conf/sites/default" where it specifies which web
service must be loaded. You can see this under the section
[WEB_SERVICE]
- In technical terms, a Duda web service is a shared library loaded by
the Duda plugin:

           Monkey -> Duda Plugin -> Duda Web Services

* Now about the web service internals:

Every web service must have a duda_main() function, when the web
service is loaded, it performs a symbols lookup and invoke that
function, this is done from duda.c:69 (duda_service_register()). But
there is a trick here, duda_main is an expanded macro, when you type
duda_main it's replaced by a different content by the compiler, refer
to webservice.h:78 :

#define duda_main()
    _duda_bootstrap(struct duda_api_objects *api) {
        /* API Objects */
        monkey   = api->monkey;
        map      = api->map;
        msg      = api->msg;
.....

so from Duda core what really happens is to load the symbol
referencing to _duda_bootstrap:

           service_init = (int (*)()) duda_load_symbol(ws->handler,
"_duda_bootstrap");

so finally the service_init variable, its a pointer referencing the
service function. so we invoke _duda_bootstrap() remotely through
service_init(..);

If you look at the API when mapping static URLS, you do something like this:

    map->static_add("/", "cb_hello");

what does static add, is to register in a linked list the URL to map
and the callback function *name*. check that the parameters are simple
strings. So from duda core when the HTTP request arrives, it checks
the static URLs registered, it will find "/" associated to a
"cb_hello" function name, so the proper way to invoke the callback is
to have a prior reference to that function through a symbol lookup
(made in duda.c:91) , e.g:

                 static_cb->callback = duda_load_symbol(ws->handler,
static_cb->cb_name);

for short static_cb->cb_name contains "cb_hello", so that function is
referenced in static_cb->callback. When the request arrives we just do
static_cb->callback(); and that function in the web service is
triggered.

BTW, the "cb_" prefix is used just to reference a "callback" function,
its not mandatory but we can consider it a good practice to prefix
your callbacks functions with cb_ .

In order to accomplish the callback stuff we need to do a mix of
pointers to structs and functions so at the beginning it can be
confusing... the good part is that it works properly. So please feel
free to ask or send us your comments,

cheers!

>
> --
> Paul
>
> http://www.readiescards.co.uk
>
>
> _______________________________________________
> Monkey mailing list
> [email protected]
> http://lists.monkey-project.com/listinfo/monkey
>



-- 
Eduardo Silva
http://edsiper.linuxchile.cl
http://www.monkey-project.com
_______________________________________________
Monkey mailing list
[email protected]
http://lists.monkey-project.com/listinfo/monkey

Reply via email to