aboutsummaryrefslogtreecommitdiff
path: root/external/miniupnpc/minihttptestserver.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--[-rwxr-xr-x]external/miniupnpc/minihttptestserver.c173
1 files changed, 159 insertions, 14 deletions
diff --git a/external/miniupnpc/minihttptestserver.c b/external/miniupnpc/minihttptestserver.c
index b71936117..fb779650b 100755..100644
--- a/external/miniupnpc/minihttptestserver.c
+++ b/external/miniupnpc/minihttptestserver.c
@@ -1,7 +1,7 @@
-/* $Id: minihttptestserver.c,v 1.13 2012/05/29 13:03:07 nanard Exp $ */
+/* $Id: minihttptestserver.c,v 1.16 2014/04/01 15:08:28 nanard Exp $ */
/* Project : miniUPnP
* Author : Thomas Bernard
- * Copyright (c) 2011-2012 Thomas Bernard
+ * Copyright (c) 2011-2014 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
@@ -28,20 +28,20 @@ volatile sig_atomic_t child_to_wait_for = 0;
*/
void handle_signal_chld(int sig)
{
- printf("handle_signal_chld(%d)\n", sig);
+ (void)sig;
+ /* printf("handle_signal_chld(%d)\n", sig); */
++child_to_wait_for;
}
/**
* signal handler for SIGINT (CRTL C)
*/
-#if 0
void handle_signal_int(int sig)
{
- printf("handle_signal_int(%d)\n", sig);
+ (void)sig;
+ /* printf("handle_signal_int(%d)\n", sig); */
quit = 1;
}
-#endif
/**
* build a text/plain content of the specified length
@@ -94,7 +94,8 @@ void build_crap(char * p, int n)
* build chunked response.
* return a malloc'ed buffer
*/
-char * build_chunked_response(int content_length, int * response_len) {
+char * build_chunked_response(int content_length, int * response_len)
+{
char * response_buffer;
char * content_buffer;
int buffer_length;
@@ -141,7 +142,115 @@ char * build_chunked_response(int content_length, int * response_len) {
return response_buffer;
}
-enum modes { MODE_INVALID, MODE_CHUNKED, MODE_ADDCRAP, MODE_NORMAL };
+/* favicon.ico generator */
+#ifdef OLD_HEADER
+#define FAVICON_LENGTH (6 + 16 + 12 + 8 + 32 * 4)
+#else
+#define FAVICON_LENGTH (6 + 16 + 40 + 8 + 32 * 4)
+#endif
+void build_favicon_content(char * p, int n)
+{
+ int i;
+ if(n < FAVICON_LENGTH)
+ return;
+ /* header : 6 bytes */
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = 1; /* type : ICO */
+ *p++ = 0;
+ *p++ = 1; /* number of images in file */
+ *p++ = 0;
+ /* image directory (1 entry) : 16 bytes */
+ *p++ = 16; /* width */
+ *p++ = 16; /* height */
+ *p++ = 2; /* number of colors in the palette. 0 = no palette */
+ *p++ = 0; /* reserved */
+ *p++ = 1; /* color planes */
+ *p++ = 0; /* " */
+ *p++ = 1; /* bpp */
+ *p++ = 0; /* " */
+#ifdef OLD_HEADER
+ *p++ = 12 + 8 + 32 * 4; /* bmp size */
+#else
+ *p++ = 40 + 8 + 32 * 4; /* bmp size */
+#endif
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 6 + 16; /* bmp offset */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ /* BMP */
+#ifdef OLD_HEADER
+ /* BITMAPCOREHEADER */
+ *p++ = 12; /* size of this header */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 16; /* width */
+ *p++ = 0; /* " */
+ *p++ = 16 * 2; /* height x 2 ! */
+ *p++ = 0; /* " */
+ *p++ = 1; /* color planes */
+ *p++ = 0; /* " */
+ *p++ = 1; /* bpp */
+ *p++ = 0; /* " */
+#else
+ /* BITMAPINFOHEADER */
+ *p++ = 40; /* size of this header */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 16; /* width */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 16 * 2; /* height x 2 ! */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 0; /* " */
+ *p++ = 1; /* color planes */
+ *p++ = 0; /* " */
+ *p++ = 1; /* bpp */
+ *p++ = 0; /* " */
+ /* compression method, image size, ppm x, ppm y */
+ /* colors in the palette ? */
+ /* important colors */
+ for(i = 4 * 6; i > 0; --i)
+ *p++ = 0;
+#endif
+ /* palette */
+ *p++ = 0; /* b */
+ *p++ = 0; /* g */
+ *p++ = 0; /* r */
+ *p++ = 0; /* reserved */
+ *p++ = 255; /* b */
+ *p++ = 255; /* g */
+ *p++ = 255; /* r */
+ *p++ = 0; /* reserved */
+ /* pixel data */
+ for(i = 16; i > 0; --i) {
+ if(i & 1) {
+ *p++ = 0125;
+ *p++ = 0125;
+ } else {
+ *p++ = 0252;
+ *p++ = 0252;
+ }
+ *p++ = 0;
+ *p++ = 0;
+ }
+ /* Opacity MASK */
+ for(i = 16 * 4; i > 0; --i) {
+ *p++ = 0;
+ }
+}
+
+enum modes {
+ MODE_INVALID, MODE_CHUNKED, MODE_ADDCRAP, MODE_NORMAL, MODE_FAVICON
+};
+
const struct {
const enum modes mode;
const char * text;
@@ -149,6 +258,7 @@ const struct {
{MODE_CHUNKED, "chunked"},
{MODE_ADDCRAP, "addcrap"},
{MODE_NORMAL, "normal"},
+ {MODE_FAVICON, "favicon.ico"},
{MODE_INVALID, NULL}
};
@@ -201,6 +311,8 @@ void handle_http_connection(int c)
request_buffer + request_len,
sizeof(request_buffer) - request_len);
if(n < 0) {
+ if(errno == EINTR)
+ continue;
perror("read");
return;
} else if(n==0) {
@@ -219,6 +331,7 @@ void handle_http_connection(int c)
}
if(!headers_found) {
/* error */
+ printf("no HTTP header found in the request\n");
return;
}
printf("headers :\n%.*s", request_len, request_buffer);
@@ -292,6 +405,8 @@ void handle_http_connection(int c)
case MODE_ADDCRAP:
response_len = content_length+256;
response_buffer = malloc(response_len);
+ if(!response_buffer)
+ break;
n = snprintf(response_buffer, response_len,
"HTTP/1.1 200 OK\r\n"
"Server: minihttptestserver\r\n"
@@ -303,9 +418,27 @@ void handle_http_connection(int c)
build_content(response_buffer + n, content_length);
build_crap(response_buffer + n + content_length, CRAP_LENGTH);
break;
+ case MODE_FAVICON:
+ content_length = FAVICON_LENGTH;
+ response_len = content_length + 256;
+ response_buffer = malloc(response_len);
+ if(!response_buffer)
+ break;
+ n = snprintf(response_buffer, response_len,
+ "HTTP/1.1 200 OK\r\n"
+ "Server: minihttptestserver\r\n"
+ "Content-Type: image/vnd.microsoft.icon\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n", content_length);
+ /* image/x-icon */
+ build_favicon_content(response_buffer + n, content_length);
+ response_len = content_length + n;
+ break;
default:
response_len = content_length+256;
response_buffer = malloc(response_len);
+ if(!response_buffer)
+ break;
n = snprintf(response_buffer, response_len,
"HTTP/1.1 200 OK\r\n"
"Server: minihttptestserver\r\n"
@@ -338,6 +471,7 @@ int main(int argc, char * * argv) {
int child = 0;
int status;
const char * expected_file_name = NULL;
+ struct sigaction sa;
for(i = 1; i < argc; i++) {
if(argv[i][0] == '-') {
@@ -364,10 +498,21 @@ int main(int argc, char * * argv) {
}
srand(time(NULL));
- signal(SIGCHLD, handle_signal_chld);
-#if 0
- signal(SIGINT, handle_signal_int);
-#endif
+
+ memset(&sa, 0, sizeof(struct sigaction));
+
+ /*signal(SIGCHLD, handle_signal_chld);*/
+ sa.sa_handler = handle_signal_chld;
+ if(sigaction(SIGCHLD, &sa, NULL) < 0) {
+ perror("sigaction");
+ return 1;
+ }
+ /*signal(SIGINT, handle_signal_int);*/
+ sa.sa_handler = handle_signal_int;
+ if(sigaction(SIGINT, &sa, NULL) < 0) {
+ perror("sigaction");
+ return 1;
+ }
s = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
if(s < 0) {
@@ -442,12 +587,12 @@ int main(int argc, char * * argv) {
}
--child_to_wait_for;
}
- /* TODO : add a select() call in order to handle the case
- * when a signal is caught */
client_addrlen = sizeof(struct sockaddr_storage);
c = accept(s, (struct sockaddr *)&client_addr,
&client_addrlen);
if(c < 0) {
+ if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
+ continue;
perror("accept");
return 1;
}