diff mbox series

[V4,2/2] mongoose: set V1 or V2 at runtime

Message ID 1520539274-21371-2-git-send-email-sbabic@denx.de
State Accepted
Headers show
Series None | expand

Commit Message

Stefano Babic March 8, 2018, 8:01 p.m. UTC
V1 version of REST-API is still more suitable for M2M
updates together with the SWU forwarder handler.
However, it is not currently possible to switch
between them and the API must be selected at compile time,
and this requires different binaries.

Let the user decides which version of API should run
with a command line parameter.

Signed-off-by: Stefano Babic <sbabic@denx.de>
CC: Sami Hartikainen <sami.hartikainen@teleste.com>
---
Changes since V3:
	- disable http file server for V1

Changes since V2:
	- use enum for API
	- drop V1 website support and let just the two URLs:
		handle_post_request
		getstatus.json
	this to guarantee the compatibility with SWU forwarder and
	proprietary applications using (or abusing of..) the REST-API
	For the Webserver itself, just V2 should be used.
Changes since V1:
	- Drop MONGOOSE_WEB_API_V1 and MONGOOSE_WEB_API_V2
	- Add help for "api"
	- Add "api" parameter to configuration file
	- "/upload" URL just in case of v2
	- print API version when Webserver is started


 mongoose/Config.in            |  18 --
 mongoose/Makefile             |   2 -
 mongoose/mongoose_interface.c | 426 ++++++++++++++++++++----------------------
 3 files changed, 203 insertions(+), 243 deletions(-)

Comments

Stefan Herbrechtsmeier March 11, 2018, 10:13 a.m. UTC | #1
Hi Stefano,

Am 08.03.2018 um 21:01 schrieb Stefano Babic:
> V1 version of REST-API is still more suitable for M2M
> updates together with the SWU forwarder handler.
> However, it is not currently possible to switch
> between them and the API must be selected at compile time,
> and this requires different binaries.
>
> Let the user decides which version of API should run
> with a command line parameter.
>
> Signed-off-by: Stefano Babic <sbabic@denx.de>
> CC: Sami Hartikainen <sami.hartikainen@teleste.com>
> ---
> Changes since V3:
> 	- disable http file server for V1
>
> Changes since V2:
> 	- use enum for API
> 	- drop V1 website support and let just the two URLs:
> 		handle_post_request
> 		getstatus.json
> 	this to guarantee the compatibility with SWU forwarder and
> 	proprietary applications using (or abusing of..) the REST-API
> 	For the Webserver itself, just V2 should be used.
> Changes since V1:
> 	- Drop MONGOOSE_WEB_API_V1 and MONGOOSE_WEB_API_V2
> 	- Add help for "api"
> 	- Add "api" parameter to configuration file
> 	- "/upload" URL just in case of v2
> 	- print API version when Webserver is started
>
>
>   mongoose/Config.in            |  18 --
>   mongoose/Makefile             |   2 -
>   mongoose/mongoose_interface.c | 426 ++++++++++++++++++++----------------------
>   3 files changed, 203 insertions(+), 243 deletions(-)
>

[snip]

> diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c
> index 0e22671..a880b25 100644
> --- a/mongoose/mongoose_interface.c
> +++ b/mongoose/mongoose_interface.c
> @@ -510,6 +471,12 @@ static int mongoose_settings(void *elem, void  __attribute__ ((__unused__)) *dat
>   		opts->ssl_key = strdup(tmp);
>   	}
>   #endif
> +	GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "api", tmp);
> +	if (strlen(tmp)) {
> +		opts->api_version = (!strcmp(tmp, "1")) ?
> +					MONGOOSE_API_V1 :
> +					MONGOOSE_API_V2;
> +	}

Could this be changed to a get_field function with an int value?

[snip]

Best regards
   Stefan
