[Olsr-dev] [PATCH] jsoninfo: HTTP headers with CORS (if requested)

Ferry Huberts (spam-protected)
Fri May 16 13:41:15 CEST 2014



On 16/05/14 13:17, Alessio Caiazza wrote:
> The new "httpheaders" parameter prepends HTTP headers to the reply.
> If not set it will defaults to "no" and have the same behaviour as before.

default to

> Cross-origin resource sharing headers (CORS) are included in reply allowing the
> json retrieval by javascript applications not served by olsrd itself.
> This will allow to easily develop js applications running directly into the

directly in the

> browser.
> ---
>   lib/jsoninfo/README_JSONINFO      |  3 ++
>   lib/jsoninfo/src/olsrd_jsoninfo.c | 85 +++++++++++++++++++++++++++++++++++----
>   lib/jsoninfo/src/olsrd_jsoninfo.h |  2 +
>   lib/jsoninfo/src/olsrd_plugin.c   | 18 +++++++++
>   4 files changed, 100 insertions(+), 8 deletions(-)
>
> diff --git a/lib/jsoninfo/README_JSONINFO b/lib/jsoninfo/README_JSONINFO
> index a102a56..f1c0ba3 100644
> --- a/lib/jsoninfo/README_JSONINFO
> +++ b/lib/jsoninfo/README_JSONINFO
> @@ -73,6 +73,9 @@ LoadPlugin "olsrd_jsoninfo.so.0.0"
>       # if you set it to 0.0.0.0, it will accept all connections
>       #PlParam      "accept" "0.0.0.0"
>
> +    # reply can include standard HTTP headers (default "no")
> +    #PlParam      "httpheaders" "yes"
> +

* please rename the parameter to 'extrahttpheaders'
* the default is 'no', not 'yes' as indicated here
* add a description of what will actually happen if set to 'yes' 
(something like the commit log). make sure to list the headers that will
be added

>       # specify a UUID for this node to track it for debugging
>       #PlParam      "UUIDFile" "/etc/olsrd/olsrd.uuid"
>   }
> diff --git a/lib/jsoninfo/src/olsrd_jsoninfo.c b/lib/jsoninfo/src/olsrd_jsoninfo.c
> index 9db99b8..e1fdd67 100644
> --- a/lib/jsoninfo/src/olsrd_jsoninfo.c
> +++ b/lib/jsoninfo/src/olsrd_jsoninfo.c
> @@ -5,6 +5,7 @@
>    *                     includes code by Andreas Lopatic
>    *                     includes code by Sven-Ola Tuecke
>    *                     includes code by Lorenz Schori
> + *                     includes code by Alessio Caiazza

If you insist, can can leave it in but these things are not needed ever 
since we moved to git.


