* move stuff from Hdr into substruct that may be easily wiped by memset 0'ing them
authorWilfried Göesgens <willi@citadel.org>
Sun, 24 May 2009 19:55:08 +0000 (19:55 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sun, 24 May 2009 19:55:08 +0000 (19:55 +0000)
* Hdr now belongs to the worker_entry() so we can lower the frequency of it and its members being de/alloced
* add commandline switch to set the default size of StrBuf s

21 files changed:
webcit/auth.c
webcit/config.guess
webcit/config.sub
webcit/context_loop.c
webcit/downloads.c
webcit/groupdav_main.c
webcit/listsub.c
webcit/mainmenu.c
webcit/messages.c
webcit/openid.c
webcit/paramhandling.c
webcit/roomops.c
webcit/rss.c
webcit/serv_func.c
webcit/static.c
webcit/tcp_sockets.c
webcit/vcard_edit.c
webcit/webcit.c
webcit/webcit.h
webcit/webserver.c
webcit/webserver.h

index 2e317b2..a751b89 100644 (file)
@@ -322,8 +322,8 @@ void do_openid_login(void)
                snprintf(buf, sizeof buf,
                        "OIDS %s|%s://%s/finalize_openid_login|%s://%s",
                        bstr("openid_url"),
-                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host),
-                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host)
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host),
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host)
                );
 
                serv_puts(buf);
@@ -906,13 +906,13 @@ void _display_reg(void) {display_reg(0);}
 
 void Header_HandleAuth(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       if (hdr->got_auth == NO_AUTH) /* don't override cookie auth... */
+       if (hdr->HR.got_auth == NO_AUTH) /* don't override cookie auth... */
        {
                if (strncasecmp(ChrPtr(Line), "Basic", 5) == 0) {
                        StrBufCutLeft(Line, 6);
                        StrBufDecodeBase64(Line);
-                       hdr->plainauth = Line;
-                       hdr->got_auth = AUTH_BASIC;
+                       hdr->HR.plainauth = Line;
+                       hdr->HR.got_auth = AUTH_BASIC;
                }
                else 
                        lprintf(1, "Authentication scheme not supported! [%s]\n", ChrPtr(Line));
@@ -926,9 +926,9 @@ void CheckAuthBasic(ParsedHttpHdrs *hdr)
        if (hdr->DontNeedAuth)
                return;
 */
-       StrBufAppendBufPlain(hdr->plainauth, HKEY(":"), 0);
-       StrBufAppendBuf(hdr->plainauth, hdr->user_agent, 0);
-       hdr->SessionKey = hashlittle(SKEY(hdr->plainauth), 89479832);
+       StrBufAppendBufPlain(hdr->HR.plainauth, HKEY(":"), 0);
+       StrBufAppendBuf(hdr->HR.plainauth, hdr->HR.user_agent, 0);
+       hdr->HR.SessionKey = hashlittle(SKEY(hdr->HR.plainauth), 89479832);
        
 }
 
@@ -939,8 +939,8 @@ void GetAuthBasic(ParsedHttpHdrs *hdr)
                hdr->c_username = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
        if (hdr->c_password == NULL)
                hdr->c_password = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
-       StrBufExtract_NextToken(hdr->c_username, hdr->plainauth, &Pos, ':');
-       StrBufExtract_NextToken(hdr->c_password, hdr->plainauth, &Pos, ':');
+       StrBufExtract_NextToken(hdr->c_username, hdr->HR.plainauth, &Pos, ':');
+       StrBufExtract_NextToken(hdr->c_password, hdr->HR.plainauth, &Pos, ':');
 }
 
 void Header_HandleCookie(StrBuf *Line, ParsedHttpHdrs *hdr)
@@ -956,9 +956,9 @@ void Header_HandleCookie(StrBuf *Line, ParsedHttpHdrs *hdr)
                return;
        }
 
-       hdr->RawCookie = Line;
-       StrBufCutLeft(hdr->RawCookie, (pch - ChrPtr(hdr->RawCookie)) + 7);
-       StrBufDecodeHex(hdr->RawCookie);
+       hdr->HR.RawCookie = Line;
+       StrBufCutLeft(hdr->HR.RawCookie, (pch - ChrPtr(hdr->HR.RawCookie)) + 7);
+       StrBufDecodeHex(hdr->HR.RawCookie);
 
        if (hdr->c_username == NULL)
                hdr->c_username = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
@@ -968,13 +968,13 @@ void Header_HandleCookie(StrBuf *Line, ParsedHttpHdrs *hdr)
                hdr->c_roomname = NewStrBuf();
        if (hdr->c_language == NULL)
                hdr->c_language = NewStrBuf();
-       cookie_to_stuff(Line, &hdr->desired_session,
+       cookie_to_stuff(Line, &hdr->HR.desired_session,
                        hdr->c_username,
                        hdr->c_password,
                        hdr->c_roomname,
                        hdr->c_language
        );
-       hdr->got_auth = AUTH_COOKIE;
+       hdr->HR.got_auth = AUTH_COOKIE;
 }
 
 void 
index da83314..f32079a 100755 (executable)
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
 #   Free Software Foundation, Inc.
 
-timestamp='2009-04-27'
+timestamp='2008-01-23'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -324,9 +324,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        case `/usr/bin/uname -p` in
            sparc) echo sparc-icl-nx7; exit ;;
        esac ;;
-    s390x:SunOS:*:*)
-       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
     sun4H:SunOS:5.*:*)
        echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
@@ -334,20 +331,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       eval $set_cc_for_build
-       SUN_ARCH="i386"
-       # If there is a compiler, see if it is configured for 64-bit objects.
-       # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
-       # This test works for both compilers.
-       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-           if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-               grep IS_64BIT_ARCH >/dev/null
-           then
-               SUN_ARCH="x86_64"
-           fi
-       fi
-       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
     sun4*:SunOS:6*:*)
        # According to config.sub, this is the proper way to canonicalize
@@ -812,7 +796,7 @@ EOF
            x86)
                echo i586-pc-interix${UNAME_RELEASE}
                exit ;;
-           EM64T | authenticamd | genuineintel)
+           EM64T | authenticamd)
                echo x86_64-unknown-interix${UNAME_RELEASE}
                exit ;;
            IA64)
@@ -951,9 +935,6 @@ EOF
        if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
        echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
        exit ;;
-    padre:Linux:*:*)
-       echo sparc-unknown-linux-gnu
-       exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -1004,6 +985,9 @@ EOF
          a.out-i386-linux)
                echo "${UNAME_MACHINE}-pc-linux-gnuaout"
                exit ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit ;;
          "")
                # Either a pre-BFD a.out linker (linux-gnuoldld) or
                # one that does not give us useful --help.
@@ -1118,11 +1102,8 @@ EOF
     pc:*:*:*)
        # Left here for compatibility:
         # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i586.
-       # Note: whatever this is, it MUST be the same as what config.sub
-       # prints for the "djgpp" host, or else GDB configury will decide that
-       # this is a cross-build.
-       echo i586-pc-msdosdjgpp
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
         exit ;;
     Intel:Mach:3*:*)
        echo i386-pc-mach3
@@ -1160,16 +1141,6 @@ EOF
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
           && { echo i486-ncr-sysv4; exit; } ;;
-    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
-       OS_REL='.3'
-       test -r /etc/.relid \
-           && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
        echo m68k-unknown-lynxos${UNAME_RELEASE}
        exit ;;
@@ -1245,9 +1216,6 @@ EOF
     BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
        echo i586-pc-beos
        exit ;;
-    BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
-       echo i586-pc-haiku
-       exit ;;
     SX-4:SUPER-UX:*:*)
        echo sx4-nec-superux${UNAME_RELEASE}
        exit ;;
