info: respond with "not found" (404) on invalid commands
authorFerry Huberts <ferry.huberts@pelagic.nl>
Sun, 21 Feb 2016 15:26:07 +0000 (16:26 +0100)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Thu, 25 Feb 2016 12:39:16 +0000 (13:39 +0100)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
lib/info/http_headers.h
lib/info/olsrd_info.c
lib/jsoninfo/src/olsrd_jsoninfo.c
lib/jsoninfo/src/olsrd_jsoninfo.h
lib/jsoninfo/src/olsrd_plugin.c
lib/txtinfo/src/olsrd_plugin.c
lib/txtinfo/src/olsrd_txtinfo.c
lib/txtinfo/src/olsrd_txtinfo.h

index 308c561..2a54031 100644 (file)
@@ -48,6 +48,7 @@
 
 /* Response types */
 #define INFO_HTTP_OK             (200)
+#define INFO_HTTP_NOTFOUND       (404)
 
 void http_header_build(const char * plugin_name, unsigned int status, const char *mime, struct autobuf *abuf, int *contentLengthIndex);
 
@@ -55,6 +56,9 @@ void http_header_adjust_content_length(struct autobuf *abuf, int contentLengthIn
 
 static INLINE const char * httpStatusToReply(unsigned int status) {
   switch (status) {
+    case INFO_HTTP_NOTFOUND:
+      return INFO_HTTP_VERSION " 404 Not Found";
+
     case INFO_HTTP_OK:
     default:
       return INFO_HTTP_VERSION " 200 OK";
index 63c343e..acb728a 100644 (file)
@@ -187,7 +187,7 @@ static void write_data(void *foo __attribute__ ((unused))) {
   }
 }
 
-static void send_info(const char * req __attribute__((unused)), unsigned int send_what, int the_socket, unsigned int status) {
+static void send_info(const char * req, unsigned int send_what, int the_socket, unsigned int status) {
   struct autobuf abuf;
 
   const char *content_type = functions->determine_mime_type ? functions->determine_mime_type(send_what) : "text/plain; charset=utf-8";
@@ -201,56 +201,66 @@ static void send_info(const char * req __attribute__((unused)), unsigned int sen
     headerLength = abuf.len;
   }
 
-  // only add if normal format
-  if (send_what & SIW_ALL) {
-    typedef struct {
-      unsigned int siw;
-      printer_generic func;
-    } SiwLookupTableEntry;
-
-    SiwLookupTableEntry funcs[] = {
-      { SIW_NEIGHBORS , functions->neighbors  }, //
-      { SIW_LINKS     , functions->links      }, //
-      { SIW_ROUTES    , functions->routes     }, //
-      { SIW_HNA       , functions->hna        }, //
-      { SIW_MID       , functions->mid        }, //
-      { SIW_TOPOLOGY  , functions->topology   }, //
-      { SIW_GATEWAYS  , functions->gateways   }, //
-      { SIW_INTERFACES, functions->interfaces }, //
-      { SIW_2HOP      , functions->twohop     }, //
-      { SIW_SGW       , functions->sgw        }, //
-      //
-      { SIW_VERSION, functions->version }, //
-      { SIW_CONFIG, functions->config }, //
-      { SIW_PLUGINS, functions->plugins } //
-      };
-
-    unsigned int i;
-
-    if (functions->output_start) {
-      functions->output_start(&abuf);
-    }
+  if (status == INFO_HTTP_OK) {
+    /* OK */
+
+    // only add if normal format
+    if (send_what & SIW_ALL) {
+      typedef struct {
+        unsigned int siw;
+        printer_generic func;
+      } SiwLookupTableEntry;
+
+      SiwLookupTableEntry funcs[] = {
+        { SIW_NEIGHBORS , functions->neighbors  }, //
+        { SIW_LINKS     , functions->links      }, //
+        { SIW_ROUTES    , functions->routes     }, //
+        { SIW_HNA       , functions->hna        }, //
+        { SIW_MID       , functions->mid        }, //
+        { SIW_TOPOLOGY  , functions->topology   }, //
+        { SIW_GATEWAYS  , functions->gateways   }, //
+        { SIW_INTERFACES, functions->interfaces }, //
+        { SIW_2HOP      , functions->twohop     }, //
+        { SIW_SGW       , functions->sgw        }, //
+        //
+        { SIW_VERSION, functions->version }, //
+        { SIW_CONFIG, functions->config }, //
+        { SIW_PLUGINS, functions->plugins } //
+        };
+
+      unsigned int i;
+
+      if (functions->output_start) {
+        functions->output_start(&abuf);
+      }
 
-    for (i = 0; i < ARRAY_SIZE(funcs); i++) {
-      if (send_what & funcs[i].siw) {
-        printer_generic func = funcs[i].func;
-        if (func) {
-          func(&abuf);
+      for (i = 0; i < ARRAY_SIZE(funcs); i++) {
+        if (send_what & funcs[i].siw) {
+          printer_generic func = funcs[i].func;
+          if (func) {
+            func(&abuf);
+          }
         }
       }
+
+      if (functions->output_end) {
+        functions->output_end(&abuf);
+      }
+    } else if ((send_what & SIW_OLSRD_CONF) && functions->olsrd_conf) {
+      /* this outputs the olsrd.conf text directly, not normal format */
+      functions->olsrd_conf(&abuf);
     }
 
-    if (functions->output_end) {
-      functions->output_end(&abuf);
+    if (!abuf.len) {
+      /* wget can't handle output of zero length */
+      abuf_puts(&abuf, "\n");
     }
-  } else if ((send_what & SIW_OLSRD_CONF) && functions->olsrd_conf) {
-    /* this outputs the olsrd.conf text directly, not normal format */
-    functions->olsrd_conf(&abuf);
   }
 
-  if (!abuf.len) {
-    /* wget can't handle output of zero length */
-    abuf_puts(&abuf, "\n");
+  if (status != INFO_HTTP_OK) {
+    if (functions->output_error) {
+      functions->output_error(&abuf, status, req, config->http_headers);
+    }
   }
 
   if (config->http_headers) {
@@ -439,7 +449,7 @@ static void ipc_action(int fd, void *data __attribute__ ((unused)), unsigned int
     }
 
     if (!send_what) {
-      send_what = SIW_ALL;
+      http_status = INFO_HTTP_NOTFOUND;
     }
   }
 
index 45dba76..0e4d1f1 100644 (file)
@@ -56,6 +56,7 @@
 #include "olsrd_jsoninfo_helpers.h"
 #include "olsrd_plugin.h"
 #include "../../info/info_types.h"
+#include "../../info/http_headers.h"
 #include "gateway_default_handler.h"
 
 struct timeval start_time;
@@ -173,6 +174,29 @@ void output_end(struct autobuf *abuf) {
   abuf_puts(abuf, "\n");
 }
 
+void output_error(struct autobuf *abuf, unsigned int status, const char * req, bool http_headers) {
+  char buf[1024];
+
+  if (http_headers || (status == INFO_HTTP_OK)) {
+    return;
+  }
+
+  output_start(abuf);
+
+  switch (status) {
+    case INFO_HTTP_NOTFOUND:
+      snprintf(buf, sizeof(buf) - 1, "Invalid request '%s'", req);
+      buf[sizeof(buf) - 1] = '\0';
+      abuf_json_string(abuf, "error", buf);
+      break;
+
+    default:
+      break;
+  }
+
+  output_end(abuf);
+}
+
 static void ipc_print_neighbors_internal(struct autobuf *abuf, bool list_2hop) {
   struct ipaddr_str buf1, buf2;
   struct neighbor_entry *neigh;
index 5d74c9a..c9c0658 100644 (file)
@@ -57,6 +57,7 @@ const char * determine_mime_type(unsigned int send_what);
 
 void output_start(struct autobuf *abuf);
 void output_end(struct autobuf *abuf);
+void output_error(struct autobuf *abuf, unsigned int status, const char * req, bool http_headers);
 
 void ipc_print_neighbors(struct autobuf *abuf);
 void ipc_print_links(struct autobuf *abuf);
index fb9e600..b64541f 100644 (file)
@@ -60,6 +60,7 @@ static info_plugin_functions_t functions = { //
         .determine_mime_type = determine_mime_type, //
         .output_start = output_start, //
         .output_end = output_end, //
+        .output_error = output_error, //
         .neighbors = ipc_print_neighbors, //
         .links = ipc_print_links, //
         .routes = ipc_print_routes, //
index af42439..e8c7767 100644 (file)
@@ -60,6 +60,7 @@ static info_plugin_functions_t functions = { //
         .determine_mime_type = NULL, //
         .output_start = NULL, //
         .output_end = NULL, //
+        .output_error = output_error, //
         .neighbors = ipc_print_neighbors, //
         .links = ipc_print_links, //
         .routes = ipc_print_routes, //
index d94c9f9..a62ad88 100644 (file)
@@ -53,6 +53,7 @@
 #include "gateway.h"
 #include "olsrd_plugin.h"
 #include "../../info/info_types.h"
+#include "../../info/http_headers.h"
 #include "gateway_default_handler.h"
 
 bool isCommand(const char *str, unsigned int siw) {
@@ -181,6 +182,22 @@ static void ipc_print_neighbors_internal(struct autobuf *abuf, bool list_2hop) {
   abuf_puts(abuf, "\n");
 }
 
+void output_error(struct autobuf *abuf, unsigned int status, const char * req, bool http_headers) {
+  if (http_headers) {
+    return;
+  }
+
+  switch (status) {
+    case INFO_HTTP_NOTFOUND:
+      abuf_appendf(abuf, "error: Invalid request '%s'\n", req);
+      break;
+
+    case INFO_HTTP_OK:
+    default:
+      return;
+  }
+}
+
 void ipc_print_neighbors(struct autobuf *abuf) {
   ipc_print_neighbors_internal(abuf, false);
 }
index c4080bc..5a0a77d 100644 (file)
@@ -47,6 +47,7 @@
 #include "common/autobuf.h"
 
 bool isCommand(const char *str, unsigned int siw);
+void output_error(struct autobuf *abuf, unsigned int status, const char * req, bool http_headers);
 
 void ipc_print_neighbors(struct autobuf *abuf);
 void ipc_print_links(struct autobuf *abuf);