>    *                     includes bugs by Markus Kittenberger
>    *                     includes bugs by Hans-Christoph Steiner
>    * All rights reserved.
> @@ -96,6 +97,9 @@
>
>   static int ipc_socket;
>
> +/**Response types */
> +#define HTTP_200 "HTTP/1.1 200 OK"
> +
>   /* IPC initialization function */
>   static int plugin_ipc_init(void);
>
> @@ -126,6 +130,9 @@ static void ipc_print_interfaces(struct autobuf *);
>   static void ipc_print_plugins(struct autobuf *);
>   static void ipc_print_olsrd_conf(struct autobuf *abuf);
>
> +static size_t build_http_header(const char *status, const char *mime,
> +  uint32_t msgsize, char *buf, uint32_t bufsize);
> +
>   #define TXT_IPC_BUFSIZE 256
>
>   /* these provide all of the runtime status info */
> @@ -151,6 +158,7 @@ static void ipc_print_olsrd_conf(struct autobuf *abuf);
>   #define SIW_OLSRD_CONF 0x1000
>
>   #define MAX_CLIENTS 3
> +#define MAX_HTTPHEADER_SIZE 1024
>
>   static char *outbuffer[MAX_CLIENTS];
>   static size_t outbuffer_size[MAX_CLIENTS];
> @@ -1282,6 +1290,9 @@ static void
>   send_info(unsigned int send_what, int the_socket)
>   {
>     struct autobuf abuf;
> +  size_t header_len = 0;
> +  char header_buf[MAX_HTTPHEADER_SIZE];
> +  const char *content_type = "application/json";

drop the const, you assign it later

>
>     /* global variables for tracking when to put a comma in for JSON */
>     entrynumber[0] = 0;
> @@ -1318,28 +1329,86 @@ send_info(unsigned int send_what, int the_socket)
>     /* this outputs the olsrd.conf text directly, not JSON */
>     if ((send_what & SIW_OLSRD_CONF) == SIW_OLSRD_CONF) {
>       ipc_print_olsrd_conf(&abuf);
> +    content_type = "text/plain";
> +  }
> +
> +  if(http_headers) {
> +    memset(header_buf, 0, sizeof(header_buf));
> +    header_len = build_http_header(HTTP_200, content_type, abuf.len, header_buf, sizeof(header_buf));

memsetting can be avoided (for performance) by letting build_http_header 
ensure \0 termination.


>     }
>
> -  outbuffer[outbuffer_count] = olsr_malloc(abuf.len, "txt output buffer");
> -  outbuffer_size[outbuffer_count] = abuf.len;
> -  outbuffer_written[outbuffer_count] = 0;
> -  outbuffer_socket[outbuffer_count] = the_socket;
> +  if (header_len + abuf.len > 0) {

why is the if added?

> +    outbuffer[outbuffer_count] = olsr_malloc(header_len + abuf.len, "json output buffer");
> +    outbuffer_size[outbuffer_count] = header_len + abuf.len;
> +    outbuffer_written[outbuffer_count] = 0;
> +    outbuffer_socket[outbuffer_count] = the_socket;
>
> -  memcpy(outbuffer[outbuffer_count], abuf.buf, abuf.len);
> -  outbuffer_count++;
> +    memcpy(outbuffer[outbuffer_count], header_buf, header_len);
> +    if (abuf.len > 0) {

no need for this if

> +      memcpy((outbuffer[outbuffer_count]) + header_len, abuf.buf, abuf.len);
> +    }
> +    outbuffer_count++;



>
> -  if (outbuffer_count == 1) {
> -    writetimer_entry = olsr_start_timer(100,
> +    if (outbuffer_count == 1) {
> +      writetimer_entry = olsr_start_timer(100,
>                                           0,
>                                           OLSR_TIMER_PERIODIC,
>                                           &jsoninfo_write_data,
>                                           NULL,
>                                           0);
> +    }
>     }
>
>     abuf_free(&abuf);
>   }
>
> +static size_t
> +build_http_header(const char *status, const char *mime, uint32_t msgsize,
> +  char *buf, uint32_t bufsize)
> +{

why not use an abuf?
you're now (at least) missing string length overrun checks


> +  time_t currtime;
> +  size_t size;
> +
> +  size = snprintf(buf, bufsize, "%s\r\n", status);
> +
> +  /* Date */
> +  time(&currtime);
> +  size += strftime(&buf[size], bufsize - size, "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", localtime(&currtime));
> +
> +  /* Server version */
> +  size += snprintf(&buf[size], bufsize - size, "Server: OLSRD JSONInfo plugin\r\n");
> +
> +  /* connection-type */
> +  size += snprintf(&buf[size], bufsize - size, "Connection: closed\r\n");
> +
> +  /* MIME type */
> +  if(mime != NULL) {
> +    size += snprintf(&buf[size], bufsize - size, "Content-type: %s\r\n", mime);
> +  }
> +
> +  /* CORS data */
> +  /**No needs to be strict here, access control is based on source IP*/
> +  size += snprintf(&buf[size], bufsize - size, "Access-Control-Allow-Origin: *\r\n");
> +  size += snprintf(&buf[size], bufsize - size, "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n");
> +  size += snprintf(&buf[size], bufsize - size, "Access-Control-Allow-Headers: Accept, Origin, X-Requested-With\r\n");
> +  size += snprintf(&buf[size], bufsize - size, "Access-Control-Max-Age: 1728000\r\n");
> +
> +  /* Content length */
> +  if (msgsize > 0) {
> +    size += snprintf(&buf[size], bufsize - size, "Content-length: %i\r\n", msgsize);
> +  }
> +
> +  /* Cache-control
> +   * No caching dynamic pages
> +   */
> +  size += snprintf(&buf[size], bufsize - size, "Cache-Control: no-cache\r\n");
> +
> +  /* End header */
> +  size += snprintf(&buf[size], bufsize - size, "\r\n");
> +
> +  return size;
> +}
> +
>   /*
>    * Local Variables:
>    * mode: c
> diff --git a/lib/jsoninfo/src/olsrd_jsoninfo.h b/lib/jsoninfo/src/olsrd_jsoninfo.h
> index 8478f62..47e6004 100644
> --- a/lib/jsoninfo/src/olsrd_jsoninfo.h
> +++ b/lib/jsoninfo/src/olsrd_jsoninfo.h
> @@ -3,6 +3,7 @@
>    * The olsr.org Optimized Link-State Routing daemon(olsrd)
>    * Copyright (c) 2004, Andreas Tonnesen((spam-protected))
>    *                     includes code by Bruno Randolf
> + *                     includes code by Alessio Caiazza
>    * All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
> @@ -62,6 +63,7 @@ extern union olsr_ip_addr jsoninfo_accept_ip;
>   extern union olsr_ip_addr jsoninfo_listen_ip;
>   extern int ipc_port;
>   extern int nompr;
> +extern bool http_headers;
>
>   int olsrd_plugin_interface_version(void);
>   int olsrd_plugin_init(void);
> diff --git a/lib/jsoninfo/src/olsrd_plugin.c b/lib/jsoninfo/src/olsrd_plugin.c
> index 36550a8..44d0428 100644
> --- a/lib/jsoninfo/src/olsrd_plugin.c
> +++ b/lib/jsoninfo/src/olsrd_plugin.c
> @@ -2,6 +2,7 @@
>   /*
>    * The olsr.org Optimized Link-State Routing daemon(olsrd)
>    * Copyright (c) 2004, Andreas Tonnesen((spam-protected))
> + *                     includes code by Alessio Caiazza
>    * All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
> @@ -64,6 +65,7 @@ union olsr_ip_addr jsoninfo_accept_ip;
>   union olsr_ip_addr jsoninfo_listen_ip;
>   int ipc_port;
>   int nompr;
> +bool http_headers;
>
>   static void my_init(void) __attribute__ ((constructor));
>   static void my_fini(void) __attribute__ ((destructor));
> @@ -79,6 +81,7 @@ my_init(void)
>
>     /* defaults for parameters */
>     ipc_port = 9090;
> +  http_headers = false;
>     if (olsr_cnf->ip_version == AF_INET) {
>       jsoninfo_accept_ip.v4.s_addr = htonl(INADDR_LOOPBACK);
>       jsoninfo_listen_ip.v4.s_addr = htonl(INADDR_ANY);
> @@ -120,11 +123,26 @@ store_string(const char *value, void *data, set_plugin_parameter_addon addon __a
>     return 0;
>   }
>
> +static int
> +store_boolean(const char *value, void *data, set_plugin_parameter_addon addon __attribute__ ((unused)))
> +{
> +  bool *dest = data;
> +  if(strcmp(value, "yes") == 0)
> +    *dest = true;
> +  else if (strcmp(value, "no") == 0)
> +    *dest = false;
> +  else
> +    return 1; //error
> +
> +  return 0;
> +}
> +
>   static const struct olsrd_plugin_parameters plugin_parameters[] = {
>     {.name = "port",.set_plugin_parameter = &set_plugin_port,.data = &ipc_port},
>     {.name = "accept",.set_plugin_parameter = &set_plugin_ipaddress,.data = &jsoninfo_accept_ip},
>     {.name = "listen",.set_plugin_parameter = &set_plugin_ipaddress,.data = &jsoninfo_listen_ip},
>     {.name = "uuidfile",.set_plugin_parameter = &store_string,.data = uuidfile},
> +  {.name = "httpheaders",.set_plugin_parameter = &store_boolean,.data = &http_headers},
>   };
>
>   void
>

-- 
Ferry Huberts




More information about the Olsr-dev mailing list