@@ -1356,9 +1324,6 @@ EOF
     i*86:rdos:*:*)
        echo ${UNAME_MACHINE}-pc-rdos
        exit ;;
-    i*86:AROS:*:*)
-       echo ${UNAME_MACHINE}-pc-aros
-       exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
index a39437d..6759825 100755 (executable)
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
 #   Free Software Foundation, Inc.
 
-timestamp='2009-04-17'
+timestamp='2008-01-16'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -122,7 +122,6 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
   uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -250,16 +249,13 @@ case $basic_machine in
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
-       | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
+       | maxq | mb | microblaze | mcore | mep \
        | mips | mipsbe | mipseb | mipsel | mipsle \
        | mips16 \
        | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
        | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
        | mips64vr4100 | mips64vr4100el \
        | mips64vr4300 | mips64vr4300el \
        | mips64vr5000 | mips64vr5000el \
@@ -272,7 +268,6 @@ case $basic_machine in
        | mipsisa64sr71k | mipsisa64sr71kel \
        | mipstx39 | mipstx39el \
        | mn10200 | mn10300 \
-       | moxie \
        | mt \
        | msp430 \
        | nios | nios2 \
@@ -282,7 +277,7 @@ case $basic_machine in
        | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
        | pyramid \
        | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -291,7 +286,7 @@ case $basic_machine in
        | v850 | v850e \
        | we32k \
        | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-       | z8k | z80)
+       | z8k)
                basic_machine=$basic_machine-unknown
                ;;
        m6811 | m68hc11 | m6812 | m68hc12)
@@ -334,17 +329,14 @@ case $basic_machine in
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
-       | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* \
        | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
        | mips16-* \
        | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
        | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
        | mips64vr4100-* | mips64vr4100el-* \
        | mips64vr4300-* | mips64vr4300el-* \
        | mips64vr5000-* | mips64vr5000el-* \
@@ -366,20 +358,20 @@ case $basic_machine in
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
        | pyramid-* \
        | romp-* | rs6000-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
        | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
        | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
        | tron-* \
        | v850-* | v850e-* | vax-* \
        | we32k-* \
        | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
        | xstormy16-* | xtensa*-* \
        | ymp-* \
-       | z8k-* | z80-*)
+       | z8k-*)
                ;;
        # Recognize the basic CPU types without company name, with glob match.
        xtensa*)
@@ -447,10 +439,6 @@ case $basic_machine in
                basic_machine=m68k-apollo
                os=-bsd
                ;;
-       aros)
-               basic_machine=i386-pc
-               os=-aros
-               ;;
        aux)
                basic_machine=m68k-apple
                os=-aux
@@ -471,10 +459,6 @@ case $basic_machine in
                basic_machine=c90-cray
                os=-unicos
                ;;
-        cegcc)
-               basic_machine=arm-unknown
-               os=-cegcc
-               ;;
        convex-c1)
                basic_machine=c1-convex
                os=-bsd
@@ -542,10 +526,6 @@ case $basic_machine in
                basic_machine=m88k-motorola
                os=-sysv3
                ;;
-       dicos)
-               basic_machine=i686-pc
-               os=-dicos
-               ;;
        djgpp)
                basic_machine=i586-pc
                os=-msdosdjgpp
@@ -1148,10 +1128,6 @@ case $basic_machine in
                basic_machine=z8k-unknown
                os=-sim
                ;;
-       z80-*-coff)
-               basic_machine=z80-unknown
-               os=-sim
-               ;;
        none)
                basic_machine=none-none
                os=-none
@@ -1190,7 +1166,7 @@ case $basic_machine in
        we32k)
                basic_machine=we32k-att
                ;;
-       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
                basic_machine=sh-unknown
                ;;
        sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1262,9 +1238,8 @@ case $os in
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -kopensolaris* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* \
+             | -aos* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
              | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1273,7 +1248,7 @@ case $os in
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* | -cegcc* \
+             | -chorusos* | -chorusrdb* \
              | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
              | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
              | -uxpv* | -beos* | -mpeix* | -udk* \
@@ -1413,9 +1388,6 @@ case $os in
        -zvmoe)
                os=-zvmoe
                ;;
-       -dicos*)
-               os=-dicos
-               ;;
        -none)
                ;;
        *)
index 8347030..abe5dd3 100644 (file)
@@ -137,42 +137,6 @@ int GenerateSessionID(void)
 }
 
 
-/*
- * lingering_close() a`la Apache. see
- * http://www.apache.org/docs/misc/fin_wait_2.html for rationale
- */
-int lingering_close(int fd)
-{
-       char buf[SIZ];
-       int i;
-       fd_set set;
-       struct timeval tv, start;
-
-       gettimeofday(&start, NULL);
-       shutdown(fd, 1);
-       do {
-               do {
-                       gettimeofday(&tv, NULL);
-                       tv.tv_sec = SLEEPING - (tv.tv_sec - start.tv_sec);
-                       tv.tv_usec = start.tv_usec - tv.tv_usec;
-                       if (tv.tv_usec < 0) {
-                               tv.tv_sec--;
-                               tv.tv_usec += 1000000;
-                       }
-                       FD_ZERO(&set);
-                       FD_SET(fd, &set);
-                       i = select(fd + 1, &set, NULL, NULL, &tv);
-               } while (i == -1 && errno == EINTR);
-
-               if (i <= 0)
-                       break;
-
-               i = read(fd, buf, sizeof buf);
-       } while (i != 0 && (i != -1 || errno == EINTR));
-
-       return close(fd);
-}
-
 
 
 
@@ -211,72 +175,72 @@ int ReadHttpSubject(ParsedHttpHdrs *Hdr, StrBuf *Line, StrBuf *Buf)
        const char *Pos = NULL;
 
 
-       Hdr->ReqLine = Line;
+       Hdr->HR.ReqLine = Line;
        /* The requesttype... GET, POST... */
-       StrBufExtract_token(Buf, Hdr->ReqLine, 0, ' ');
+       StrBufExtract_token(Buf, Hdr->HR.ReqLine, 0, ' ');
        if (GetHash(HttpReqTypes, SKEY(Buf), &vLine) &&
            (vLine != NULL))
        {
-               Hdr->eReqType = *(long*)vLine;
+               Hdr->HR.eReqType = *(long*)vLine;
        }
        else {
-               Hdr->eReqType = eGET;
+               Hdr->HR.eReqType = eGET;
                return 1;
        }
-       StrBufCutLeft(Hdr->ReqLine, StrLength(Buf) + 1);
+       StrBufCutLeft(Hdr->HR.ReqLine, StrLength(Buf) + 1);
 
        /* the HTTP Version... */
-       StrBufExtract_token(Buf, Hdr->ReqLine, 1, ' ');
-       StrBufCutRight(Hdr->ReqLine, StrLength(Buf) + 1);
+       StrBufExtract_token(Buf, Hdr->HR.ReqLine, 1, ' ');
+       StrBufCutRight(Hdr->HR.ReqLine, StrLength(Buf) + 1);
        
        if (StrLength(Buf) == 0) {
-               Hdr->eReqType = eGET;
+               Hdr->HR.eReqType = eGET;
                return 1;
        }
 
-       Hdr->this_page = NewStrBufDup(Hdr->ReqLine);
+       Hdr->this_page = NewStrBufDup(Hdr->HR.ReqLine);
        /* chop Filename / query arguments */
-       Args = strchr(ChrPtr(Hdr->ReqLine), '?');
+       Args = strchr(ChrPtr(Hdr->HR.ReqLine), '?');
        if (Args == NULL) /* whe're not that picky about params... TODO: this will spoil '&' in filenames.*/
