Skip to content

Commit

Permalink
Core: new 'service root' feature.
Browse files Browse the repository at this point in the history
When a request arrives to Duda, it tries to match to which Virtual Host
should be assigned, after that it check which Web Services are registered
under that Virtual Host. So having multiple Web Services under the same
Virtual Host is possible defining different URI addresses for each one
based on their short name, e.g:

   app1 -> http://host1:port/app1/
   app2 -> hhtp://host1:port/app2/

The 'service root' feature allow to define a service it selfs as
'Service Root', which means that it will own the Virtual Host and others
Web Services will not be used (despites they are loaded). So when using
this feature the URI address becomes root and the short name of the
web service is not longer required, so if 'app1' defines it self as
'service root' it will be accessed through:

   http://host1:port/

The way to use this feature can be through the configuration or through
a hard call in duda_main():

1. Web Service Configuration:

   on the Virtual Host configuration, set the 'Root' key with value 'on'
   or 'off', e.g:

   [WEB_SERVICE]
       Enable on
       Root   on

   setting the key to 'on' means the service is root.

2. Setup through duda_main():

   When starting the service invoke the following method:

     conf->service_root();

Both options are valid, just note that using both ways at same time the
option monkey#2 will override any setup made by the setup on monkey#1.

Signed-off-by: Eduardo Silva <[email protected]>
  • Loading branch information
edsiper committed Dec 31, 2013
1 parent 1c8407f commit b36bfd0
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 33 deletions.
74 changes: 51 additions & 23 deletions src/duda.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,8 @@ int duda_request_set_method(duda_request_t *dr)
}


