X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Ftcp_sockets.c;h=3e3194b341859ff8a729d0eb66a838c490f7dd75;hb=e7923ad2e2db07d95b5d127f12f17d89dd9fe279;hp=53ff1ebce774cad36594bb7773bf4370daf53637;hpb=53b0c0c8794b64528d7384bf3500a5367a03d358;p=citadel.git diff --git a/webcit/tcp_sockets.c b/webcit/tcp_sockets.c index 53ff1ebce..3e3194b34 100644 --- a/webcit/tcp_sockets.c +++ b/webcit/tcp_sockets.c @@ -14,9 +14,7 @@ extern int DisableGzip; /* - * register the timeout - * signum signalhandler number - * \return signals + * register the timeout */ RETSIGTYPE timeout(int signum) { @@ -174,7 +172,7 @@ int StrBuf_ServGetln(StrBuf *buf) if (rc < 0) { lprintf(1, "Server connection broken: %s\n", - ErrStr); + (ErrStr)?ErrStr:""); wc_backtrace(); WCC->serv_sock = (-1); WCC->connected = 0; @@ -186,7 +184,7 @@ int StrBuf_ServGetln(StrBuf *buf) int StrBuf_ServGetBLOBBuffered(StrBuf *buf, long BlobSize) { wcsession *WCC = WC; - const char *Err; + const char *ErrStr; int rc; rc = StrBufReadBLOBBuffered(buf, @@ -196,11 +194,11 @@ int StrBuf_ServGetBLOBBuffered(StrBuf *buf, long BlobSize) 1, BlobSize, NNN_TERM, - &Err); + &ErrStr); if (rc < 0) { lprintf(1, "Server connection broken: %s\n", - Err); + (ErrStr)?ErrStr:""); wc_backtrace(); WCC->serv_sock = (-1); WCC->connected = 0; @@ -212,15 +210,15 @@ int StrBuf_ServGetBLOBBuffered(StrBuf *buf, long BlobSize) int StrBuf_ServGetBLOB(StrBuf *buf, long BlobSize) { wcsession *WCC = WC; - const char *Err; + const char *ErrStr; int rc; WCC->ReadPos = NULL; - rc = StrBufReadBLOB(buf, &WCC->serv_sock, 1, BlobSize, &Err); + rc = StrBufReadBLOB(buf, &WCC->serv_sock, 1, BlobSize, &ErrStr); if (rc < 0) { lprintf(1, "Server connection broken: %s\n", - Err); + (ErrStr)?ErrStr:""); wc_backtrace(); WCC->serv_sock = (-1); WCC->connected = 0; @@ -246,8 +244,9 @@ void serv_write(const char *buf, int nbytes) retval = write(WCC->serv_sock, &buf[bytes_written], nbytes - bytes_written); if (retval < 1) { + const char *ErrStr = strerror(errno); lprintf(1, "Server connection broken: %s\n", - strerror(errno)); + (ErrStr)?ErrStr:""); close(WCC->serv_sock); WCC->serv_sock = (-1); WCC->connected = 0; @@ -416,7 +415,7 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len) if (port_number == 0) { lprintf(1, "Cannot start: no port number specified.\n"); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } sin.sin_port = htons((u_short) port_number); @@ -425,7 +424,7 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len) s = socket(PF_INET, SOCK_STREAM, (p->p_proto)); if (s < 0) { lprintf(1, "Can't create a socket: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } /* Set some socket options that make sense. */ i = 1; @@ -440,11 +439,11 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len) if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { lprintf(1, "Can't bind: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } if (listen(s, queue_len) < 0) { lprintf(1, "Can't listen: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } return (s); } @@ -470,7 +469,7 @@ int ig_uds_server(char *sockpath, int queue_len) if ((i != 0) && (errno != ENOENT)) { lprintf(1, "webcit: can't unlink %s: %s\n", sockpath, strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } memset(&addr, 0, sizeof(addr)); @@ -481,19 +480,19 @@ int ig_uds_server(char *sockpath, int queue_len) if (s < 0) { lprintf(1, "webcit: Can't create a socket: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { lprintf(1, "webcit: Can't bind: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } if (listen(s, actual_queue_len) < 0) { lprintf(1, "webcit: Can't listen: %s\n", strerror(errno)); - exit(WC_EXIT_BIND); + return (-WC_EXIT_BIND); } chmod(sockpath, 0777); @@ -523,27 +522,41 @@ int client_read_to(ParsedHttpHdrs *Hdr, StrBuf *Target, int bytes, int timeout) #ifdef HAVE_OPENSSL if (is_https) { - long bufremain = StrLength(Hdr->ReadBuf) - (Hdr->Pos - ChrPtr(Hdr->ReadBuf)); + long bufremain; + long baselen; + + baselen = StrLength(Target); + + if (Hdr->Pos == NULL) + Hdr->Pos = ChrPtr(Hdr->ReadBuf); + bufremain = StrLength(Hdr->ReadBuf) - (Hdr->Pos - ChrPtr(Hdr->ReadBuf)); + + if (bytes < bufremain) + bufremain = bytes; StrBufAppendBufPlain(Target, Hdr->Pos, bufremain, 0); - Hdr->Pos = NULL; - FlushStrBuf(Hdr->ReadBuf); - - while ((StrLength(Hdr->ReadBuf) + StrLength(Target) < bytes) && - (retval >= 0)) - retval = client_read_sslbuffer(Hdr->ReadBuf, timeout); - if (retval >= 0) { - StrBufAppendBuf(Target, Hdr->ReadBuf, 0); /* todo: Buf > bytes? */ + StrBufCutLeft(Hdr->ReadBuf, bufremain); + + if (bytes > bufremain) + { + while ((StrLength(Hdr->ReadBuf) + StrLength(Target) < bytes + baselen) && + (retval >= 0)) + retval = client_read_sslbuffer(Hdr->ReadBuf, timeout); + if (retval >= 0) { + StrBufAppendBuf(Target, Hdr->ReadBuf, 0); /* todo: Buf > bytes? */ #ifdef HTTP_TRACING - write(2, "\033[32m", 5); - write(2, buf, bytes); - write(2, "\033[30m", 5); + write(2, "\033[32m", 5); + write(2, buf, bytes); + write(2, "\033[30m", 5); #endif - return 1; - } - else { - lprintf(2, "client_read_ssl() failed\n"); - return -1; + return 1; + } + else { + lprintf(2, "client_read_ssl() failed\n"); + return -1; + } } + else + return 1; } #endif @@ -589,13 +602,18 @@ long end_burst(void) wcsession *WCC = WC; const char *ptr, *eptr; long count; - ssize_t res; + ssize_t res = 0; fd_set wset; int fdflags; - if (!DisableGzip && (WCC->Hdr->HR.gzip_ok) && CompressBuffer(WCC->WBuf)) + if (!DisableGzip && (WCC->Hdr->HR.gzip_ok)) { - hprintf("Content-encoding: gzip\r\n"); + if (CompressBuffer(WCC->WBuf) > 0) + hprintf("Content-encoding: gzip\r\n"); + else { + lprintf(CTDL_ALERT, "Compression failed: %d [%s] sending uncompressed\n", errno, strerror(errno)); + wc_backtrace(); + } } if (WCC->Hdr->HR.prohibit_caching) @@ -621,9 +639,11 @@ long end_burst(void) write(2, ptr, StrLength(WCC->WBuf)); write(2, "\033[30m", 5); #endif + if (WCC->Hdr->http_sock == -1) + return -1; fdflags = fcntl(WC->Hdr->http_sock, F_GETFL); - while (ptr < eptr) { + while ((ptr < eptr) && (WCC->Hdr->http_sock != -1)){ if ((fdflags & O_NONBLOCK) == O_NONBLOCK) { FD_ZERO(&wset); FD_SET(WCC->Hdr->http_sock, &wset); @@ -633,7 +653,8 @@ long end_burst(void) } } - if ((res = write(WCC->Hdr->http_sock, + if ((WCC->Hdr->http_sock == -1) || + (res = write(WCC->Hdr->http_sock, ptr, count)) == -1) { lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno)); @@ -655,7 +676,7 @@ long end_burst(void) write(2, "\033[30m", 5); #endif - while (ptr < eptr) { + while ((ptr < eptr) && (WCC->Hdr->http_sock != -1)) { if ((fdflags & O_NONBLOCK) == O_NONBLOCK) { FD_ZERO(&wset); FD_SET(WCC->Hdr->http_sock, &wset); @@ -665,7 +686,8 @@ long end_burst(void) } } - if ((res = write(WCC->Hdr->http_sock, + if ((WCC->Hdr->http_sock == -1) || + (res = write(WCC->Hdr->http_sock, ptr, count)) == -1) { lprintf(2, "client_write: Socket write failed (%s)\n", strerror(errno)); @@ -692,6 +714,8 @@ int lingering_close(int fd) struct timeval tv, start; gettimeofday(&start, NULL); + if (fd == -1) + return -1; shutdown(fd, 1); do { do {