Stefano Babic March 11, 2018, 10:17 a.m. UTC | #2
On 11/03/2018 11:13, Stefan Herbrechtsmeier wrote:
> Hi Stefano,
> 
> Am 08.03.2018 um 21:01 schrieb Stefano Babic:
>> V1 version of REST-API is still more suitable for M2M
>> updates together with the SWU forwarder handler.
>> However, it is not currently possible to switch
>> between them and the API must be selected at compile time,
>> and this requires different binaries.
>>
>> Let the user decides which version of API should run
>> with a command line parameter.
>>
>> Signed-off-by: Stefano Babic <sbabic@denx.de>
>> CC: Sami Hartikainen <sami.hartikainen@teleste.com>
>> ---
>> Changes since V3:
>> 	- disable http file server for V1
>>
>> Changes since V2:
>> 	- use enum for API
>> 	- drop V1 website support and let just the two URLs:
>> 		handle_post_request
>> 		getstatus.json
>> 	this to guarantee the compatibility with SWU forwarder and
>> 	proprietary applications using (or abusing of..) the REST-API
>> 	For the Webserver itself, just V2 should be used.
>> Changes since V1:
>> 	- Drop MONGOOSE_WEB_API_V1 and MONGOOSE_WEB_API_V2
>> 	- Add help for "api"
>> 	- Add "api" parameter to configuration file
>> 	- "/upload" URL just in case of v2
>> 	- print API version when Webserver is started
>>
>>
>>  mongoose/Config.in            |  18 --
>>  mongoose/Makefile             |   2 -
>>  mongoose/mongoose_interface.c | 426 ++++++++++++++++++++----------------------
>>  3 files changed, 203 insertions(+), 243 deletions(-)
>>
> 
> [snip]
> 
>> diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c
>> index 0e22671..a880b25 100644
>> --- a/mongoose/mongoose_interface.c
>> +++ b/mongoose/mongoose_interface.c
>> @@ -510,6 +471,12 @@ static int mongoose_settings(void *elem, void  __attribute__ ((__unused__)) *dat
>>  		opts->ssl_key = strdup(tmp);
>>  	}
>>  #endif
>> +	GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "api", tmp);
>> +	if (strlen(tmp)) {
>> +		opts->api_version = (!strcmp(tmp, "1")) ?
>> +					MONGOOSE_API_V1 :
>> +					MONGOOSE_API_V2;
>> +	}
> 
> Could this be changed to a get_field function with an int value?

Yes. I have already merged, I will write a follow-up patch.

Best regards,
Stefano
diff mbox series

Patch

diff --git a/mongoose/Config.in b/mongoose/Config.in
index a001247..29cac90 100644
--- a/mongoose/Config.in
+++ b/mongoose/Config.in
@@ -18,24 +18,6 @@  config MONGOOSE
 
 endchoice
 
-choice
-	prompt "Web Application Interface"
-	default MONGOOSE_WEB_API_V1
-	help
-	  Choose the bootloader
-
-config MONGOOSE_WEB_API_V1
-	bool "Version 1 (deprecated)"
-	help
-	  Support for version 1
-
-config MONGOOSE_WEB_API_V2
-	bool "Version 2"
-	help
-	  Support for version 2
-
-endchoice
-
 config MONGOOSEIPV6
 	bool "IPv6 support"
 	default y
diff --git a/mongoose/Makefile b/mongoose/Makefile
index 77a616c..dc2d3d3 100644
--- a/mongoose/Makefile
+++ b/mongoose/Makefile
@@ -1,9 +1,7 @@ 
 ifneq ($(CONFIG_WEBSERVER),)
 ifneq ($(CONFIG_MONGOOSE),)
 KBUILD_CFLAGS += -DMG_ENABLE_HTTP_STREAMING_MULTIPART=1
-ifneq ($(CONFIG_MONGOOSE_WEB_API_V2),)
 KBUILD_CFLAGS += -DMG_ENABLE_HTTP_WEBSOCKET=1 -DMG_ENABLE_THREADS=1
