#include "telemetry.h"
#include "tele2json.h"
-static struct telemetry_state_t *telemetry;
-static struct telemetry_state_t telemetry0;
+struct thread_data_t {
+ int sock;
+ struct telemetry_state_t tele;
+};
struct {
int port;
false,
};
-struct thread_data_t {
- int sock;
- struct telemetry_state_t tele;
-};
+static struct telemetry_state_t *telemetry;
+static struct telemetry_state_t telemetry0;
-static volatile int force_quit;
+static volatile sig_atomic_t force_quit;
static void handle_signal(int sig) {
fprintf (stderr, "SIGNAL: %d\n", sig);
return 0;
}
+static size_t copy_field_val( char *buf, size_t bufsz, const char *needle, const char *haystack, const char *def ) {
+ const char *s;
+ size_t l;
+
+ if ( NULL != ( s = strstr( haystack, needle ) ) ) {
+ const char *e;
+ s += strlen( needle );
+ if ( NULL != ( e = strstr( s, "\r\n" ) ) )
+ l = e - s;
+ else
+ s = NULL;
+ }
+ if ( NULL == s ) {
+ s = def;
+ l = def ? strlen( def ) : 0;
+ }
+ l = l < bufsz ? l : 0;
+ for ( size_t i = 0; i < l; i++ )
+ buf[i] = s[i];
+ buf[l] = '\0';
+ return l;
+}
+
static void respond( struct thread_data_t *td, const char *req ) {
- char buf[4096];
+ int n;
+ char buf[4096]; // Must be large enough to satisfy tele2json()!
char origin[256];
char host[256];
- const char *s;
- int fd = td->sock;
enum respond_code {
r_index,
r_json,
else
code = r_none;
+ copy_field_val( host, sizeof host, "Host: ", req, cfg.host );
+
switch (code) {
case r_json:
- case r_index:
- if ( NULL != (s = strstr(req, "Origin: ")) ) {
- s += 8; //strlen("Origin: ");
- const char *e = strstr(s, "\r\n");
- strncpy(origin, s, e-s);
- }
- else
- strcpy(origin, cfg.origin);
-
- if ( NULL != (s = strstr(req, "Host: ")) ) {
- s += 6;//strlen("Host: ");
- const char *e = strstr(s, "\r\n");
- strncpy(host, s, e-s);
- }
- else
- strcpy(host, cfg.host);
-
- if (r_json == code){
- write(fd, buf, sprintf(buf, "HTTP/1.1 200 OK\r\n"));
- write(fd, buf, sprintf(buf, "Host: %s\r\n", host));
- write(fd, buf, sprintf(buf, "Access-Control-Allow-Origin: %s\r\n", origin));
- write(fd, buf, sprintf(buf, "Content-type: text/json\r\n"));
- write(fd, buf, sprintf(buf, "Connection: close\r\n\r\n"));
- write( fd, buf, tele2json(buf, sizeof buf, &td->tele) );
- }
- else {
- struct file_info_t fi;
- if (0 == fserv_open_server(cfg.idxfile, &fi)){
- write(fd, buf, sprintf(buf, "HTTP/1.1 200 OK\r\n"));
- write(fd, buf, sprintf(buf, "Host: %s\r\n", host));
- write(fd, buf, sprintf(buf, "Content-type: text/html\r\n"));
- write(fd, buf, sprintf(buf, "Connection: close\r\n\r\n"));
- fserv_sendfile(fd, &fi);
- fserv_close(&fi);
+ copy_field_val( origin, sizeof origin, "Origin: ", req, cfg.origin );
+ n = snprintf( buf, sizeof buf,
+ "HTTP/1.1 200 OK\r\n"
+ "Host: %s\r\n"
+ "Access-Control-Allow-Origin: %s\r\n"
+ "Content-type: text/json\r\n"
+ "Connection: close\r\n"
+ "\r\n",
+ host,
+ origin
+ );
+ if ( 0 < n && (size_t)n < sizeof buf && n == write( td->sock, buf, n ) )
+ write( td->sock, buf, tele2json( buf, sizeof buf, &td->tele ) );
+ break;
+ case r_index: {
+ struct file_info_t fi;
+ if ( 0 == fserv_open_server( cfg.idxfile, &fi ) ){
+ n = snprintf( buf, sizeof buf,
+ "HTTP/1.1 200 OK\r\n"
+ "Host: %s\r\n"
+ "Content-type: text/html\r\n"
+ "Connection: close\r\n"
+ "\r\n",
+ host
+ );
+ if ( 0 < n && (size_t)n < sizeof buf && n == write( td->sock, buf, n ) ) {
+ fserv_sendfile( td->sock, &fi );
+ fserv_close( &fi );
}
- else
- goto SEND_404;
}
+ else
+ goto SEND_404;
break;
+ }
case r_none:
SEND_404:
- write(fd, buf, sprintf(buf, "HTTP/1.1 404 Not Found\r\n"));
- write(fd, buf, sprintf(buf, "Host: localhost\r\n"));
- write(fd, buf, sprintf(buf, "Content-type: text/plain\r\n"));
- write(fd, buf, sprintf(buf, "Connection: close\r\n\r\n"));
- write(fd, buf, sprintf(buf, "404 Not Found"));
+ n = snprintf( buf, sizeof buf,
+ "HTTP/1.1 404 Not Found\r\n"
+ "Host: %s\r\n"
+ "Content-type: text/plain\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "404 Not Found",
+ host
+ );
+ if ( 0 < n && (size_t)n < sizeof buf )
+ write( td->sock, buf, n );
break;
default:
- write(fd, buf, sprintf(buf, "HTTP/1.1 500 Internal Server Error\r\n"));
- write(fd, buf, sprintf(buf, "Host: localhost\r\n"));
- write(fd, buf, sprintf(buf, "Content-type: text/plain\r\n"));
- write(fd, buf, sprintf(buf, "Connection: close\r\n\r\n"));
- write(fd, buf, sprintf(buf, "500 Internal Server Error"));
+ n = snprintf( buf, sizeof buf,
+ "HTTP/1.1 500 Internal Server Error\r\n"
+ "Host: %s\r\n"
+ "Content-type: text/plain\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ "500 Internal Server Error",
+ host
+ );
+ if ( 0 < n && (size_t)n < sizeof buf )
+ write( td->sock, buf, n );
break;
}
}