From b24ba2f5d4f734f8e6fa9cd27b5a5b66773c4c78 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Tue, 22 Jan 2008 21:22:10 +0000 Subject: [PATCH] * correctly handle tcp write, so that we work properly on openbsd. Thanks to Maide for this work. --- webcit/webcit.c | 37 ++++++++++++++++++++++++++++++++----- webcit/webserver.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/webcit/webcit.c b/webcit/webcit.c index 9b8d74a69..da8d02141 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -676,6 +676,8 @@ void output_static(char *what) FILE *fp; struct stat statbuf; off_t bytes; + off_t count = 0; + size_t res; char *bigbuffer; char content_type[128]; int len; @@ -683,10 +685,10 @@ void output_static(char *what) fp = fopen(what, "rb"); if (fp == NULL) { lprintf(9, "output_static('%s') -- NOT FOUND --\n", what); - wprintf("HTTP/1.1 404 %s\n", strerror(errno)); + wprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); wprintf("Content-Type: text/plain\r\n"); wprintf("\r\n"); - wprintf("Cannot open %s: %s\n", what, strerror(errno)); + wprintf("Cannot open %s: %s\r\n", what, strerror(errno)); } else { len = strlen (what); if (!strncasecmp(&what[len - 4], ".gif", 4)) @@ -720,10 +722,35 @@ void output_static(char *what) else safestrncpy(content_type, "application/octet-stream", sizeof content_type); - fstat(fileno(fp), &statbuf); + if (fstat(fileno(fp), &statbuf) == -1) { + lprintf(9, "output_static('%s') -- FSTAT FAILED --\n", what); + wprintf("HTTP/1.1 404 %s\r\n", strerror(errno)); + wprintf("Content-Type: text/plain\r\n"); + wprintf("\r\n"); + wprintf("Cannot fstat %s: %s\n", what, strerror(errno)); + return; + } + + count = 0; bytes = statbuf.st_size; - bigbuffer = malloc(bytes + 2); - fread(bigbuffer, bytes, 1, fp); + if ((bigbuffer = malloc(bytes + 2)) == NULL) { + lprintf(9, "output_static('%s') -- MALLOC FAILED (%s) --\n", what, strerror(errno)); + wprintf("HTTP/1.1 500 internal server error\r\n"); + wprintf("Content-Type: text/plain\r\n"); + wprintf("\r\n"); + return; + } + while (count < bytes) { + if ((res = fread(bigbuffer + count, 1, bytes - count, fp)) == 0) { + lprintf(9, "output_static('%s') -- FREAD FAILED (%s) %zu bytes of %zu --\n", what, strerror(errno), bytes - count, bytes); + wprintf("HTTP/1.1 500 internal server error \r\n"); + wprintf("Content-Type: text/plain\r\n"); + wprintf("\r\n"); + return; + } + count += res; + } + fclose(fp); lprintf(9, "output_static('%s') %s\n", what, content_type); diff --git a/webcit/webserver.c b/webcit/webserver.c index 2bb927030..9a409e3a5 100644 --- a/webcit/webserver.c +++ b/webcit/webserver.c @@ -108,7 +108,10 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len) i = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); - fcntl(s, F_SETFL, O_NONBLOCK);/// TODO + fcntl(s, F_SETFL, O_NONBLOCK); /* maide: this statement is incorrect + there should be a preceding F_GETFL + and a bitwise OR with the previous + fd flags */ if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { lprintf(1, "Can't bind: %s\n", strerror(errno)); @@ -237,8 +240,12 @@ int client_read_to(int sock, char *buf, int bytes, int timeout) */ ssize_t client_write(const void *buf, size_t count) { - char *newptr; - size_t newalloc; + char *newptr; + size_t newalloc; + size_t bytesWritten = 0; + ssize_t res; + fd_set wset; + int fdflags; if (WC->burst != NULL) { if ((WC->burst_len + count) >= WC->burst_alloc) { @@ -272,7 +279,26 @@ ssize_t client_write(const void *buf, size_t count) write(2, buf, count); write(2, "\033[30m", 5); #endif - return (write(WC->http_sock, buf, count)); + + while (bytesWritten < count) { + if ((fdflags & O_NONBLOCK) == O_NONBLOCK) { + FD_ZERO(&wset); + FD_SET(WC->http_sock, &wset); + if (select(1, NULL, &wset, NULL, NULL) == -1) { + lprintf(2, "client_write: Socket select failed (%s)\n", strerror(errno)); + return -1; + } + } + + if ((res = write(WC->http_sock, (char*)buf + bytesWritten, + count - bytesWritten)) == -1) { + lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno)); + return res; + } + bytesWritten += res; + } + + return bytesWritten; } /* -- 2.39.2