-               Args = strchr(ChrPtr(Hdr->ReqLine), '&');
+               Args = strchr(ChrPtr(Hdr->HR.ReqLine), '&');
        if (Args != NULL) {
                Args ++; /* skip the ? */
                Hdr->PlainArgs = NewStrBufPlain(
                        Args, 
-                       StrLength(Hdr->ReqLine) -
-                       (Args - ChrPtr(Hdr->ReqLine)));
-               StrBufCutAt(Hdr->ReqLine, 0, Args - 1);
+                       StrLength(Hdr->HR.ReqLine) -
+                       (Args - ChrPtr(Hdr->HR.ReqLine)));
+               StrBufCutAt(Hdr->HR.ReqLine, 0, Args - 1);
        } /* don't parse them yet, maybe we don't even care... */
        
        /* now lookup what we are going to do with this... */
        /* skip first slash */
-       StrBufExtract_NextToken(Buf, Hdr->ReqLine, &Pos, '/');
+       StrBufExtract_NextToken(Buf, Hdr->HR.ReqLine, &Pos, '/');
        do {
-               StrBufExtract_NextToken(Buf, Hdr->ReqLine, &Pos, '/');
+               StrBufExtract_NextToken(Buf, Hdr->HR.ReqLine, &Pos, '/');
 
                GetHash(HandlerHash, SKEY(Buf), &vHandler),
-               Hdr->Handler = (WebcitHandler*) vHandler;
-               if (Hdr->Handler == NULL)
+               Hdr->HR.Handler = (WebcitHandler*) vHandler;
+               if (Hdr->HR.Handler == NULL)
                        break;
                /*
                 * If the request is prefixed by "/webcit" then chop that off.  This
                 * allows a front end web server to forward all /webcit requests to us
                 * while still using the same web server port for other things.
                 */
-               if ((Hdr->Handler->Flags & URLNAMESPACE) != 0)
+               if ((Hdr->HR.Handler->Flags & URLNAMESPACE) != 0)
                        continue;
                break;
        } while (1);
        /* remove the handlername from the URL */
        if (Pos != NULL) {
-               StrBufCutLeft(Hdr->ReqLine, 
-                             Pos - ChrPtr(Hdr->ReqLine));
+               StrBufCutLeft(Hdr->HR.ReqLine, 
+                             Pos - ChrPtr(Hdr->HR.ReqLine));
        }
 
