summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/afb-hreq.c2
-rw-r--r--src/afb-hreq.h2
-rw-r--r--src/afb-hsrv.c179
-rw-r--r--src/afb-hsrv.h8
-rw-r--r--src/local-def.h7
-rw-r--r--src/main.c46
6 files changed, 137 insertions, 107 deletions
diff --git a/src/afb-hreq.c b/src/afb-hreq.c
index badddd1e..3f95c532 100644
--- a/src/afb-hreq.c
+++ b/src/afb-hreq.c
@@ -380,7 +380,7 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f
}
/* fills the value and send */
- MHD_add_response_header(response, MHD_HTTP_HEADER_CACHE_CONTROL, hreq->session->cacheTimeout);
+ MHD_add_response_header(response, MHD_HTTP_HEADER_CACHE_CONTROL, hreq->cacheTimeout);
MHD_add_response_header(response, MHD_HTTP_HEADER_ETAG, etag);
MHD_queue_response(hreq->connection, status, response);
MHD_destroy_response(response);
diff --git a/src/afb-hreq.h b/src/afb-hreq.h
index c317a7a5..752d06ce 100644
--- a/src/afb-hreq.h
+++ b/src/afb-hreq.h
@@ -19,7 +19,7 @@ struct AFB_session;
struct AFB_clientCtx;
struct afb_hreq {
- struct AFB_session *session;
+ const char *cacheTimeout;
struct MHD_Connection *connection;
enum afb_method method;
const char *version;
diff --git a/src/afb-hsrv.c b/src/afb-hsrv.c
index 334b8b3b..61366552 100644
--- a/src/afb-hsrv.c
+++ b/src/afb-hsrv.c
@@ -57,12 +57,14 @@ struct afb_diralias {
};
struct afb_hsrv {
- struct MHD_Daemon *httpd;
+ unsigned refcount;
struct afb_hsrv_handler *handlers;
+ struct MHD_Daemon *httpd;
struct upoll *upoll;
+ char *cache_to;
};
-static struct upoll *upoll = NULL;
+
static struct afb_hsrv_handler *new_handler(
struct afb_hsrv_handler *head,
@@ -106,7 +108,7 @@ static struct afb_hsrv_handler *new_handler(
}
int afb_hsrv_add_handler(
- AFB_session * session,
+ struct afb_hsrv *hsrv,
const char *prefix,
int (*handler) (struct afb_hreq *, void *),
void *data,
@@ -114,10 +116,10 @@ int afb_hsrv_add_handler(
{
struct afb_hsrv_handler *head;
- head = new_handler(session->handlers, prefix, handler, data, priority);
+ head = new_handler(hsrv->handlers, prefix, handler, data, priority);
if (head == NULL)
return 0;
- session->handlers = head;
+ hsrv->handlers = head;
return 1;
}
@@ -200,7 +202,7 @@ static int handle_alias(struct afb_hreq *hreq, void *data)
return afb_hreq_reply_file(hreq, da->dirfd, &hreq->tail[1]);
}
-int afb_hsrv_add_alias(AFB_session * session, const char *prefix, const char *alias, int priority)
+int afb_hsrv_add_alias(struct afb_hsrv *hsrv, const char *prefix, const char *alias, int priority)
{
struct afb_diralias *da;
int dirfd;
@@ -216,7 +218,7 @@ int afb_hsrv_add_alias(AFB_session * session, const char *prefix, const char *al
da->directory = alias;
da->lendir = strlen(da->directory);
da->dirfd = dirfd;
- if (afb_hsrv_add_handler(session, prefix, handle_alias, da, priority))
+ if (afb_hsrv_add_handler(hsrv, prefix, handle_alias, da, priority))
return 1;
free(da);
}
@@ -224,7 +226,7 @@ int afb_hsrv_add_alias(AFB_session * session, const char *prefix, const char *al
return 0;
}
-void afb_hsrv_reply_error(struct MHD_Connection *connection, unsigned int status)
+static void reply_error(struct MHD_Connection *connection, unsigned int status)
{
char *buffer;
int length;
@@ -272,11 +274,11 @@ static int access_handler(
int rc;
struct afb_hreq *hreq;
enum afb_method method;
- AFB_session *session;
+ struct afb_hsrv *hsrv;
struct afb_hsrv_handler *iter;
const char *type;
- session = cls;
+ hsrv = cls;
hreq = *recordreq;
if (hreq == NULL) {
/* create the request */
@@ -292,7 +294,7 @@ static int access_handler(
goto bad_request;
/* init the request */
- hreq->session = cls;
+ hreq->cacheTimeout = hsrv->cache_to;
hreq->connection = connection;
hreq->method = method;
hreq->version = version;
@@ -311,7 +313,7 @@ static int access_handler(
goto internal_error;
return MHD_YES;
} else if (strcasestr(type, JSON_CONTENT) == NULL) {
- afb_hsrv_reply_error(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE);
+ reply_error(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE);
return MHD_YES;
}
}
@@ -339,7 +341,7 @@ static int access_handler(
}
/* search an handler for the request */
- iter = session->handlers;
+ iter = hsrv->handlers;
while (iter) {
if (afb_hreq_unprefix(hreq, iter->prefix, iter->length)) {
if (iter->handler(hreq, iter->data))
@@ -355,11 +357,11 @@ static int access_handler(
return MHD_YES;
bad_request:
- afb_hsrv_reply_error(connection, MHD_HTTP_BAD_REQUEST);
+ reply_error(connection, MHD_HTTP_BAD_REQUEST);
return MHD_YES;
internal_error:
- afb_hsrv_reply_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR);
+ reply_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR);
return MHD_YES;
}
@@ -380,61 +382,43 @@ static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t
return MHD_YES;
}
-static int my_default_init(AFB_session * session)
+/* infinite loop */
+static void hsrv_handle_event(struct MHD_Daemon *httpd)
{
- int idx;
-
- if (!afb_hsrv_add_handler(session, session->config->rootapi, afb_hreq_websocket_switch, NULL, 20))
- return 0;
-
- if (!afb_hsrv_add_handler(session, session->config->rootapi, afb_hreq_rest_api, NULL, 10))
- return 0;
-
- for (idx = 0; session->config->aliasdir[idx].url != NULL; idx++)
- if (!afb_hsrv_add_alias (session, session->config->aliasdir[idx].url, session->config->aliasdir[idx].path, 0))
- return 0;
+ MHD_run(httpd);
+}
- if (!afb_hsrv_add_alias(session, "", session->config->rootdir, -10))
- return 0;
+int afb_hsrv_set_cache_timeout(struct afb_hsrv *hsrv, int duration)
+{
+ int rc;
+ char *dur;
- if (!afb_hsrv_add_handler(session, session->config->rootbase, afb_hreq_one_page_api_redirect, NULL, -20))
+ rc = asprintf(&dur, "%d", duration);
+ if (rc < 0)
return 0;
+ free(hsrv->cache_to);
+ hsrv->cache_to = dur;
return 1;
}
-/* infinite loop */
-static void hsrv_handle_event(struct MHD_Daemon *httpd)
-{
- MHD_run(httpd);
-}
-
-int afb_hsrv_start(AFB_session * session)
+int _afb_hsrv_start(struct afb_hsrv *hsrv, uint16_t port, unsigned int connection_timeout)
{
+ struct upoll *upoll;
struct MHD_Daemon *httpd;
const union MHD_DaemonInfo *info;
- if (!my_default_init(session)) {
- printf("Error: initialisation of httpd failed");
- return 0;
- }
-
- if (verbosity) {
- printf("AFB:notice Waiting port=%d rootdir=%s\n", session->config->httpdPort, session->config->rootdir);
- printf("AFB:notice Browser URL= http:/*localhost:%d\n", session->config->httpdPort);
- }
-
httpd = MHD_start_daemon(
MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_TCP_FASTOPEN | MHD_USE_DEBUG | MHD_USE_SUSPEND_RESUME,
- (uint16_t) session->config->httpdPort, /* port */
+ port, /* port */
new_client_handler, NULL, /* Tcp Accept call back + extra attribute */
- access_handler, session, /* Http Request Call back + extra attribute */
- MHD_OPTION_NOTIFY_COMPLETED, end_handler, session,
- MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int)15, /* 15 seconds */
+ access_handler, hsrv, /* Http Request Call back + extra attribute */
+ MHD_OPTION_NOTIFY_COMPLETED, end_handler, hsrv,
+ MHD_OPTION_CONNECTION_TIMEOUT, connection_timeout,
MHD_OPTION_END); /* options-end */
if (httpd == NULL) {
- printf("Error: httpStart invalid httpd port: %d", session->config->httpdPort);
+ printf("Error: httpStart invalid httpd port: %d", (int)port);
return 0;
}
@@ -453,17 +437,94 @@ int afb_hsrv_start(AFB_session * session)
}
upoll_on_readable(upoll, (void*)hsrv_handle_event);
- session->httpd = httpd;
+ hsrv->httpd = httpd;
+ hsrv->upoll = upoll;
+ return 1;
+}
+
+void _afb_hsrv_stop(struct afb_hsrv *hsrv)
+{
+ if (hsrv->upoll)
+ upoll_close(hsrv->upoll);
+ hsrv->upoll = NULL;
+ if (hsrv->httpd != NULL)
+ MHD_stop_daemon(hsrv->httpd);
+ hsrv->httpd = NULL;
+}
+
+struct afb_hsrv *afb_hsrv_create()
+{
+ struct afb_hsrv *result = calloc(1, sizeof(struct afb_hsrv));
+ if (result != NULL)
+ result->refcount = 1;
+ return result;
+}
+
+void afb_hsrv_put(struct afb_hsrv *hsrv)
+{
+ assert(hsrv->refcount != 0);
+ if (!--hsrv->refcount) {
+ _afb_hsrv_stop(hsrv);
+ free(hsrv);
+ }
+}
+
+static int my_default_init(struct afb_hsrv *hsrv, AFB_session * session)
+{
+ int idx;
+
+ if (!afb_hsrv_add_handler(hsrv, session->config->rootapi, afb_hreq_websocket_switch, NULL, 20))
+ return 0;
+
+ if (!afb_hsrv_add_handler(hsrv, session->config->rootapi, afb_hreq_rest_api, NULL, 10))
+ return 0;
+
+ for (idx = 0; session->config->aliasdir[idx].url != NULL; idx++)
+ if (!afb_hsrv_add_alias (hsrv, session->config->aliasdir[idx].url, session->config->aliasdir[idx].path, 0))
+ return 0;
+
+ if (!afb_hsrv_add_alias(hsrv, "", session->config->rootdir, -10))
+ return 0;
+
+ if (!afb_hsrv_add_handler(hsrv, session->config->rootbase, afb_hreq_one_page_api_redirect, NULL, -20))
+ return 0;
+
+ return 1;
+}
+
+int afb_hsrv_start(AFB_session * session)
+{
+ int rc;
+ struct afb_hsrv *hsrv;
+
+ hsrv = afb_hsrv_create();
+ if (hsrv == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ return 0;
+ }
+
+ if (!afb_hsrv_set_cache_timeout(hsrv, session->config->cacheTimeout)
+ || !my_default_init(hsrv, session)) {
+ printf("Error: initialisation of httpd failed");
+ afb_hsrv_put(hsrv);
+ return 0;
+ }
+
+ if (verbosity) {
+ printf("AFB:notice Waiting port=%d rootdir=%s\n", session->config->httpdPort, session->config->rootdir);
+ printf("AFB:notice Browser URL= http:/*localhost:%d\n", session->config->httpdPort);
+ }
+
+ rc = _afb_hsrv_start(hsrv, (uint16_t) session->config->httpdPort, 15);
+ if (!rc)
+ return 0;
+
+ session->hsrv = hsrv;
return 1;
}
void afb_hsrv_stop(AFB_session * session)
{
- if (upoll)
- upoll_close(upoll);
- upoll = NULL;
- if (session->httpd != NULL)
- MHD_stop_daemon(session->httpd);
- session->httpd = NULL;
+ _afb_hsrv_stop(session->hsrv);
}
diff --git a/src/afb-hsrv.h b/src/afb-hsrv.h
index da4fe09a..93b845c1 100644
--- a/src/afb-hsrv.h
+++ b/src/afb-hsrv.h
@@ -16,5 +16,9 @@
limitations under the License.
*/
-int afb_hsrv_start(AFB_session * session);
-void afb_hsrv_stop(AFB_session * session);
+struct afb_hsrv;
+
+extern struct afb_hsrv *afb_hsrv_create();
+
+extern int afb_hsrv_start(AFB_session * session);
+extern void afb_hsrv_stop(AFB_session * session);
diff --git a/src/local-def.h b/src/local-def.h
index fcab6adb..1992b510 100644
--- a/src/local-def.h
+++ b/src/local-def.h
@@ -63,6 +63,7 @@ struct AFB_config
AFB_aliasdir *aliasdir; // alias mapping for icons,apps,...
};
+struct afb_hsrv;
struct afb_hsrv_handler;
struct MHD_Daemon;
@@ -71,12 +72,8 @@ struct AFB_session
struct AFB_config *config; // pointer to current config
// List of commands to execute
int background; // run in backround mode
- int foreground; // run in forground mode
- char *cacheTimeout; // http require timeout to be a string
- struct MHD_Daemon *httpd; // structure for httpd handler
- int fakemod; // respond to GET/POST request without interacting with sndboard
int readyfd; // a #fd to signal when ready to serve
- struct afb_hsrv_handler *handlers;
+ struct afb_hsrv *hsrv;
};
diff --git a/src/main.c b/src/main.c
index 4ea70f96..aa4b84c3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -46,7 +46,6 @@
#define SET_VERBOSE 1
#define SET_BACKGROUND 2
#define SET_FORGROUND 3
-#define SET_FAKE_MOD 4
#define SET_TCP_PORT 5
#define SET_ROOT_DIR 6
@@ -129,8 +128,6 @@ static void printVersion (void)
// load config from disk and merge with CLI option
static void config_set_default (AFB_session * session)
{
- static char cacheTimeout [10];
-
// default HTTP port
if (session->config->httpdPort == 0)
session->config->httpdPort = 1234;
@@ -185,10 +182,6 @@ static void config_set_default (AFB_session * session)
strncpy (session->config->console, session->config->sessiondir, 512);
strncat (session->config->console, "/AFB-console.out",512);
}
-
- // cacheTimeout is an integer but HTTPd wants it as a string
- snprintf (cacheTimeout, sizeof (cacheTimeout),"%d", session->config->cacheTimeout);
- session->cacheTimeout = cacheTimeout; // httpd uses cacheTimeout string version
}
@@ -331,14 +324,9 @@ static void parse_arguments(int argc, char *argv[], AFB_session *session)
if (!sscanf (optarg, "%d", &session->config->cacheTimeout)) goto notAnInteger;
break;
- case SET_FAKE_MOD:
- if (optarg != 0) goto noValueForOption;
- session->fakemod = 1;
- break;
-
case SET_FORGROUND:
if (optarg != 0) goto noValueForOption;
- session->foreground = 1;
+ session->background = 0;
break;
case SET_BACKGROUND:
@@ -516,10 +504,6 @@ int main(int argc, char *argv[]) {
parse_arguments(argc, argv, session);
// ------------------ sanity check ----------------------------------------
- if ((session->background) && (session->foreground)) {
- fprintf (stderr, "ERR: cannot select foreground & background at the same time\n");
- exit (1);
- }
if (session->config->httpdPort <= 0) {
fprintf (stderr, "ERR: no port is defined\n");
exit (1);
@@ -532,10 +516,6 @@ int main(int argc, char *argv[]) {
install_error_handlers();
- // ------------------ Some useful default values -------------------------
- if ((session->background == 0) && (session->foreground == 0))
- session->foreground = 1;
-
// ------------------ clean exit on CTR-C signal ------------------------
if (signal (SIGINT, signalQuit) == SIG_ERR || signal (SIGABRT, signalQuit) == SIG_ERR) {
fprintf (stderr, "ERR: main fail to install Signal handler\n");
@@ -551,28 +531,16 @@ int main(int argc, char *argv[]) {
if (verbosity) fprintf (stderr, "AFB: notice Init config done\n");
- // ---- run in foreground mode --------------------
- if (session->foreground) {
-
- if (verbosity) fprintf (stderr,"AFB: notice Foreground mode\n");
-
- } // end foreground
-
- // --------- run in background mode -----------
+ // --------- run -----------
if (session->background) {
-
+ // --------- in background mode -----------
if (verbosity) printf ("AFB: Entering background mode\n");
-
daemonize(session);
+ } else {
+ // ---- in foreground mode --------------------
+ if (verbosity) fprintf (stderr,"AFB: notice Foreground mode\n");
- // if everything look OK then look forever
- syslog (LOG_ERR, "AFB: Entering infinite loop in background mode");
-
-
- } // end background-foreground
-
-
- // ------ Start httpd server
+ }
rc = afb_hsrv_start (session);
if (!rc)