int duda_request_parse(struct session_request *sr,
int duda_request_parse(struct web_service *web_service,
struct session_request *sr,
struct duda_request *dr)
{
short int last_field = MAP_WS_APP_NAME;
Expand Down Expand Up @@ -668,11 +669,18 @@ int duda_request_parse(struct session_request *sr,
val_len = len - i;
end = len;
}

switch (last_field) {
case MAP_WS_APP_NAME:
dr->appname.data = sr->uri_processed.data + i;
dr->appname.len = val_len;
if (web_service->is_root == MK_FALSE) {
dr->appname.data = sr->uri_processed.data + i;
dr->appname.len = val_len;
}
else {
dr->appname.data = web_service->name.data;
dr->appname.len = web_service->name.len;
last_field = MAP_WS_METHOD;
end = i - 1;
}
last_field = MAP_WS_INTERFACE;
break;
case MAP_WS_INTERFACE:
Expand All @@ -684,6 +692,7 @@ int duda_request_parse(struct session_request *sr,
dr->method.data = sr->uri_processed.data + i;
dr->method.len = val_len;
last_field = MAP_WS_PARAM;

if(duda_request_set_method(dr) == -1) {
return -1;
}
Expand Down Expand Up @@ -893,8 +902,7 @@ int duda_service_run(struct plugin *plugin,
duda_qs_parse(dr);

/* Parse request for 'Duda Map' format */
if ((duda_request_parse(sr, dr) != 0) || (!dr->_method)) {

if ((duda_request_parse(web_service, sr, dr) != 0) || (!dr->_method)) {
/* Static Map */
if (duda_map_static_check(dr) == 0) {
return 0;
Expand Down Expand Up @@ -987,38 +995,58 @@ int _mkp_stage_30(struct plugin *plugin, struct client_session *cs,
struct vhost_services *vs_entry, *vs_match=NULL;
struct web_service *web_service;

/* we don't care about '/' request */
if (sr->uri_processed.len > 1) {

/* Check for a DDR request */
if (document_root.data && strncmp(sr->uri_processed.data, "/ddr", 4) == 0) {
duda_override_docroot(sr, 4, document_root.data, document_root.len);
return MK_PLUGIN_RET_NOT_ME;
/* Match virtual host */
mk_list_foreach(head, &services_list) {
vs_entry = mk_list_entry(head, struct vhost_services, _head);
if (sr->host_conf == vs_entry->host) {
vs_match = vs_entry;
break;
}
}

/* Match virtual host */
mk_list_foreach(head, &services_list) {
vs_entry = mk_list_entry(head, struct vhost_services, _head);
if (sr->host_conf == vs_entry->host) {
vs_match = vs_entry;
break;
}
}
if (!vs_match) {
return MK_PLUGIN_RET_NOT_ME;
}

/*
* Check for a DDR request: a DDR is a fixed path for generic static files
* distributed by Duda I/O, as an example we can mention Twitter Bootstrap
* that is used to render the console interfaces.
*/
if (document_root.data && strncmp(sr->uri_processed.data, "/ddr", 4) == 0) {
duda_override_docroot(sr, 4, document_root.data, document_root.len);
return MK_PLUGIN_RET_NOT_ME;
}

/*
* Check if the current Virtual Host contains a service who wants to
* be Root
*/
if (vs_match->root_service != NULL) {

if (!vs_match) {
/* Run the service directly */
if (duda_service_run(plugin, cs, sr, vs_match->root_service) == 0) {
return MK_PLUGIN_RET_CONTINUE;
}
else {
return MK_PLUGIN_RET_NOT_ME;
}
}

/* Match web service */
/* we don't care about '/' request */
if (sr->uri_processed.len > 1) {
/* Match web service by URI lookup */
web_service = duda_get_service_from_uri(sr, vs_match);
if (!web_service) {
return MK_PLUGIN_RET_NOT_ME;
}

/* Run the web service */
if (duda_service_run(plugin, cs, sr, web_service) == 0) {
return MK_PLUGIN_RET_CONTINUE;
}
}

/* There is nothing we can do... */
return MK_PLUGIN_RET_NOT_ME;
}
52 changes: 48 additions & 4 deletions src/duda_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ int duda_conf_vhost_init()
char *app_datadir;
char *app_logdir;
int app_enabled;
int app_is_root;

struct file_info finfo;

/* vhost services list */
Expand All @@ -231,8 +233,9 @@ int duda_conf_vhost_init()
entry_host = mk_list_entry(head_host, struct host, _head);

vs = mk_api->mem_alloc(sizeof(struct vhost_services));
vs->host = entry_host; /* link virtual host entry */
mk_list_init(&vs->services); /* init services list */
vs->host = entry_host; /* link virtual host entry */
vs->root_service = NULL; /* root web service (optional) */
mk_list_init(&vs->services); /* init services list */

/*
* check vhost 'config' and look for [WEB_SERVICE] sections, we don't use
Expand All @@ -243,8 +246,10 @@ int duda_conf_vhost_init()
section = mk_list_entry(head_section, struct mk_config_section, _head);

if (strcasecmp(section->name, "WEB_SERVICE") == 0) {
app_name = NULL;
/* Initialize temporal keys */
app_name = NULL;
app_enabled = MK_FALSE;
app_is_root = MK_FALSE;
app_docroot = NULL;
app_confdir = NULL;
app_logdir = NULL;
Expand All @@ -253,10 +258,15 @@ int duda_conf_vhost_init()
app_name = mk_api->config_section_getval(section,
"Name",
MK_CONFIG_VAL_STR);

app_enabled = (size_t) mk_api->config_section_getval(section,
"Enabled",
MK_CONFIG_VAL_BOOL);

app_is_root = (size_t) mk_api->config_section_getval(section,
"Root",
MK_CONFIG_VAL_BOOL);

app_docroot = mk_api->config_section_getval(section,
"DocumentRoot",
MK_CONFIG_VAL_STR);
Expand Down Expand Up @@ -339,6 +349,22 @@ int duda_conf_vhost_init()
}
}

/*
* If this web service wants to be Root (the only one who serves
* everything on this virtual host, let the parent head know about
* it.
*/
if (app_is_root == MK_TRUE) {
ws->is_root = MK_TRUE;
vs->root_service = ws;
}
else {
ws->is_root = MK_FALSE;
}

/* Set a reference to the parent vhost_services */
ws->vh_parent = vs;

/* link data to the web services list */
mk_list_add(&ws->_head, &vs->services);
mk_list_add(&ws->_head_loaded, &services_loaded);
Expand Down Expand Up @@ -471,14 +497,32 @@ void duda_conf_service_name(struct web_service *ws, const char *name)
ws->name.len = strlen(name);
}

/*
* @METHOD_NAME: service_root
* @METHOD_DESC: By default when starting a web service, the way to access it is
* through it shortname in the URL. Defining a web service as Root, means that it
* owns a Virtual Host, so all further incoming request arriving to the Virtual
* Host will be handled by the web service in question. On using this call, the
* service will be accessed through the root URI '/' (the short name prefix is
* not longer required).
* @METHOD_PROTO: void service_root()
* @METHOD_RETURN: This method do not return any value.
*/
void duda_conf_service_root(struct web_service *ws)
{
ws->is_root = MK_TRUE;
ws->vh_parent->root_service = ws;
}

struct duda_api_conf *duda_conf_object()
{
struct duda_api_conf *c;

c = mk_api->mem_alloc(sizeof(struct duda_api_conf));
c->_force_redirect = duda_conf_force_redirect;
c->_force_redirect = duda_conf_force_redirect;
c->_bind_messages = duda_conf_bind_messages;
c->_service_name = duda_conf_service_name;
c->_service_root = duda_conf_service_root;

return c;
}
10 changes: 7 additions & 3 deletions src/duda_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ struct mk_list services_list;
struct mk_list services_loaded;

struct vhost_services {
struct host *host;
struct mk_list services;
struct mk_list _head;
struct host *host; /* virtual host reference with Monkey */
struct web_service *root_service; /* optional root service */
struct mk_list services; /* list of web services under this VH */
struct mk_list _head; /* head for services_loaded HEAD */
};

int duda_conf_set_confdir(struct web_service *ws, const char *dir);
Expand All @@ -67,6 +68,9 @@ struct duda_api_conf {

#define service_name(n) _service_name(self, n)
void (*_service_name) (struct web_service *, const char *);

#define service_root(n) _service_root(self)
void (*_service_root) (struct web_service *);
};

struct duda_api_conf *duda_conf_object();
Expand Down
12 changes: 9 additions & 3 deletions src/duda_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@

int duda_map_static_check(duda_request_t *dr)
{
int len;
int offset = 0;
int port_redirect = 0;
char *buf;
char *host;
char *location = 0;
int port_redirect = 0;
int len;
struct mk_list *head;
struct session_request *sr = dr->sr;
struct duda_map_static_cb *st;
Expand All @@ -49,7 +50,12 @@ int duda_map_static_check(duda_request_t *dr)
continue;
}

if (strncmp(sr->uri_processed.data + dr->ws_root->name.len + 1,
/* Check URI offset for name matching */
if (dr->ws_root->is_root == MK_FALSE) {
offset = dr->ws_root->name.len + 1;
}

if (strncmp(sr->uri_processed.data + offset,
st->path, st->path_len) == 0) {

/*
Expand Down
4 changes: 4 additions & 0 deletions src/duda_webservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct web_service {
mk_pointer logdir; /* directory to store logs */

int enabled;
int is_root;
int url_force_redirect;
int bind_messages;

Expand Down Expand Up @@ -65,6 +66,9 @@ struct web_service {
/* node entry associated with services_list */
struct mk_list _head;

/* reference to the parent vhost_services entry */
struct vhost_services *vh_parent;

/* node entry associated with services_loaded */
struct mk_list _head_loaded;

Expand Down

0 comments on commit b36bfd0

Please sign in to comment.