-endif
 ifneq ($(CONFIG_MONGOOSEIPV6),)
 KBUILD_CFLAGS += -DMG_ENABLE_IPV6=1
 endif
diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c
index 0e22671..a880b25 100644
--- a/mongoose/mongoose_interface.c
+++ b/mongoose/mongoose_interface.c
@@ -32,6 +32,11 @@ 
 #define MG_PORT "8080"
 #define MG_ROOT "."
 
+enum MONGOOSE_API_VERSION {
+	MONGOOSE_API_V1,
+	MONGOOSE_API_V2
+};
+
 struct mongoose_options {
 	char *root;
 	char *listing;
@@ -40,6 +45,7 @@  struct mongoose_options {
 	char *ssl_cert;
 	char *ssl_key;
 #endif
+	enum MONGOOSE_API_VERSION api_version;
 };
 
 struct file_upload_state {
@@ -50,7 +56,9 @@  struct file_upload_state {
 static struct mg_serve_http_opts s_http_server_opts;
 static void upload_handler(struct mg_connection *nc, int ev, void *p);
 
-#if defined(CONFIG_MONGOOSE_WEB_API_V2)
+/*
+ * These functions are for V2 of the protocol
+ */
 #define enum_string(x)	[x] = #x
 static const char *get_status_string(unsigned int status)
 {
@@ -111,210 +119,7 @@  static size_t snescape(char *dst, size_t n, const char *src)
 
 	return len;
 }
-#endif
-
-#if defined(CONFIG_MONGOOSE_WEB_API_V1)
-static void upload_handler_v1(struct mg_connection *nc, int ev, void *p)
-{
-	struct mg_str *filename, *data;
-	struct http_message *hm;
-	size_t length;
-	char buf[16];
-	int fd;
-
-	switch (ev) {
-	case MG_EV_HTTP_REQUEST:
-		hm = (struct http_message *) p;
-
-		filename = mg_get_http_header(hm, "X_FILENAME");
-		if (filename == NULL) {
-			mg_http_send_error(nc, 403, NULL);
-			return;
-		}
-
-		data = mg_get_http_header(hm, "Content-length");
-		if (data == NULL || data->len >= ARRAY_SIZE(buf)) {
-			mg_http_send_error(nc, 403, NULL);
-			return;
-		}
-
-		memcpy(buf, data->p, data->len);
-		buf[data->len] = '\0';
-		length = strtoul(data->p, NULL, 10);
-		if (length == 0) {
-			mg_http_send_error(nc, 403, NULL);
-			return;
-		}
-
-		fd = ipc_inst_start_ext(SOURCE_WEBSERVER, filename->len, filename->p);
-		ipc_send_data(fd, (char *) hm->body.p, hm->body.len);
-		ipc_end(fd);
-
-		mg_send_response_line(nc, 200,
-			"Content-Type: text/plain\r\n"
-			"Connection: close");
-		mg_send(nc, "\r\n", 2);
-		mg_printf(nc, "Ok, %.*s - %d bytes.\r\n", (int) filename->len, filename->p, (int) length);
-		nc->flags |= MG_F_SEND_AND_CLOSE;
-		break;
-	default:
-		upload_handler(nc, ev, p);
-		break;
-	}
-}
-#endif
-
-static void upload_handler(struct mg_connection *nc, int ev, void *p)
-{
-	struct mg_http_multipart_part *mp;
-	struct file_upload_state *fus;
-
-	switch (ev) {
-	case MG_EV_HTTP_PART_BEGIN:
-		mp = (struct mg_http_multipart_part *) p;
-
-		fus = (struct file_upload_state *) calloc(1, sizeof(*fus));
-		if (fus == NULL) {
-			mg_http_send_error(nc, 500, "Out of memory");
-			break;
-		}
-
-		fus->fd = ipc_inst_start_ext(SOURCE_WEBSERVER, strlen(mp->file_name), mp->file_name);
-		if (fus->fd < 0) {
-			mg_http_send_error(nc, 500, "Failed to queue command");
-			free(fus);
-			break;
-		}
-
-		mp->user_data = fus;
-
-		break;
-
-	case MG_EV_HTTP_PART_DATA:
-		mp = (struct mg_http_multipart_part *) p;
-		fus = (struct file_upload_state *) mp->user_data;
-
-		if (!fus)
-			break;
-
-		ipc_send_data(fus->fd, (char *) mp->data.p, mp->data.len);
-		fus->len += mp->data.len;
-
-		break;
-
-	case MG_EV_HTTP_PART_END:
-		mp = (struct mg_http_multipart_part *) p;
-		fus = (struct file_upload_state *) mp->user_data;
-
-		if (!fus)
-			break;
-
-		ipc_end(fus->fd);
-
-		mg_send_response_line(nc, 200,
-			"Content-Type: text/plain\r\n"
-			"Connection: close");
-		mg_send(nc, "\r\n", 2);
-		mg_printf(nc, "Ok, %s - %d bytes.\r\n", mp->file_name, (int) fus->len);
-		nc->flags |= MG_F_SEND_AND_CLOSE;
-
-		mp->user_data = NULL;
-		free(fus);
-		break;
-	}
-}
-
-#if defined(CONFIG_MONGOOSE_WEB_API_V1)
-static void recovery_status(struct mg_connection *nc, int ev, void *ev_data)
-{
-	ipc_message ipc;
-	int ret;
-	char buf[4096];
-
-	(void)ev;
-	(void)ev_data;
-
-	ret = ipc_get_status(&ipc);
-
-	if (ret) {
-		mg_http_send_error(nc, 500, NULL);
-		return;
-	}
-
-	snprintf(buf, sizeof(buf),
-		"{\r\n"
-		"\t\"Status\" : \"%d\",\r\n"
-		"\t\"Msg\" : \"%s\",\r\n"
-		"\t\"Error\" : \"%d\",\r\n"
-		"\t\"LastResult\" : \"%d\"\r\n"
-		"}\r\n",
-		ipc.data.status.current,
-		strlen(ipc.data.status.desc) ? ipc.data.status.desc : "",
-		ipc.data.status.error,
-		ipc.data.status.last_result);
-
-	mg_send_head(nc, 200, strlen(buf),
-		"Cache: no-cache\r\n"
-		"Content-Type: text/plain");
-
-	mg_send(nc, buf, strlen(buf));
-
-	nc->flags |= MG_F_SEND_AND_CLOSE;
-}
-
-static void reboot_target(struct mg_connection *nc, int ev, void *ev_data)
-{
-	struct http_message *hm = (struct http_message *) ev_data;
-	int ret;
-
-	(void)ev;
-
-	if(mg_vcasecmp(&hm->method, "POST") == 0) {
-		ret = system("reboot");
-		if (ret) {
-			mg_http_send_error(nc, 500,
-				"Device cannot be reboot, internal fault.");
-			return;
-		}
-
-		mg_http_send_error(nc, 200, "Device will reboot now.");
-	}
-	else {
-		mg_send_response_line(nc, 200,
-			"Content-Type: text/html\r\n"
-			"Connection: close");
-		mg_send(nc, "\r\n", 2);
-		mg_printf(nc,
-			"<form method='POST' action=''>"
-			"<input type='submit' value='Reboot'>"
-			"</form>");
-		nc->flags |= MG_F_SEND_AND_CLOSE;
-	}
-}
-
-static void post_update_cmd(struct mg_connection *nc, int ev, void *ev_data)
-{
-	ipc_message msg = {};
 
-	(void)ev;
-	(void)ev_data;
-
-	int ret = ipc_postupdate(&msg);
-	mg_send_response_line(nc, 200, "Content-Type: application/json");
-	mg_send(nc, "\r\n", 2);
-	mg_printf(nc,
-		"{\r\n"
-		"\t\"code\": %d,\r\n"
-		"\t\"error\": \"%s\",\r\n"
-		"\t\"detail\": \"%s\"\r\n"
-		"}",
-		(ret == 0) ? 200 : 501,
-		(ret == 0) ? "" : "Internal server error",
-		(ret == 0) ? "" : "Failed to queue command");
-
-	nc->flags |= MG_F_SEND_AND_CLOSE;
-}
-#elif defined(CONFIG_MONGOOSE_WEB_API_V2)
 static void restart_handler(struct mg_connection *nc, int ev, void *ev_data)
 {
 	struct http_message *hm = (struct http_message *) ev_data;
@@ -470,14 +275,170 @@  static void *broadcast_progress_thread(void *data)
 
 	return NULL;
 }
-#endif
+
+/*
+ * These functions are for V1 of the protocol
+ */
+static void upload_handler_v1(struct mg_connection *nc, int ev, void *p)
+{
+	struct mg_str *filename, *data;
+	struct http_message *hm;
+	size_t length;
+	char buf[16];
+	int fd;
+
+	switch (ev) {
+	case MG_EV_HTTP_REQUEST:
+		hm = (struct http_message *) p;
+
+		filename = mg_get_http_header(hm, "X_FILENAME");
+		if (filename == NULL) {
+			mg_http_send_error(nc, 403, NULL);
+			return;
+		}
+
+		data = mg_get_http_header(hm, "Content-length");
+		if (data == NULL || data->len >= ARRAY_SIZE(buf)) {
+			mg_http_send_error(nc, 403, NULL);
+			return;
+		}
+
+		memcpy(buf, data->p, data->len);
+		buf[data->len] = '\0';
+		length = strtoul(data->p, NULL, 10);
+		if (length == 0) {
+			mg_http_send_error(nc, 403, NULL);
+			return;
+		}
+
+		fd = ipc_inst_start_ext(SOURCE_WEBSERVER, filename->len, filename->p);
+		ipc_send_data(fd, (char *) hm->body.p, hm->body.len);
+		ipc_end(fd);
+
+		mg_send_response_line(nc, 200,
+			"Content-Type: text/plain\r\n"
+			"Connection: close");
+		mg_send(nc, "\r\n", 2);
+		mg_printf(nc, "Ok, %.*s - %d bytes.\r\n", (int) filename->len, filename->p, (int) length);
+		nc->flags |= MG_F_SEND_AND_CLOSE;
+		break;
+	default:
+		upload_handler(nc, ev, p);
+		break;
+	}
+}
+
+static void recovery_status(struct mg_connection *nc, int ev, void *ev_data)
+{
+	ipc_message ipc;
+	int ret;
+	char buf[4096];
+
+	(void)ev;
+	(void)ev_data;
+
+	ret = ipc_get_status(&ipc);
+
+	if (ret) {
+		mg_http_send_error(nc, 500, NULL);
+		return;
+	}
+
+	snprintf(buf, sizeof(buf),
+		"{\r\n"
+		"\t\"Status\" : \"%d\",\r\n"
+		"\t\"Msg\" : \"%s\",\r\n"
+		"\t\"Error\" : \"%d\",\r\n"
+		"\t\"LastResult\" : \"%d\"\r\n"
+		"}\r\n",
+		ipc.data.status.current,
+		strlen(ipc.data.status.desc) ? ipc.data.status.desc : "",
+		ipc.data.status.error,
+		ipc.data.status.last_result);
+
+	mg_send_head(nc, 200, strlen(buf),
+		"Cache: no-cache\r\n"
+		"Content-Type: text/plain");
+
+	mg_send(nc, buf, strlen(buf));
+
+	nc->flags |= MG_F_SEND_AND_CLOSE;
+}
+
+/*
+ * Code common to V1 and V2
+ */
+static void upload_handler(struct mg_connection *nc, int ev, void *p)
+{
+	struct mg_http_multipart_part *mp;
+	struct file_upload_state *fus;
+
+	switch (ev) {
+	case MG_EV_HTTP_PART_BEGIN:
+		mp = (struct mg_http_multipart_part *) p;
+
+		fus = (struct file_upload_state *) calloc(1, sizeof(*fus));
+		if (fus == NULL) {
+			mg_http_send_error(nc, 500, "Out of memory");
+			break;
+		}
+
+		fus->fd = ipc_inst_start_ext(SOURCE_WEBSERVER, strlen(mp->file_name), mp->file_name);
+		if (fus->fd < 0) {
+			mg_http_send_error(nc, 500, "Failed to queue command");
+			free(fus);
+			break;
+		}
+
+		mp->user_data = fus;
+
+		break;
+
+	case MG_EV_HTTP_PART_DATA:
+		mp = (struct mg_http_multipart_part *) p;
+		fus = (struct file_upload_state *) mp->user_data;
+
+		if (!fus)
+			break;
+
+		ipc_send_data(fus->fd, (char *) mp->data.p, mp->data.len);
+		fus->len += mp->data.len;
+
+		break;
+
+	case MG_EV_HTTP_PART_END:
+		mp = (struct mg_http_multipart_part *) p;
+		fus = (struct file_upload_state *) mp->user_data;
+
+		if (!fus)
+			break;
+
+		ipc_end(fus->fd);
+
+		mg_send_response_line(nc, 200,
+			"Content-Type: text/plain\r\n"
+			"Connection: close");
+		mg_send(nc, "\r\n", 2);
+		mg_printf(nc, "Ok, %s - %d bytes.\r\n", mp->file_name, (int) fus->len);
+		nc->flags |= MG_F_SEND_AND_CLOSE;
+
+		mp->user_data = NULL;
+		free(fus);
+		break;
+	}
+}
+
+static void ev_handler_v1(struct mg_connection __attribute__ ((__unused__)) *nc,
+				int __attribute__ ((__unused__)) ev,
+				void __attribute__ ((__unused__)) *ev_data)
+{
+}
 
 static void ev_handler(struct mg_connection *nc, int ev, void *ev_data)
 {
 	if (ev == MG_EV_HTTP_REQUEST) {
 		mg_serve_http(nc, ev_data, s_http_server_opts);
 	}
-
 }
 
 static int mongoose_settings(void *elem, void  __attribute__ ((__unused__)) *data)
@@ -510,6 +471,12 @@  static int mongoose_settings(void *elem, void  __attribute__ ((__unused__)) *dat
 		opts->ssl_key = strdup(tmp);
 	}
 #endif
+	GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "api", tmp);
+	if (strlen(tmp)) {
+		opts->api_version = (!strcmp(tmp, "1")) ?
+					MONGOOSE_API_V1 :
+					MONGOOSE_API_V2;
+	}
 	return 0;
 }
 
@@ -523,6 +490,7 @@  static struct option long_options[] = {
 	{"ssl-key", required_argument, NULL, 'K'},
 #endif
 	{"document-root", required_argument, NULL, 'r'},
+	{"api-version", required_argument, NULL, 'a'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -538,7 +506,8 @@  void mongoose_print_help(void)
 		"\t  -C, --ssl-cert <cert>          : ssl certificate to present to clients\n"
 		"\t  -K, --ssl-key <key>            : key corresponding to the ssl certificate\n"
 #endif
-		"\t  -r, --document-root <path>     : path to document root directory (default: %s)\n",
+		"\t  -r, --document-root <path>     : path to document root directory (default: %s)\n"
+		"\t  -a, --api-version [1|2]        : set Web protocol API to v1 (legacy) or v2 (default v2)\n",
 		MG_LISTING, MG_PORT, MG_ROOT);
 }
 
@@ -556,12 +525,14 @@  int start_mongoose(const char *cfgfname, int argc, char *argv[])
 	int choice = 0;
 
 	memset(&opts, 0, sizeof(opts));
+	/* Set default API version */
+	opts.api_version = MONGOOSE_API_V2;
 	if (cfgfname) {
 		read_module_settings(cfgfname, "webserver", mongoose_settings, &opts);
 	}
 
 	optind = 1;
-	while ((choice = getopt_long(argc, argv, "lp:sC:K:r:",
+	while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:",
 				     long_options, NULL)) != -1) {
 		switch (choice) {
 		case 'l':
@@ -589,6 +560,11 @@  int start_mongoose(const char *cfgfname, int argc, char *argv[])
 			free(opts.root);
 			opts.root = strdup(optarg);
 			break;
+		case 'a':
+			opts.api_version = (!strcmp(optarg, "1")) ?
+						MONGOOSE_API_V1 :
+						MONGOOSE_API_V2;
+			break;
 		case '?':
 		default:
 			return -EINVAL;
@@ -612,29 +588,33 @@  int start_mongoose(const char *cfgfname, int argc, char *argv[])
 
 	mg_mgr_init(&mgr, NULL);
 
-	nc = mg_bind_opt(&mgr, s_http_port, ev_handler, bind_opts);
+	if (opts.api_version == MONGOOSE_API_V1)
+		nc = mg_bind_opt(&mgr, s_http_port, ev_handler_v1, bind_opts);
+	else
+		nc = mg_bind_opt(&mgr, s_http_port, ev_handler, bind_opts);
 	if (nc == NULL) {
 		fprintf(stderr, "Failed to start Mongoose: %s\n", *bind_opts.error_string);
 		exit(EXIT_FAILURE);
 	}
 
 	mg_set_protocol_http_websocket(nc);
-	mg_register_http_endpoint(nc, "/upload", MG_CB(upload_handler, NULL));
-#if defined(CONFIG_MONGOOSE_WEB_API_V1)
-	mg_register_http_endpoint(nc, "/handle_post_request", MG_CB(upload_handler_v1, NULL));
-	mg_register_http_endpoint(nc, "/getstatus.json", MG_CB(recovery_status, NULL));
-	mg_register_http_endpoint(nc, "/rebootTarget", MG_CB(reboot_target, NULL));
-	mg_register_http_endpoint(nc, "/postUpdateCommand", MG_CB(post_update_cmd, NULL));
-#endif
-#if defined(CONFIG_MONGOOSE_WEB_API_V2)
-	mg_register_http_endpoint(nc, "/restart", restart_handler);
-	mg_start_thread(broadcast_message_thread, &mgr);
-	mg_start_thread(broadcast_progress_thread, &mgr);
-#endif
+	switch (opts.api_version) {
+	case MONGOOSE_API_V1:
+		mg_register_http_endpoint(nc, "/handle_post_request", MG_CB(upload_handler_v1, NULL));
+		mg_register_http_endpoint(nc, "/getstatus.json", MG_CB(recovery_status, NULL));
+		break;
+	case MONGOOSE_API_V2:
+		mg_register_http_endpoint(nc, "/restart", restart_handler);
+		mg_register_http_endpoint(nc, "/upload", MG_CB(upload_handler, NULL));
+		mg_start_thread(broadcast_message_thread, &mgr);
+		mg_start_thread(broadcast_progress_thread, &mgr);
+		break;
+	}
 
-	printf("Mongoose web server version %s with pid %d started on port(s) %s with web root [%s]\n",
+	printf("Mongoose web server version %s with pid %d started on port(s) %s with web root [%s] and API %s\n",
 		MG_VERSION, getpid(), s_http_port,
-		s_http_server_opts.document_root);
+		s_http_server_opts.document_root,
+		(opts.api_version  == MONGOOSE_API_V1) ? "v1" : "v2");
 
 	for (;;) {
 		mg_mgr_poll(&mgr, 100);