-       if (Hdr->Handler != NULL) {
-               if ((Hdr->Handler->Flags & BOGUS) != 0)
+       if (Hdr->HR.Handler != NULL) {
+               if ((Hdr->HR.Handler->Flags & BOGUS) != 0)
                        return 1;
-               Hdr->DontNeedAuth = (Hdr->Handler->Flags & ISSTATIC) != 0;
+               Hdr->HR.DontNeedAuth = (Hdr->HR.Handler->Flags & ISSTATIC) != 0;
        }
 
        Hdr->HTTPHeaders = NewHash(1, NULL);
@@ -323,13 +287,17 @@ int ReadHTTPRequset (ParsedHttpHdrs *Hdr)
                nLine ++;
                Line = NewStrBuf();
 
-               if (ClientGetLine(&Hdr->http_sock, Line, Hdr->ReadBuf, &Hdr->Pos) < 0) return 1;
+               if (ClientGetLine(Hdr, Line) < 0) return 1;
 
                if (StrLength(Line) == 0) {
                        FreeStrBuf(&Line);
                        continue;
                }
                if (nLine == 1) {
+                       pHdr = (OneHttpHeader*) malloc(sizeof(OneHttpHeader));
+                       memset(pHdr, 0, sizeof(OneHttpHeader));
+                       pHdr->Val = Line;
+                       Put(Hdr->HTTPHeaders, HKEY("GET /"), pHdr, DestroyHttpHeaderHandler);
                        lprintf(9, "%s\n", ChrPtr(Line));
                        isbogus = ReadHttpSubject(Hdr, Line, HeaderName);
                        if (isbogus) break;
@@ -397,9 +365,8 @@ int ReadHTTPRequset (ParsedHttpHdrs *Hdr)
  * function returns, the worker thread is then free to handle another
  * transaction.
  */
-void context_loop(int *sock)
+void context_loop(ParsedHttpHdrs *Hdr)
 {
-       ParsedHttpHdrs Hdr;
        int isbogus = 0;
        wcsession *TheSession, *sptr;
        struct timeval tx_start;
@@ -407,37 +374,34 @@ void context_loop(int *sock)
        
        gettimeofday(&tx_start, NULL);          /* start a stopwatch for performance timing */
 
-       memset(&Hdr, 0, sizeof(ParsedHttpHdrs));
-       Hdr.eReqType = eGET;
-       Hdr.http_sock = *sock;
        /*
         * Find out what it is that the web browser is asking for
         */
-       isbogus = ReadHTTPRequset(&Hdr);
+       isbogus = ReadHTTPRequset(Hdr);
 
        if (!isbogus)
-               isbogus = AnalyseHeaders(&Hdr);
+               isbogus = AnalyseHeaders(Hdr);
 
        if ((isbogus) ||
-           ((Hdr.Handler != NULL) &&
-            ((Hdr.Handler->Flags & BOGUS) != 0)))
+           ((Hdr->HR.Handler != NULL) &&
+            ((Hdr->HR.Handler->Flags & BOGUS) != 0)))
        {
                wcsession *Bogus;
                Bogus = (wcsession *)
                        malloc(sizeof(wcsession));
                memset(Bogus, 0, sizeof(wcsession));
                pthread_setspecific(MyConKey, (void *)Bogus);
-               Bogus->Hdr = &Hdr;
+               Bogus->Hdr = Hdr;
                session_new_modules(Bogus);
                do_404();
                session_detach_modules(Bogus);
-               http_destroy_modules(&Hdr);
+               http_destroy_modules(Hdr);
                session_destroy_modules(&Bogus);
                return;
        }
 
-       if ((Hdr.Handler != NULL) && 
-           ((Hdr.Handler->Flags & ISSTATIC) != 0))
+       if ((Hdr->HR.Handler != NULL) && 
+           ((Hdr->HR.Handler->Flags & ISSTATIC) != 0))
        {
                wcsession *Static;
 
@@ -445,31 +409,31 @@ void context_loop(int *sock)
                        malloc(sizeof(wcsession));
                memset(Static, 0, sizeof(wcsession));
                pthread_setspecific(MyConKey, (void *)Static);
-               Static->Hdr = &Hdr;
+               Static->Hdr = Hdr;
                Static->serv_sock = (-1);
                Static->chat_sock = (-1);
                Static->is_mobile = -1;
                session_new_modules(Static);
                
-               Hdr.Handler->F();
+               Hdr->HR.Handler->F();
 
                /* How long did this transaction take? */
                gettimeofday(&tx_finish, NULL);
                
                lprintf(9, "SL: Transaction [%s] completed in %ld.%06ld seconds.\n",
-                       ChrPtr(Hdr.this_page),
+                       ChrPtr(Hdr->this_page),
                        ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000,
                        ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000
                        );
 
                session_detach_modules(Static);
-               http_destroy_modules(&Hdr);
+               http_destroy_modules(Hdr);
                session_destroy_modules(&Static);
                return;
        }
 
-       if (Hdr.got_auth == AUTH_BASIC) 
-               CheckAuthBasic(&Hdr);
+       if (Hdr->HR.got_auth == AUTH_BASIC) 
+               CheckAuthBasic(Hdr);
 
 /*
 TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
@@ -505,20 +469,20 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
                      sptr = sptr->next) {
 
                        /** If HTTP-AUTH, look for a session with matching credentials */
-                       switch (Hdr.got_auth)
+                       switch (Hdr->HR.got_auth)
                        {
                        case AUTH_BASIC:
-                               if ( (Hdr.SessionKey != sptr->SessionKey))
+                               if ( (Hdr->HR.SessionKey != sptr->SessionKey))
                                        continue;
-                               GetAuthBasic(&Hdr);
-                               if ((!strcasecmp(ChrPtr(Hdr.c_username), ChrPtr(sptr->wc_username))) &&
-                                   (!strcasecmp(ChrPtr(Hdr.c_password), ChrPtr(sptr->wc_password))) ) 
+                               GetAuthBasic(Hdr);
+                               if ((!strcasecmp(ChrPtr(Hdr->c_username), ChrPtr(sptr->wc_username))) &&
+                                   (!strcasecmp(ChrPtr(Hdr->c_password), ChrPtr(sptr->wc_password))) ) 
                                        TheSession = sptr;
                                break;
                        case AUTH_COOKIE:
                        /** If cookie-session, look for a session with matching session ID */
-                               if ( (Hdr.desired_session != 0) && 
-                                    (sptr->wc_session == Hdr.desired_session)) 
+                               if ( (Hdr->HR.desired_session != 0) && 
+                                    (sptr->wc_session == Hdr->HR.desired_session)) 
                                        TheSession = sptr;
                                break;                       
                        case NO_AUTH:
@@ -536,8 +500,8 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
                TheSession = (wcsession *)
                        malloc(sizeof(wcsession));
                memset(TheSession, 0, sizeof(wcsession));
-               TheSession->Hdr = &Hdr;
-               TheSession->SessionKey = Hdr.SessionKey;
+               TheSession->Hdr = Hdr;
+               TheSession->SessionKey = Hdr->HR.SessionKey;
                TheSession->serv_sock = (-1);
                TheSession->chat_sock = (-1);
        
@@ -547,11 +511,11 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
                 * doesn't, and that's a Bad Thing because it causes lots of spurious sessions
                 * to get created.
                 */     
-               if (Hdr.desired_session == 0) {
+               if (Hdr->HR.desired_session == 0) {
                        TheSession->wc_session = GenerateSessionID();
                }
                else {
-                       TheSession->wc_session = Hdr.desired_session;
+                       TheSession->wc_session = Hdr->HR.desired_session;
                }
 
                pthread_setspecific(MyConKey, (void *)TheSession);
@@ -565,9 +529,9 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
                SessionList = TheSession;
                pthread_mutex_unlock(&SessionListMutex);
 
-               if (StrLength(Hdr.c_language) > 0) {
-                       lprintf(9, "Session cookie requests language '%s'\n", ChrPtr(Hdr.c_language));
-                       set_selected_language(ChrPtr(Hdr.c_language));
+               if (StrLength(Hdr->c_language) > 0) {
+                       lprintf(9, "Session cookie requests language '%s'\n", ChrPtr(Hdr->c_language));
+                       set_selected_language(ChrPtr(Hdr->c_language));
                        go_selected_language();
                }
        }
@@ -584,7 +548,7 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
        pthread_setspecific(MyConKey, (void *)TheSession);
        
        TheSession->lastreq = time(NULL);                       /* log */
-       TheSession->Hdr = &Hdr;
+       TheSession->Hdr = Hdr;
 
        session_attach_modules(TheSession);
        session_loop();                         /* do transaction */
@@ -594,7 +558,7 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
        gettimeofday(&tx_finish, NULL);
        
        lprintf(9, "Transaction [%s] completed in %ld.%06ld seconds.\n",
-               ChrPtr(Hdr.this_page),
+               ChrPtr(Hdr->this_page),
                ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) / 1000000,
                ((tx_finish.tv_sec*1000000 + tx_finish.tv_usec) - (tx_start.tv_sec*1000000 + tx_start.tv_usec)) % 1000000
        );
@@ -604,7 +568,7 @@ TODO    HKEY("/static/nocookies.html?force_close_session=yes"));
        TheSession->Hdr = NULL;
        pthread_mutex_unlock(&TheSession->SessionMutex);        /* unbind */
 
-       http_destroy_modules(&Hdr);
+       http_destroy_modules(Hdr);
 }
 
 void tmplput_nonce(StrBuf *Target, WCTemplputParams *TP)
@@ -626,17 +590,17 @@ void tmplput_current_room(StrBuf *Target, WCTemplputParams *TP)
 
 void Header_HandleContentLength(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       hdr->ContentLength = StrToi(Line);
+       hdr->HR.ContentLength = StrToi(Line);
 }
 
 void Header_HandleContentType(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       hdr->ContentType = Line;
+       hdr->HR.ContentType = Line;
 }
 
 void Header_HandleUserAgent(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       hdr->user_agent = Line;
+       hdr->HR.user_agent = Line;
 #ifdef TECH_PREVIEW
 /* TODO: do this later on session creating
        if ((WCC->is_mobile < 0) && is_mobile_ua(&buf[12])) {                   
@@ -652,32 +616,32 @@ void Header_HandleUserAgent(StrBuf *Line, ParsedHttpHdrs *hdr)
 
 void Header_HandleHost(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       if ((follow_xff) && (hdr->http_host != NULL))
+       if ((follow_xff) && (hdr->HR.http_host != NULL))
                return;
        else
-               hdr->http_host = Line;
+               hdr->HR.http_host = Line;
 }
 
 void Header_HandleXFFHost(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
        if (follow_xff)
-               hdr->http_host = Line;
+               hdr->HR.http_host = Line;
 }
 
 
 void Header_HandleXFF(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       hdr->browser_host = Line;
+       hdr->HR.browser_host = Line;
 
-       while (StrBufNum_tokens(hdr->browser_host, ',') > 1) {
-               StrBufRemove_token(hdr->browser_host, 0, ',');
+       while (StrBufNum_tokens(hdr->HR.browser_host, ',') > 1) {
+               StrBufRemove_token(hdr->HR.browser_host, 0, ',');
        }
-       StrBufTrim(hdr->browser_host);
+       StrBufTrim(hdr->HR.browser_host);
 }
 
 void Header_HandleIfModSince(StrBuf *Line, ParsedHttpHdrs *hdr)
 {
-       hdr->if_modified_since = httpdate_to_timestamp(Line);
+       hdr->HR.if_modified_since = httpdate_to_timestamp(Line);
 }
 
 void Header_HandleAcceptEncoding(StrBuf *Line, ParsedHttpHdrs *hdr)
@@ -686,7 +650,7 @@ void Header_HandleAcceptEncoding(StrBuf *Line, ParsedHttpHdrs *hdr)
         * Can we compress?
         */
        if (strstr(&ChrPtr(Line)[16], "gzip")) {
-               hdr->gzip_ok = 1;
+               hdr->HR.gzip_ok = 1;
        }
 }
 const char *ReqStrs[eNONE] = {
@@ -800,7 +764,6 @@ void
 HttpDestroyModule_CONTEXT
 (ParsedHttpHdrs *httpreq)
 {
-       FreeStrBuf(&httpreq->ReqLine);
        FreeStrBuf(&httpreq->ReadBuf);
        FreeStrBuf(&httpreq->PlainArgs);
        FreeStrBuf(&httpreq->this_page);
index b5c04c2..ba8d03a 100644 (file)
@@ -249,7 +249,7 @@ void download_file(void)
        int force_download = 1;
        
        Buf = NewStrBuf();
-       StrBufExtract_token(Buf, WCC->Hdr->ReqLine, 0, '/');
+       StrBufExtract_token(Buf, WCC->Hdr->HR.ReqLine, 0, '/');
        StrBufUnescape(Buf, 1);
        serv_printf("OPEN %s", ChrPtr(Buf));
        StrBuf_ServGetln(Buf);
index 2e33e26..c31b40b 100644 (file)
@@ -101,10 +101,10 @@ void groupdav_main(HashList *HTTPHeaders,
        strcpy(dav_ifmatch, "");
        dav_depth = 0;
 
-       if ((StrLength(WCC->Hdr->http_host) == 0) &&
+       if ((StrLength(WCC->Hdr->HR.http_host) == 0) &&
            GetHash(HTTPHeaders, HKEY("HOST"), &vLine) && 
            (vLine != NULL)) {
-               WCC->Hdr->http_host = (StrBuf*)vLine;
+               WCC->Hdr->HR.http_host = (StrBuf*)vLine;
        }
        if (GetHash(HTTPHeaders, HKEY("IF-MATCH"), &vLine) && 
            (vLine != NULL)) {
@@ -163,7 +163,7 @@ void groupdav_main(HashList *HTTPHeaders,
                }
        }
 
-       switch (WCC->Hdr->eReqType)
+       switch (WCC->Hdr->HR.eReqType)
        {
        /*
         * The OPTIONS method is not required by GroupDAV.  This is an
@@ -216,7 +216,7 @@ void groupdav_main(HashList *HTTPHeaders,
                groupdav_common_headers();
                hprintf("Content-Type: text/plain\r\n");
                wprintf("GroupDAV method \"%s\" is not implemented.\r\n",
-                       ReqStrs[WCC->Hdr->eReqType]);
+                       ReqStrs[WCC->Hdr->HR.eReqType]);
                end_burst();
        }
 }
@@ -228,10 +228,10 @@ void groupdav_main(HashList *HTTPHeaders,
 void groupdav_identify_host(void) {
        wcsession *WCC = WC;
 
-       if (StrLength(WCC->Hdr->http_host)!=0) {
+       if (StrLength(WCC->Hdr->HR.http_host)!=0) {
                wprintf("%s://%s",
                        (is_https ? "https" : "http"),
-                       ChrPtr(WCC->Hdr->http_host));
+                       ChrPtr(WCC->Hdr->HR.http_host));
        }
 }
 
index 0f4af8c..260a8f4 100644 (file)
@@ -61,7 +61,7 @@ void do_listsub(void)
                        email,
                        subtype,
                        (is_https ? "https" : "http"),
-                           ChrPtr(WC->Hdr->http_host)
+                           ChrPtr(WC->Hdr->HR.http_host)
                );
                serv_getln(buf, sizeof buf);
                if (buf[0] == '2') {
@@ -102,7 +102,7 @@ void do_listsub(void)
                            room,
                            email,
                            (is_https ? "https" : "http"),
-                           ChrPtr(WC->Hdr->http_host)
+                           ChrPtr(WC->Hdr->HR.http_host)
                );
                serv_getln(buf, sizeof buf);
                if (buf[0] == '2') {
index ab3d2f3..6fcc549 100644 (file)
@@ -62,7 +62,7 @@ void display_generic(void)
        wprintf("<br /><textarea name=\"g_input\" rows=10 cols=80 width=80></textarea><br />\n");
 
        wprintf("<font size=-2>");
-       wprintf(_("Detected host header is %s://%s"), (is_https ? "https" : "http"), ChrPtr(WC->Hdr->http_host));
+       wprintf(_("Detected host header is %s://%s"), (is_https ? "https" : "http"), ChrPtr(WC->Hdr->HR.http_host));
        wprintf("</font>\n");
        wprintf("<input type=\"submit\" name=\"sc_button\" value=\"%s\">", _("Send command"));
        wprintf("&nbsp;");
index 70b2a79..a3bca06 100644 (file)
@@ -367,16 +367,16 @@ void handle_one_message(void)
        const char *pMsg;
 
 
-       pMsg = strchr(ChrPtr(WCC->Hdr->ReqLine), '/');
+       pMsg = strchr(ChrPtr(WCC->Hdr->HR.ReqLine), '/');
        if (pMsg == NULL) {
                HttpStatus(CitStatus);
                return;
        }
 
        msgnum = atol(pMsg + 1);
-       StrBufCutAt(WCC->Hdr->ReqLine, 0, pMsg);
-       gotoroom(WCC->Hdr->ReqLine);
-       switch (WCC->Hdr->eReqType)
+       StrBufCutAt(WCC->Hdr->HR.ReqLine, 0, pMsg);
+       gotoroom(WCC->Hdr->HR.ReqLine);
+       switch (WCC->Hdr->HR.eReqType)
        {
        case eGET:
        case ePOST:
@@ -435,8 +435,8 @@ void embed_message(void) {
        const StrBuf *Tmpl;
        StrBuf *CmdBuf = NULL;
 
-       msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 0, '/');
-       switch (WCC->Hdr->eReqType)
+       msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
+       switch (WCC->Hdr->HR.eReqType)
        {
        case eGET:
        case ePOST:
@@ -475,7 +475,7 @@ void print_message(void) {
        long msgnum = 0L;
        const StrBuf *Mime;
 
-       msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 0, '/');
+       msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/');
        output_headers(0, 0, 0, 0, 0, 0);
 
        hprintf("Content-type: text/html\r\n"
@@ -499,7 +499,7 @@ void mobile_message_view(void)
        long msgnum = 0L;
        const StrBuf *Mime;
   
-       msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 0, '/');
+       msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/');
        output_headers(1, 0, 0, 0, 0, 1);
        begin_burst();
        do_template("msgcontrols", NULL);
@@ -516,7 +516,7 @@ void display_headers(void) {
        long msgnum = 0L;
        char buf[1024];
 
-       msgnum = StrBufExtract_long(WC->Hdr->ReqLine, 0, '/');
+       msgnum = StrBufExtract_long(WC->Hdr->HR.ReqLine, 0, '/');
        output_headers(0, 0, 0, 0, 0, 0);
 
        hprintf("Content-type: text/plain\r\n"
@@ -1747,8 +1747,8 @@ void mimepart(int force_download)
        StrBuf *ContentType = NewStrBufPlain(HKEY("application/octet-stream"));
        const char *CT;
 
-       msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 0, '/');
-       att = StrBufExtract_long(WCC->Hdr->ReqLine, 1, '/');
+       msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
+       att = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 1, '/');
 
        Buf = NewStrBuf();
        serv_printf("OPNA %ld|%ld", msgnum, att);
@@ -1767,7 +1767,7 @@ void mimepart(int force_download)
 
                if (!force_download) {
                        if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
-                               StrBufExtract_token(Buf, WCC->Hdr->ReqLine, 2, '/');
+                               StrBufExtract_token(Buf, WCC->Hdr->HR.ReqLine, 2, '/');
                                CT = GuessMimeByFilename(SKEY(Buf));
                        }
                        if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
@@ -1854,8 +1854,8 @@ void view_postpart(void) {
        StrBuf *filename = NewStrBuf();
        StrBuf *partnum = NewStrBuf();
 
-       StrBufExtract_token(partnum, WC->Hdr->ReqLine, 0, '/');
-       StrBufExtract_token(filename, WC->Hdr->ReqLine, 1, '/');
+       StrBufExtract_token(partnum, WC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(filename, WC->Hdr->HR.ReqLine, 1, '/');
 
        postpart(partnum, filename, 0);
 
@@ -1867,8 +1867,8 @@ void download_postpart(void) {
        StrBuf *filename = NewStrBuf();
        StrBuf *partnum = NewStrBuf();
 
-       StrBufExtract_token(partnum, WC->Hdr->ReqLine, 0, '/');
-       StrBufExtract_token(filename, WC->Hdr->ReqLine, 1, '/');
+       StrBufExtract_token(partnum, WC->Hdr->HR.ReqLine, 0, '/');
+       StrBufExtract_token(filename, WC->Hdr->HR.ReqLine, 1, '/');
 
        postpart(partnum, filename, 1);
 
index 4385f70..75ced99 100644 (file)
@@ -75,8 +75,8 @@ void openid_attach(void) {
                snprintf(buf, sizeof buf,
                         "OIDS %s|%s://%s/finalize_openid_login|%s://%s",
                         bstr("openid_url"),
-                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host),
-                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host)
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host),
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host)
                );
 
                serv_puts(buf);
index a1a80be..613c2cf 100644 (file)
@@ -400,16 +400,16 @@ void tmplput_url_part(StrBuf *Target, WCTemplputParams *TP)
        
        if (WCC != NULL) {
                if (TP->Tokens->Params[0]->lvalue == 0) {
-                       if (WCC->Hdr->Handler != NULL)
-                               UrlBuf = Name = WCC->Hdr->Handler->Name;
+                       if (WCC->Hdr->HR.Handler != NULL)
+                               UrlBuf = Name = WCC->Hdr->HR.Handler->Name;
                }
                else if (TP->Tokens->Params[0]->lvalue == 1) {
                        UrlBuf = NewStrBuf();
-                       StrBufExtract_token(UrlBuf, WCC->Hdr->ReqLine, 0, '/');
+                       StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 0, '/');
                }
                else {
                        UrlBuf = NewStrBuf();
-                       StrBufExtract_token(UrlBuf, WCC->Hdr->ReqLine, 1, '/');
+                       StrBufExtract_token(UrlBuf, WCC->Hdr->HR.ReqLine, 1, '/');
                }
 
                if (UrlBuf == NULL)  {
index 256e3c5..e85c3c6 100644 (file)
@@ -1819,7 +1819,7 @@ void display_editroom(void)
                wprintf(_("The URL for subscribe/unsubscribe is: "));
                wprintf("<TT>%s://%s/listsub</TT></td></tr>\n",
                        (is_https ? "https" : "http"),
-                       ChrPtr(WC->Hdr->http_host));
+                       ChrPtr(WC->Hdr->HR.http_host));
                /* Public posting? */
                wprintf("<tr><td>");
                wprintf(_("Allow non-subscribers to mail to this room."));
@@ -3313,7 +3313,7 @@ void set_floordiv_expanded(void) {
        StrBuf *FloorDiv;
        
        FloorDiv = NewStrBuf();
-       StrBufExtract_token(FloorDiv, WCC->Hdr->ReqLine, 0, '/');
+       StrBufExtract_token(FloorDiv, WCC->Hdr->HR.ReqLine, 0, '/');
        set_preference("floordiv_expanded", FloorDiv, 1);
        WCC->floordiv_expanded = FloorDiv;
 }
index 7564048..08d90cd 100644 (file)
@@ -96,7 +96,7 @@ void display_rss(void)
                #endif
        }
 
-       if (gotoroom(WCC->Hdr->ReqLine)) {
+       if (gotoroom(WCC->Hdr->HR.ReqLine)) {
                lprintf(3, "RSS: Can't goto requested room\n");
                hprintf("HTTP/1.1 404 Not Found\r\n");
                hprintf("Content-Type: text/html\r\n");
@@ -155,7 +155,7 @@ void display_rss(void)
        hprintf("Content-Type: application/rss+xml\r\n");
        hprintf("Server: %s\r\n", PACKAGE_STRING);
        hprintf("Connection: close\r\n");
-       if (WCC->Hdr->eReqType == eHEAD)
+       if (WCC->Hdr->HR.eReqType == eHEAD)
                return;
 
        /* <?xml.. etc confuses our subst parser, so do it here */
@@ -164,7 +164,7 @@ void display_rss(void)
        SVPutBuf("ROOM", WCC->wc_roomname, 1);
        SVPutBuf("NODE", WCC->serv_info->serv_humannode, 1);
        /* TODO:  Fix me */
-       svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->http_host));
+       svprintf(HKEY("ROOM_LINK"), WCS_STRING, "%s://%s/", (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host));
        
        /** Get room info for description */
        serv_puts("RINF");
index 221aa84..ed53165 100644 (file)
@@ -168,16 +168,16 @@ int GetConnected (void)
                 * unless we are following X-Forwarded-For: headers
                 * and such a header has already turned up something.
                 */
-               if ( (!follow_xff) || (StrLength(WCC->Hdr->browser_host) == 0) ) {
-                       if (WCC->Hdr->browser_host == NULL) {
-                               WCC->Hdr->browser_host = NewStrBuf();
+               if ( (!follow_xff) || (StrLength(WCC->Hdr->HR.browser_host) == 0) ) {
+                       if (WCC->Hdr->HR.browser_host == NULL) {
+                               WCC->Hdr->HR.browser_host = NewStrBuf();
                                Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), 
-                                   WCC->Hdr->browser_host, HFreeStrBuf);
+                                   WCC->Hdr->HR.browser_host, HFreeStrBuf);
                        }
-                       locate_host(WCC->Hdr->browser_host, WCC->Hdr->http_sock);
+                       locate_host(WCC->Hdr->HR.browser_host, WCC->Hdr->http_sock);
                }
                if (WCC->serv_info == NULL)
-                       WCC->serv_info = get_serv_info(WCC->Hdr->browser_host, WCC->Hdr->user_agent);
+                       WCC->serv_info = get_serv_info(WCC->Hdr->HR.browser_host, WCC->Hdr->HR.user_agent);
                if (WCC->serv_info == NULL){
                        begin_burst();
                        wprintf(_("Received unexpected answer from Citadel "
index e432d53..ea308fc 100644 (file)
@@ -184,7 +184,7 @@ void output_flat_static(void)
        void *vFile;
        StrBuf *File;
 
-       if (GetHash(StaticFilemappings[0], SKEY(WCC->Hdr->Handler->Name), &vFile) &&
+       if (GetHash(StaticFilemappings[0], SKEY(WCC->Hdr->HR.Handler->Name), &vFile) &&
            (vFile != NULL))
        {
                File = (StrBuf*) vFile;
@@ -200,7 +200,7 @@ void output_static_safe(HashList *DirList)
        void *vFile;
        StrBuf *File;
 
-       if (GetHash(DirList, SKEY(WCC->Hdr->ReqLine), &vFile) &&
+       if (GetHash(DirList, SKEY(WCC->Hdr->HR.ReqLine), &vFile) &&
            (vFile != NULL))
        {
                File = (StrBuf*) vFile;
index 27fba51..058f7c8 100644 (file)
@@ -321,7 +321,7 @@ void serv_printf(const char *format,...)
 
 
 
-int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
+int ClientGetLine(ParsedHttpHdrs *Hdr, StrBuf *Target)
 {
        const char *Error, *pch, *pchs;
        int rlen, len, retval = 0;
@@ -329,28 +329,28 @@ int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
 #ifdef HAVE_OPENSSL
        if (is_https) {
                int ntries = 0;
-               if (StrLength(CLineBuf) > 0) {
-                       pchs = ChrPtr(CLineBuf);
+               if (StrLength(Hdr->ReadBuf) > 0) {
+                       pchs = ChrPtr(Hdr->ReadBuf);
                        pch = strchr(pchs, '\n');
                        if (pch != NULL) {
                                rlen = 0;
                                len = pch - pchs;
                                if (len > 0 && (*(pch - 1) == '\r') )
                                        rlen ++;
-                               StrBufSub(Target, CLineBuf, 0, len - rlen);
-                               StrBufCutLeft(CLineBuf, len + 1);
+                               StrBufSub(Target, Hdr->ReadBuf, 0, len - rlen);
+                               StrBufCutLeft(Hdr->ReadBuf, len + 1);
                                return len - rlen;
                        }
                }
 
                while (retval == 0) { 
                                pch = NULL;
-                               pchs = ChrPtr(CLineBuf);
+                               pchs = ChrPtr(Hdr->ReadBuf);
                                if (*pchs != '\0')
                                        pch = strchr(pchs, '\n');
                                if (pch == NULL) {
-                                       retval = client_read_sslbuffer(CLineBuf, SLEEPING);
-                                       pchs = ChrPtr(CLineBuf);
+                                       retval = client_read_sslbuffer(Hdr->ReadBuf, SLEEPING);
+                                       pchs = ChrPtr(Hdr->ReadBuf);
                                        pch = strchr(pchs, '\n');
                                }
                                if (retval == 0) {
@@ -365,8 +365,8 @@ int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
                        len = pch - pchs;
                        if (len > 0 && (*(pch - 1) == '\r') )
                                rlen ++;
-                       StrBufSub(Target, CLineBuf, 0, len - rlen);
-                       StrBufCutLeft(CLineBuf, len + 1);
+                       StrBufSub(Target, Hdr->ReadBuf, 0, len - rlen);
+                       StrBufCutLeft(Hdr->ReadBuf, len + 1);
                        return len - rlen;
 
                }
@@ -376,9 +376,9 @@ int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos)
        else 
 #endif
                return StrBufTCP_read_buffered_line_fast(Target, 
-                                                        CLineBuf,
-                                                        Pos,
-                                                        sock,
+                                                        Hdr->ReadBuf,
+                                                        &Hdr->Pos,
+                                                        &Hdr->http_sock,
                                                         5,
                                                         1,
                                                         &Error);
@@ -509,23 +509,23 @@ int ig_uds_server(char *sockpath, int queue_len)
  *      0       Request timed out.
  *     -1      Connection is broken, or other error.
  */
-int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int bytes, int timeout)
+int client_read_to(ParsedHttpHdrs *Hdr, StrBuf *Target, int bytes, int timeout)
 {
        const char *Error;
        int retval = 0;
 
 #ifdef HAVE_OPENSSL
        if (is_https) {
-               long bufremain = StrLength(Buf) - (*Pos - ChrPtr(Buf));
-               StrBufAppendBufPlain(Target, *Pos, bufremain, 0);
-               *Pos = NULL;
-               FlushStrBuf(Buf);
+               long bufremain = StrLength(Hdr->ReadBuf) - (Hdr->Pos - ChrPtr(Hdr->ReadBuf));
+               StrBufAppendBufPlain(Target, Hdr->Pos, bufremain, 0);
+               Hdr->Pos = NULL;
+               FlushStrBuf(Hdr->ReadBuf);
 
-               while ((StrLength(Buf) + StrLength(Target) < bytes) &&
+               while ((StrLength(Hdr->ReadBuf) + StrLength(Target) < bytes) &&
                       (retval >= 0))
-                       retval = client_read_sslbuffer(Buf, timeout);
+                       retval = client_read_sslbuffer(Hdr->ReadBuf, timeout);
                if (retval >= 0) {
-                       StrBufAppendBuf(Target, Buf, 0); /* todo: Buf > bytes? */
+                       StrBufAppendBuf(Target, Hdr->ReadBuf, 0); /* todo: Buf > bytes? */
 #ifdef HTTP_TRACING
                        write(2, "\033[32m", 5);
                        write(2, buf, bytes);
@@ -541,8 +541,9 @@ int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int
 #endif
 
        retval = StrBufReadBLOBBuffered(Target, 
-                                       Buf, Pos, 
-                                       sock, 
+                                       Hdr->ReadBuf, 
+                                       &Hdr->Pos, 
+                                       &Hdr->http_sock, 
                                        1, 
                                        bytes,
                                        O_TERM,
@@ -585,7 +586,7 @@ long end_burst(void)
         fd_set wset;
         int fdflags;
 
-       if (!DisableGzip && (WCC->Hdr->gzip_ok) && CompressBuffer(WCC->WBuf))
+       if (!DisableGzip && (WCC->Hdr->HR.gzip_ok) && CompressBuffer(WCC->WBuf))
        {
                hprintf("Content-encoding: gzip\r\n");
        }
@@ -670,6 +671,42 @@ long end_burst(void)
 }
 
 
+/*
+ * lingering_close() a`la Apache. see
+ * http://www.apache.org/docs/misc/fin_wait_2.html for rationale
+ */
+int lingering_close(int fd)
+{
+       char buf[SIZ];
+       int i;
+       fd_set set;
+       struct timeval tv, start;
+
+       gettimeofday(&start, NULL);
+       shutdown(fd, 1);
+       do {
+               do {
+                       gettimeofday(&tv, NULL);
+                       tv.tv_sec = SLEEPING - (tv.tv_sec - start.tv_sec);
+                       tv.tv_usec = start.tv_usec - tv.tv_usec;
+                       if (tv.tv_usec < 0) {
+                               tv.tv_sec--;
+                               tv.tv_usec += 1000000;
+                       }
+                       FD_ZERO(&set);
+                       FD_SET(fd, &set);
+                       i = select(fd + 1, &set, NULL, NULL, &tv);
+               } while (i == -1 && errno == EINTR);
+
+               if (i <= 0)
+                       break;
+
+               i = read(fd, buf, sizeof buf);
+       } while (i != 0 && (i != -1 || errno == EINTR));
+
+       return close(fd);
+}
+
 
 void
 SessionNewModule_TCPSOCKETS
index a0c1795..6b8e9c8 100644 (file)
@@ -1219,7 +1219,7 @@ void display_vcard_photo_img(void)
        const char *contentType;
        wcsession *WCC = WC;
 
-       msgnum = StrBufExtract_long(WCC->Hdr->ReqLine, 0, '/');
+       msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
        
        vcard = load_mimepart(msgnum,"1");
        v = VCardLoad(vcard);
index 680003e..a04d78c 100644 (file)
@@ -511,8 +511,8 @@ void ReadPostData(void)
        StrBufPrintf(content, 
                     "Content-type: %s\n"
                     "Content-length: %ld\n\n",
-                    ChrPtr(WCC->Hdr->ContentType), 
-                            WCC->Hdr->ContentLength);
+                    ChrPtr(WCC->Hdr->HR.ContentType), 
+                            WCC->Hdr->HR.ContentLength);
 /*
   hprintf("Content-type: %s\n"
   "Content-length: %d\n\n",
@@ -521,18 +521,16 @@ void ReadPostData(void)
        body_start = StrLength(content);
 
        /** Read the entire input data at once. */
-       client_read_to(&WCC->Hdr->http_sock, 
-                      content, 
-                      WCC->Hdr->ReadBuf, &WCC->Hdr->Pos,
-                      WCC->Hdr->ContentLength,
+       client_read_to(WCC->Hdr, content, 
+                      WCC->Hdr->HR.ContentLength,
                       SLEEPING);
        
-       if (!strncasecmp(ChrPtr(WCC->Hdr->ContentType), "application/x-www-form-urlencoded", 33)) {
+       if (!strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "application/x-www-form-urlencoded", 33)) {
                StrBufCutLeft(content, body_start);
                ParseURLParams(content);
-       } else if (!strncasecmp(ChrPtr(WCC->Hdr->ContentType), "multipart", 9)) {
+       } else if (!strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "multipart", 9)) {
                content_end = ChrPtr(content) + 
-                       WCC->Hdr->ContentLength + 
+                       WCC->Hdr->HR.ContentLength + 
                        body_start;
                mime_parser(ChrPtr(content), content_end, *upload_handler, NULL, NULL, NULL, 0);
        }
@@ -567,10 +565,10 @@ void session_loop(void)
        WCC->is_mobile = 0;
        WCC->trailing_javascript = NewStrBuf();
        WCC->Hdr->nWildfireHeaders = 0;
-       if (WCC->Hdr->Handler != NULL)
-               Flags = WCC->Hdr->Handler->Flags; /* so we can temporarily add our own... */
+       if (WCC->Hdr->HR.Handler != NULL)
+               Flags = WCC->Hdr->HR.Handler->Flags; /* so we can temporarily add our own... */
 
-       if (WCC->Hdr->ContentLength > 0) {
+       if (WCC->Hdr->HR.ContentLength > 0) {
                ReadPostData();
        }
 
@@ -628,9 +626,9 @@ void session_loop(void)
                }
        }
 
-       xhttp = (WCC->Hdr->eReqType != eGET) &&
-               (WCC->Hdr->eReqType != ePOST) &&
-               (WCC->Hdr->eReqType != eHEAD);
+       xhttp = (WCC->Hdr->HR.eReqType != eGET) &&
+               (WCC->Hdr->HR.eReqType != ePOST) &&
+               (WCC->Hdr->HR.eReqType != eHEAD);
 
        /*
         * If a 'gotofirst' parameter has been specified, attempt to goto that room
@@ -650,11 +648,12 @@ void session_loop(void)
         * supposed to be, and 'gotofirst' was not specified, then go there.
         */
        else if ( (StrLength(WCC->wc_roomname) == 0) && ( (StrLength(WCC->Hdr->c_roomname) > 0) )) {
+               int ret;
+
                lprintf(9, "We are in '%s' but cookie indicates '%s', going there...\n",
                        ChrPtr(WCC->wc_roomname),
                        ChrPtr(WCC->Hdr->c_roomname)
                );
-               int ret;
                ret = gotoroom(WCC->Hdr->c_roomname);   /* do quietly to avoid session output! */
                if ((ret/100) != 2) {
                        lprintf(1, "COOKIEGOTO: Unable to change to [%s]; Reason: %d\n",
@@ -662,15 +661,15 @@ void session_loop(void)
                }
        }
 
-       if (WCC->Hdr->Handler != NULL) {
-               if (!WCC->logged_in && ((WCC->Hdr->Handler->Flags & ANONYMOUS) == 0)) {
+       if (WCC->Hdr->HR.Handler != NULL) {
+               if (!WCC->logged_in && ((WCC->Hdr->HR.Handler->Flags & ANONYMOUS) == 0)) {
                        display_login(NULL);
                }
                else {
-                       if ((WCC->Hdr->Handler->Flags & AJAX) != 0)
+                       if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0)
                                begin_ajax_response();
-                       WCC->Hdr->Handler->F();
-                       if ((WCC->Hdr->Handler->Flags & AJAX) != 0)
+                       WCC->Hdr->HR.Handler->F();
+                       if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0)
                                end_ajax_response();
                }
        }
@@ -685,7 +684,6 @@ void session_loop(void)
 SKIP_ALL_THIS_CRAP:
        FreeStrBuf(&Buf);
        fflush(stdout);
-       WCC->Hdr->http_host = NULL;
 }
 
 
index 7cbc14e..8604155 100644 (file)
@@ -402,42 +402,51 @@ const char *ReqStrs[eNONE];
 #define AUTH_COOKIE 1
 #define AUTH_BASIC 2
 
-typedef struct _ParsedHttpHdrs {
-       int http_sock;                          /**< HTTP server socket */
-       const char *Pos;
-       StrBuf *ReadBuf;
 
+
+typedef struct _HdrRefs {
        long eReqType;                          /**< eGET, ePOST.... */
-       const WebcitHandler *Handler;
-       
-       int DontNeedAuth;
-       int got_auth;
+       int desired_session;
        int SessionKey;
+
+       int got_auth;
+       int DontNeedAuth;
        long ContentLength;
        time_t if_modified_since;
        int gzip_ok;                            /**< Nonzero if Accept-encoding: gzip */
 
-       StrBuf *c_username;
-       StrBuf *c_password;
-       StrBuf *c_roomname;
-       StrBuf *c_language;
-       StrBuf *RawCookie;
-       int desired_session;
-
+       /* these are references into Hdr->HTTPHeaders, so we don't need to free them. */
        StrBuf *ContentType;
-
-       StrBuf *RawLine;/* TODO: freeme */
+       StrBuf *RawCookie;
        StrBuf *ReqLine;
        StrBuf *http_host;                      /**< HTTP Host: header */
        StrBuf *browser_host;
        StrBuf *user_agent;
        StrBuf *plainauth;
 
+
+       const WebcitHandler *Handler;
+} HdrRefs;
+
+typedef struct _ParsedHttpHdrs {
+       int http_sock;                          /**< HTTP server socket */
+       const char *Pos;
+       StrBuf *ReadBuf;
+
+       
+
+       StrBuf *c_username;
+       StrBuf *c_password;
+       StrBuf *c_roomname;
+       StrBuf *c_language;
        StrBuf *this_page;                      /**< URL of current page */
        StrBuf *PlainArgs; /*TODO: freeme*/
+
        HashList *urlstrings;                   /**< variables passed to webcit in a URL */
        HashList *HTTPHeaders;                  /**< the headers the client sent us */
        int nWildfireHeaders;                   /**< how many wildfire headers did we already send? */
+
+       HdrRefs HR;
 } ParsedHttpHdrs;
 
 
index 8c6cd19..31025cf 100644 (file)
@@ -311,6 +311,7 @@ webcit_calc_dirs_n_files(int relh, const char *basedir, int home, char *webcitdi
  */
 int main(int argc, char **argv)
 {
+       size_t basesize = 2;            /* how big should strbufs be on creation? */
        pthread_t SessThread;           /* Thread descriptor */
        pthread_attr_t attr;            /* Thread attributes */
        int a, i;                       /* General-purpose variables */
@@ -352,9 +353,9 @@ int main(int argc, char **argv)
 
        /* Parse command line */
 #ifdef HAVE_OPENSSL
-       while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfsZ")) != EOF)
+       while ((a = getopt(argc, argv, "h:i:p:t:T:B:x:dD:G:cfsZ")) != EOF)
 #else
-       while ((a = getopt(argc, argv, "h:i:p:t:T:x:dD:G:cfZ")) != EOF)
+       while ((a = getopt(argc, argv, "h:i:p:t:T:B:x:dD:G:cfZ")) != EOF)
 #endif
                switch (a) {
                case 'h':
@@ -376,6 +377,11 @@ int main(int argc, char **argv)
                        pidfile = strdup(optarg);
                        running_as_daemon = 1;
                        break;
+               case 'B': /* Basesize */
+                       basesize = atoi(optarg);
+                       if (basesize > 2)
+                               StartLibCitadel(basesize);
+                       break;
                case 'i':
                        safestrncpy(ip_addr, optarg, sizeof ip_addr);
                        break;
@@ -712,9 +718,13 @@ void worker_entry(void)
 #endif
 
                        if (fail_this_transaction == 0) {
+                               ParsedHttpHdrs Hdr;
+                               memset(&Hdr, 0, sizeof(ParsedHttpHdrs));
+                               Hdr.HR.eReqType = eGET;
+                               Hdr.http_sock = ssock;
 
                                /* Perform an HTTP transaction... */
-                               context_loop(&ssock);
+                               context_loop(&Hdr);
 
                                /* Shut down SSL/TLS if required... */
 #ifdef HAVE_OPENSSL
@@ -724,7 +734,7 @@ void worker_entry(void)
 #endif
 
                                /* ...and close the socket. */
-                               if (ssock > 0)
+                               if (Hdr.http_sock > 0)
                                        lingering_close(ssock);
                        }
 
index ddb3fb7..291743e 100644 (file)
@@ -5,9 +5,8 @@ extern char *static_content_dirs[PATH_MAX];  /**< Disk representation */
 extern int ndirs;
 extern char socket_dir[PATH_MAX];
 
-int ClientGetLine(int *sock, StrBuf *Target, StrBuf *CLineBuf, const char **Pos);
-int client_getln(int *sock, char *buf, int bufsiz);
-int client_read_to(int *sock, StrBuf *Target, StrBuf *Buf, const char **Pos, int bytes, int timeout);
+int ClientGetLine(ParsedHttpHdrs *Hdr, StrBuf *Target);
+int client_read_to(ParsedHttpHdrs *Hdr, StrBuf *Target, int bytes, int timeout);
 int lprintf(int loglevel, const char *format, ...);
 void wc_backtrace(void);
 void ShutDownWebcit(void);