From 23fcabeb4944b5e79e80a37127ed84ec8a639ed8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sat, 6 Feb 2010 10:37:35 +0000 Subject: [PATCH] * move serv_func.c:read_server_binary() to tcp_sockets.c: serv_read_binary() * serv_read_binary() now knows a way to get the whole thing at once instead of scattering in 4k blocks * close the server file in all conditions while loading images, else our facility might block in the server * add -R commandline switch so the user can limit the blobsize if the tcp connection citserver <-> webcit is expected to be less stable --- webcit/downloads.c | 10 ++-- webcit/messages.c | 2 +- webcit/serv_func.c | 47 ------------------ webcit/tcp_sockets.c | 111 +++++++++++++++++++++++++++++++++++++++++++ webcit/webcit.h | 2 +- webcit/webserver.c | 9 ++-- 6 files changed, 125 insertions(+), 56 deletions(-) diff --git a/webcit/downloads.c b/webcit/downloads.c index 8544aabb9..137a6389d 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -259,7 +259,7 @@ void download_file(void) if (!force_download) { StrBufExtract_token(ContentType, Buf, 3, '|'); } - read_server_binary(WCC->WBuf, bytes, Buf); + serv_read_binary(WCC->WBuf, bytes, Buf); serv_puts("CLOS"); StrBuf_ServGetln(Buf); http_transmit_thing(ChrPtr(ContentType), 0); @@ -360,15 +360,17 @@ void output_image(void) serv_printf("OIMG %s|%s", bstr("name"), bstr("parm")); StrBuf_ServGetln(Buf); if (GetServerStatus(Buf, NULL) == 2) { + int rc; StrBufCutLeft(Buf, 4); bytes = StrBufExtract_long(Buf, 0, '|'); /** Read it from the server */ - if (read_server_binary(WCC->WBuf, bytes, Buf) > 0) { - serv_puts("CLOS"); - StrBuf_ServGetln(Buf); + rc = serv_read_binary(WCC->WBuf, bytes, Buf); + serv_puts("CLOS"); + StrBuf_ServGetln(Buf); + if (rc > 0) { MimeType = GuessMimeType (ChrPtr(WCC->WBuf), StrLength(WCC->WBuf)); /** Write it to the browser */ if (!IsEmptyStr(MimeType)) diff --git a/webcit/messages.c b/webcit/messages.c index 957968855..d09c88f9e 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -1520,7 +1520,7 @@ void mimepart(int force_download) StrBufExtract_token(ContentType, Buf, 3, '|'); } - read_server_binary(WCC->WBuf, bytes, Buf); + serv_read_binary(WCC->WBuf, bytes, Buf); serv_puts("CLOS"); StrBuf_ServGetln(Buf); CT = ChrPtr(ContentType); diff --git a/webcit/serv_func.c b/webcit/serv_func.c index 3a6487172..654cb4f2d 100644 --- a/webcit/serv_func.c +++ b/webcit/serv_func.c @@ -533,53 +533,6 @@ void server_to_text() -/** - * Read binary data from server into memory using a series of - * server READ commands. - * \return the read content as StrBuf - */ -int read_server_binary(StrBuf *Ret, size_t total_len, StrBuf *Buf) -{ - wcsession *WCC = WC; - size_t bytes = 0; - size_t thisblock = 0; - - if (Ret == NULL) - return -1; - - while ((WCC->serv_sock!=-1) && - (bytes < total_len)) { - thisblock = 4095; - if ((total_len - bytes) < thisblock) { - thisblock = total_len - bytes; - if (thisblock == 0) { - FlushStrBuf(Ret); - return -1; - } - } - serv_printf("READ %d|%d", (int)bytes, (int)thisblock); - if (StrBuf_ServGetln(Buf) > 0) - { - if (GetServerStatus(Buf, NULL) == 6) - { - StrBufCutLeft(Buf, 4); - thisblock = StrTol(Buf); - if (WCC->serv_sock==-1) { - FlushStrBuf(Ret); - return -1; - } - StrBuf_ServGetBLOBBuffered(Ret, thisblock); - bytes += thisblock; - } - else { - lprintf(3, "Error: %s\n", ChrPtr(Buf) + 4); - return -1; - } - } - } - return StrLength(Ret); -} - /** * Read text from server, appending to a string buffer until the diff --git a/webcit/tcp_sockets.c b/webcit/tcp_sockets.c index 9c2393b9f..23bdf7bea 100644 --- a/webcit/tcp_sockets.c +++ b/webcit/tcp_sockets.c @@ -12,6 +12,7 @@ #include "webserver.h" extern int DisableGzip; +long MaxRead = -1; /* should we do READ scattered or all at once? */ /* * register the timeout @@ -324,6 +325,116 @@ void serv_printf(const char *format,...) +/** + * Read binary data from server into memory using a series of + * server READ commands. + * \return the read content as StrBuf + */ +int serv_read_binary(StrBuf *Ret, size_t total_len, StrBuf *Buf) +{ + wcsession *WCC = WC; + size_t bytes = 0; + size_t thisblock = 0; + + if (Ret == NULL) + return -1; + + if (MaxRead == -1) + { + serv_printf("READ %d|%d", 0, total_len); + if (StrBuf_ServGetln(Buf) > 0) + { + long YetRead; + const char *ErrStr; + const char *pch; + int rc; + + if (GetServerStatus(Buf, NULL) == 6) + { + StrBufCutLeft(Buf, 4); + thisblock = StrTol(Buf); + if (WCC->serv_sock==-1) { + FlushStrBuf(Ret); + return -1; + } + + pch = ChrPtr(WCC->ReadBuf); + YetRead = WCC->ReadPos - pch; + if (YetRead > 0) + { + long StillThere; + + StillThere = StrLength(WCC->ReadBuf) - + YetRead; + + StrBufPlain(Ret, + WCC->ReadPos, + StillThere); + total_len -= StillThere; + } + FlushStrBuf(WCC->ReadBuf); + WCC->ReadPos = NULL; + + if (total_len > 0) + { + rc = StrBufReadBLOB(Ret, + &WCC->serv_sock, + 1, + total_len, + &ErrStr); + if (rc < 0) + { + lprintf(1, "Server connection broken: %s\n", + (ErrStr)?ErrStr:""); + wc_backtrace(); + WCC->serv_sock = (-1); + WCC->connected = 0; + WCC->logged_in = 0; + return rc; + } + else + return StrLength(Ret); + } + else + return StrLength(Ret); + } + } + else + return -1; + } + else while ((WCC->serv_sock!=-1) && + (bytes < total_len)) { + thisblock = MaxRead; + if ((total_len - bytes) < thisblock) { + thisblock = total_len - bytes; + if (thisblock == 0) { + FlushStrBuf(Ret); + return -1; + } + } + serv_printf("READ %d|%d", (int)bytes, (int)thisblock); + if (StrBuf_ServGetln(Buf) > 0) + { + if (GetServerStatus(Buf, NULL) == 6) + { + StrBufCutLeft(Buf, 4); + thisblock = StrTol(Buf); + if (WCC->serv_sock==-1) { + FlushStrBuf(Ret); + return -1; + } + StrBuf_ServGetBLOBBuffered(Ret, thisblock); + bytes += thisblock; + } + else { + lprintf(3, "Error: %s\n", ChrPtr(Buf) + 4); + return -1; + } + } + } + return StrLength(Ret); +} + int ClientGetLine(ParsedHttpHdrs *Hdr, StrBuf *Target) { diff --git a/webcit/webcit.h b/webcit/webcit.h index 8d919464d..a82ef0241 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -769,7 +769,7 @@ int ical_ctdl_is_overlap( extern char *months[]; extern char *days[]; -int read_server_binary(StrBuf *Ret, size_t total_len, StrBuf *Buf); +int serv_read_binary(StrBuf *Ret, size_t total_len, StrBuf *Buf); int StrBuf_ServGetBLOB(StrBuf *buf, long BlobSize); int StrBuf_ServGetBLOBBuffered(StrBuf *buf, long BlobSize); int read_server_text(StrBuf *Buf, long *nLines); diff --git a/webcit/webserver.c b/webcit/webserver.c index e05dffddf..6d02afed2 100644 --- a/webcit/webserver.c +++ b/webcit/webserver.c @@ -22,7 +22,7 @@ int vsnprintf(char *buf, size_t max, const char *fmt, va_list argp); extern int msock; /* master listening socket */ extern int verbosity; /* Logging level */ extern char static_icon_dir[PATH_MAX]; /* where should we find our mime icons */ - +extern long MaxRead; int is_https = 0; /* Nonzero if I am an HTTPS service */ int follow_xff = 0; /* Follow X-Forwarded-For: header */ int home_specified = 0; /* did the user specify a homedir? */ @@ -114,9 +114,9 @@ int main(int argc, char **argv) /* Parse command line */ #ifdef HAVE_OPENSSL - while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfsS:Z")) != EOF) + while ((a = getopt(argc, argv, "R:u:h:i:p:t:T:B:x:dD:G:cfsS:Z")) != EOF) #else - while ((a = getopt(argc, argv, "u:h:i:p:t:T:B:x:dD:G:cfZ")) != EOF) + while ((a = getopt(argc, argv, "R:u:h:i:p:t:T:B:x:dD:G:cfZ")) != EOF) #endif switch (a) { case 'u': @@ -205,6 +205,9 @@ int main(int argc, char **argv) I18nDump = NewStrBufPlain(HKEY("int templatestrings(void)\n{\n")); I18nDumpFile = optarg; break; + case 'R': + MaxRead = atol(optarg); + break; default: fprintf(stderr, "usage: webcit " "[-i ip_addr] [-p http_port] " -- 2.30.2