--------------------- PatchSet 1305 Date: 2001/01/14 13:11:21 Author: rbcollins Branch: te_modules Tag: (none) Log: deflate encoding functional with zlib Members: src/client_side.c:1.1.1.3.4.1.4.13.2.1->1.1.1.3.4.1.4.13.2.2 src/protos.h:1.1.1.3.8.10.2.1->1.1.1.3.8.10.2.2 src/transfer-encoding.c:1.1.4.1->1.1.4.2 Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.1.1.3.4.1.4.13.2.1 retrieving revision 1.1.1.3.4.1.4.13.2.2 diff -u -r1.1.1.3.4.1.4.13.2.1 -r1.1.1.3.4.1.4.13.2.2 --- squid/src/client_side.c 14 Jan 2001 06:10:24 -0000 1.1.1.3.4.1.4.13.2.1 +++ squid/src/client_side.c 14 Jan 2001 13:11:21 -0000 1.1.1.3.4.1.4.13.2.2 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.1.1.3.4.1.4.13.2.1 2001/01/14 06:10:24 rbcollins Exp $ + * $Id: client_side.c,v 1.1.1.3.4.1.4.13.2.2 2001/01/14 13:11:21 rbcollins Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -62,10 +62,6 @@ #endif #endif -#ifdef ATHY_COMPRESSION -#include -#endif - #if LINUX_NETFILTER #include #endif @@ -1246,269 +1242,6 @@ last call: b==0.. good time to clean up *e if you've stored stuff there.. you may produce output if necessary, but last call will be repeated. */ - -/* this is a TE filter */ -static int unbiff (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - - *obuf = ibuf; - *obufl = ibufl; - - if (!ibufl) return 0; - - for (;ibufl>0;ibufl--) - if (ibuf[ibufl-1] == 'a') - ibuf[ibufl-1] ='b'; - else - if (ibuf[ibufl-1] == 'b') - ibuf[ibufl-1] ='a'; - return 0; -} - -/* this is a TE filter */ -static int unjones (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - - *obufl = ibufl; - *obuf = ibuf; - - if (!ibufl) return 0; - - for (;ibufl>0;ibufl--) - if (ibuf[ibufl-1] == 'c') - ibuf[ibufl-1] ='b'; - else - if (ibuf[ibufl-1] == 'b') - ibuf[ibufl-1] ='c'; - return 0; -} - -#ifdef ATHY_COMPRESSION - -/* this is a TE filter */ -static int dogzip (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - compression_t *m13; - char *tb; - int tbl, of,created; - - m13 = *((compression_t **) d); - - if (!m13) - { - if (!ibufl) /* no input, nothing to finish.. */ - { - *obufl = 0; - return 0; - } - - m13 = compression_init (COMPRESSION_GZIP,COMPRESSION_STD); - *d = (void *) m13; - } - - tbl = ibufl+512; - tb = xmalloc (tbl); - - if (ibufl > 0) - { - created = 0; - do - { - created += compression_shrink (m13,ibuf,ibufl,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - ibufl = 0; - } - } - while (of>0); - - } - else /* end signal */ - { - created = compression_free (m13,tb); - *d = NULL; - } - - - *obuf = tb; - *obufl = created; - - return 1; -} - -/* this is a TE filter */ -static int undogzip (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - compression_t *m13; - char *tb; - int tbl, of,created; - - m13 = *((compression_t **) d); - if (!m13) - { - m13 = compression_init (COMPRESSION_GZIP,COMPRESSION_STD); - *d = (void *) m13; - } - - tbl = ibufl*2+512; - tb = xmalloc (tbl); - - created = 0; - if (ibuf) - { - do - { - created += compression_expand (m13,ibuf,ibufl,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - ibufl = 0; - } - } - while (of>0); - } - - else - { - do - { - created += compression_finish_expand (m13,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - } - } - while (of > 0); - - compression_free (m13,tb); - *d = NULL; - } - - - *obuf = tb; - *obufl = created; - - return 1; -} - - -/* this is a TE filter */ -static int dodeflate (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - compression_t *m13; - char *tb; - int tbl, of,created; - - m13 = *((compression_t **) d); - - if (!m13) - { - if (!ibufl) /* no input, nothing to finish.. */ - { - *obufl = 0; - return 0; - } - - m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); - *d = (void *) m13; - } - - tbl = ibufl+512; - tb = xmalloc (tbl); - - if (ibufl > 0) - { - created = 0; - do - { - created += compression_shrink (m13,ibuf,ibufl,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - ibufl = 0; - } - } - while (of>0); - - } - else /* end signal */ - { - created = compression_free (m13,tb); - *d = NULL; - } - - - *obuf = tb; - *obufl = created; - - return 1; -} - -/* this is a TE filter */ -static int undodeflate(char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - compression_t *m13; - char *tb; - int tbl, of,created; - - m13 = *((compression_t **) d); - - if (!m13) - { - m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); /* rfc 1950 */ - *d = (void *) m13; - } - - tbl = ibufl*2+512; - tb = xmalloc (tbl); - - created = 0; - if (ibuf) - { - do - { - created += compression_expand (m13,ibuf,ibufl,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - ibufl = 0; - } - } - while (of>0); - } - - else - { - do - { - created += compression_finish_expand (m13,tb+created,tbl,&of); - if (of>0) - { - tbl = of+16; - tb = xrealloc (tb,created+tbl); - } - } - while (of > 0); - - compression_free (m13,tb); - *d = NULL; - } - - - *obuf = tb; - *obufl = created; - - return 1; -} - -#endif - #ifndef _TE_RVALUES_ #define _TE_RVALUES_ #define TE_BUFFER_ALLOCATED 0x01 @@ -1520,278 +1253,6 @@ #define TE_BUFFERING_OUTPUT 0x08 #endif -static int hexvalue (char i) -{ - if ((i >= '0') && (i<='9')) - i= i - '0'; - else - i = toupper (i) - 'A' + 10; - return i; -} - - -/* this is a TE filter */ -static int dochunk (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - char *tb, *w; - int tbl, created, rv; - - tbl = ibufl+128; - tb = xmalloc (tbl); - rv = 0x00; - - if (ibufl > 0) - { - created = 0; - snprintf (tb,tbl,"%X\r\n", ibufl); - debug(33, 8) ("created chunk of %d\n",ibufl); - - w = tb + strlen (tb); - memcpy (w,ibuf,ibufl); - created = ibufl + (w-tb) + 2; - strcpy (w+ibufl,"\r\n"); - *d = (void *) 0x01; - } - else /* end signal */ - if (*d) - { - strcpy (tb,"0\r\n\r\n"); - created = 5; - debug(33,8) ("created chunk of %d\n",ibufl); - *d = NULL; - rv = 0x08; - } - else - { - *obuf = tb; - *obufl = 0; - return 0x02 | 0x01; /* signal that dochunk() is complete */ - } - - *obuf = tb; - *obufl = created; - - return rv | 0x01; -} - - -static int undochunked - (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - chunked_t *h; - char *tb, *w, *l; - int tbl, created,rv = 1,tr; - - h = *((chunked_t **) d); - - if (!h) - { - h = xmalloc (sizeof (chunked_t)); - h->state = 1; - *d = (void *) h; - } - - tbl = ibufl; - tb = xmalloc (tbl); - - created = 0; - w=ibuf; - l = ibuf+ibufl; - - state_machine_repeat: - - if (ibufl) - switch (h->state) - { - case 1: /* new chunk */ - h->pos = 0; - h->toread = 0; - h->half_crlf = 0; - - for (; (w < l) && !isxdigit (*w); w++); - if (w>=l) - break; - /* no default break! */ - h->state = 2; /* for 1 fallthru */ - - case 2: /* reading hexl */ - for (; (w < l) && isxdigit (*w); w++) - { - h->toread = h->toread << 4; - h->toread += hexvalue(*w); - } - if (w>=l) - break; - h->state = 3; - h->pos = h->toread; - debug(33,8) ("read chunk of %d\n",h->toread); - - - case 3: /* searching for CRLF */ - do - { - if (!h->half_crlf) - { - for (; (w < l) && (*w != '\r') ; w++); - if (w>=l) - break; - h->half_crlf = 1; - w++; - if (w>=l) - break; - } - if (*w != '\n') - h->half_crlf = 0; - else - { - h->state = 4; - } - w++; - if (w>=l) - break; - }while (h->state == 3); - - case 4: - /* gotta read h->toread bytes */ - if (h->toread) - { - tr = min (h->toread, l-w); - memcpy (tb+created, w, tr); - w += tr; - h->toread -= tr; - created += tr; - } - if (h->toread == 0) - { - h->state = 5; - h->half_crlf = 0; - } - if (w>=l) - break; - - case 5: /* seeking CRLF */ - do - { - if (!h->half_crlf) - { - for (; (w < l) && (*w != '\r') ; w++); - if (w>=l) - break; - h->half_crlf = 1; - w++; - if (w>=l) - break; - } - if (*(w++) != '\n') - h->half_crlf = 0; - else - { - debug(33,8) ("completed %d chunk\n",h->pos); - if (h->pos) - { - h->state = 1; - goto state_machine_repeat; - } - else - { - h->state =6; - h->half_crlf = 2; - } - } - - - - if (w>=l) - break; - }while (h->state == 5); - - case 6: - while (h->half_crlf < 4) - { - if (w>=l) - break; - if (!(h->half_crlf % 2)) - if (*w == '\r') - h->half_crlf++; - else - h->half_crlf =0; - else - if (*w == '\n') - h->half_crlf++; - else - h->half_crlf =0; - w++; - } - - /* chunked complete */ - h->state = 7; - rv = 0x04 | 0x01; /* signal that undochunk() is complete */ - - case 7: /* done, ignore */ - break; - } - else - { - xfree (h); - xfree (tb); - *d = NULL; - *obufl = 0; - return 0; - } - - - *obuf = tb; - *obufl = created; - - return rv; -} - - -/* this is a TE filter */ -int biff (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - /* like ROT13.. symmetrical mappings */ - return unbiff (ibuf,ibufl,obuf,obufl,d); -} - -/* this is a TE filter */ -int jones (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) -{ - /* like ROT13.. symmetrical mappings */ - return unjones (ibuf,ibufl,obuf,obufl,d); -} - - -void new_xlat (clientHttpRequest *http, int beg_or_end, - int (*func)(char *, int , char **, int *, void **), - void *data) -{ - TE_list *tp,*tx; - - tp = xmalloc (sizeof (TE_list)); - tp->func = func; - tp->data = data; - - if (beg_or_end == 0) - { /* beginning */ - tp->next = http->te_translations; - http->te_translations = tp; - } - else - { - /* end */ - tp->next = NULL; - for (tx = http->te_translations; tx && tx->next; tx =tx->next); - if (!tx) /* root node */ - http->te_translations = tp; - else - tx->next = tp; - } - - return; -} - - /* * filters out unwanted entries from original reply header * adds extra entries if we have more info than origin server @@ -1920,73 +1381,6 @@ stringClean(&strConnection); } -#if moveme - /* ADD NEW TRANSFER ENCODINGS.. check announcements */ - if (may_apply_tes && httpHeaderHas(ohdr, HDR_TE)) { - char vlb[128]; - vlb[0] = '\0'; - s_te = httpHeaderGetList(ohdr, HDR_TE); - if ((strListIsMember_q(&s_te, "chunked", ',')) || - ((request->http_ver.major == 1) && (request->http_ver.minor >=1))) { - /* chunked is known.. we can add te's. */ - - if (strListIsMember_q(&s_te, "biff", ',')) { - debug(33, 7) ("will add biff\n"); - new_xlat(http, 1, biff, NULL); - - if (added_te) - strcat(vlb, ", "); - else - added_te = 1; - strcat(vlb, "biff"); - } - - if (strListIsMember_q(&s_te, "jones", ',')) { - debug(33, 7) ("will add jones\n"); - new_xlat(http, 1, jones, NULL); - - if (added_te) - strcat(vlb, ", "); - else - added_te = 1; - strcat(vlb, "jones"); - } - -#ifdef ATHY_COMPRESSION - if ((strListIsMember_q(&s_te, "deflate", ',')) - && (!(may_apply_tes & 0x02))) { /* the ce: compressed */ - debug(33, 7) ("will add deflate\n"); - new_xlat(http, 1, dodeflate, NULL); - - if (added_te) - strcat(vlb, ", "); - else - added_te = 1; - strcat(vlb, "deflate"); - } - else /* ONLY IF NOT DEFLATE */ if ((strListIsMember_q(&s_te, - "gzip", ',')) - && (!(may_apply_tes & 0x02))) { /* the ce: compressed */ - debug(33, 7) ("will add gzip\n"); - new_xlat(http, 1, dogzip, NULL); - - if (added_te) - strcat(vlb, ", "); - else - added_te = 1; - strcat(vlb, "gzip"); - } -#endif - - if (added_te) { - debug(33, 7) ("will add chunked\n"); - new_xlat(http, 1, dochunk, NULL); - strcat(vlb, ", chunked"); - httpHeaderPutStr(hdr, HDR_TRANSFER_ENCODING, vlb); - httpHeaderDelById(hdr, HDR_CONTENT_LENGTH); - } -#endif - te_build_encode_xlate_list(ohdr, hdr, &http->te_translations, request->http_ver, &request->flags); #if wrong_order Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.1.1.3.8.10.2.1 retrieving revision 1.1.1.3.8.10.2.2 diff -u -r1.1.1.3.8.10.2.1 -r1.1.1.3.8.10.2.2 --- squid/src/protos.h 14 Jan 2001 06:10:24 -0000 1.1.1.3.8.10.2.1 +++ squid/src/protos.h 14 Jan 2001 13:11:21 -0000 1.1.1.3.8.10.2.2 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.1.1.3.8.10.2.1 2001/01/14 06:10:24 rbcollins Exp $ + * $Id: protos.h,v 1.1.1.3.8.10.2.2 2001/01/14 13:11:21 rbcollins Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -1292,9 +1292,6 @@ /* * transfer_encoding.c */ -extern void new_xlat (TE_list **translations, int beg_or_end, - int (*func)(char *, int , char **, int *, void **), - void *data); extern int perform_te (TE_list *xlat, char *ibuf, int ibufl, char **obuf, int *obufl); /* alters hdr as it build the list */ Index: squid/src/transfer-encoding.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/transfer-encoding.c,v retrieving revision 1.1.4.1 retrieving revision 1.1.4.2 diff -u -r1.1.4.1 -r1.1.4.2 --- squid/src/transfer-encoding.c 14 Jan 2001 06:10:24 -0000 1.1.4.1 +++ squid/src/transfer-encoding.c 14 Jan 2001 13:11:21 -0000 1.1.4.2 @@ -37,14 +37,23 @@ #include "squid.h" +#ifdef ATHY_COMPRESSION +#include +#else +#define ZLIB_STATIC +#include +#endif + +/* NOTES: TEFILTERS MUST set obuf and obufl */ + int perform_te (TE_list *xlat, char *ibuf, int ibufl, char **obuf, int *obufl) { int rv = 0, made_new, orig_len; - *obuf = ibuf; - *obufl = ibufl; + *obuf = NULL; /* was *ibuf */ + *obufl = 0; /* was ibufl */ orig_len = ibufl; made_new = 0; @@ -52,6 +61,7 @@ while (xlat) { /* xlat func is likely to be unbiff or dogzip() or something */ + debug(82,1)("perform te %p\n",xlat->func); rv &= 0xFE; /* turn off low bit, for reuse, while preserving chunk indicators */ @@ -298,15 +308,565 @@ return rv; } + + +/* this is a TE filter */ +static int unbiff (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + + *obuf = ibuf; + *obufl = ibufl; + + if (!ibufl) return 0; + + for (;ibufl>0;ibufl--) + if (ibuf[ibufl-1] == 'a') + ibuf[ibufl-1] ='b'; + else + if (ibuf[ibufl-1] == 'b') + ibuf[ibufl-1] ='a'; + return 0; +} + +/* this is a TE filter */ +int biff (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + /* like ROT13.. symmetrical mappings */ + return unbiff (ibuf,ibufl,obuf,obufl,d); +} + +/* this is a TE filter */ +static int unjones (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + + *obufl = ibufl; + *obuf = ibuf; + + if (!ibufl) return 0; + + for (;ibufl>0;ibufl--) + if (ibuf[ibufl-1] == 'c') + ibuf[ibufl-1] ='b'; + else + if (ibuf[ibufl-1] == 'b') + ibuf[ibufl-1] ='c'; + return 0; +} + +/* this is a TE filter */ +int jones (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + /* like ROT13.. symmetrical mappings */ + return unjones (ibuf,ibufl,obuf,obufl,d); +} + + +#ifdef ATHY_COMPRESSION + +/* this is a TE filter */ +static int dogzip (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + + if (!m13) + { + if (!ibufl) /* no input, nothing to finish.. */ + { + *obufl = 0; + return 0; + } + + m13 = compression_init (COMPRESSION_GZIP,COMPRESSION_STD); + *d = (void *) m13; + } + + tbl = ibufl+512; + tb = xmalloc (tbl); + + if (ibufl > 0) + { + created = 0; + do + { + created += compression_shrink (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + + } + else /* end signal */ + { + created = compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + + return 1; +} + +/* this is a TE filter */ +static int undogzip (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + if (!m13) + { + m13 = compression_init (COMPRESSION_GZIP,COMPRESSION_STD); + *d = (void *) m13; + } + + tbl = ibufl*2+512; + tb = xmalloc (tbl); + + created = 0; + if (ibuf) + { + do + { + created += compression_expand (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + } + + else + { + do + { + created += compression_finish_expand (m13,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + } + } + while (of > 0); + + compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + + return 1; +} + + +/* this is a TE filter */ +static int dodeflate (char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + + if (!m13) + { + if (!ibufl) /* no input, nothing to finish.. */ + { + *obufl = 0; + return 0; + } + + m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); + *d = (void *) m13; + } + + tbl = ibufl+512; + tb = xmalloc (tbl); + + if (ibufl > 0) + { + created = 0; + do + { + created += compression_shrink (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + + } + else /* end signal */ + { + created = compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + + return 1; +} + +/* this is a TE filter */ +static int undodeflate(char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + + if (!m13) + { + m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); /* rfc 1950 */ + *d = (void *) m13; + } + + tbl = ibufl*2+512; + tb = xmalloc (tbl); + + created = 0; + if (ibuf) + { + do + { + created += compression_expand (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + } + + else + { + do + { + created += compression_finish_expand (m13,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + } + } + while (of > 0); + + compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + + return 1; +} +#else /*ATH_COMPRESSION*/ + +static void * compcalloc (void *opaque, uInt items, uInt size) { + return xcalloc(items, size); +} + +static void compfree (void *opaque, void * address) { + xfree (address); +} + +/* this is a TE filter */ +static int dodeflate (char *ibuf, size_t ibufl, char **obuf, size_t *obufl, void **d) +{ +/* 4K. TODO: lookup membuf 4k thingy code */ +#define DEFLATEBLOCKSIZE 40 + z_streamp zdata; + size_t output=0; + int rv; + /* if we run out of output space, we have to store the already output data */ + char *tempbuf=NULL; + + if (!ibufl && !*d) { + /* we haven't been inited and there's nothing to do */ + *obufl=0; + *obuf=NULL; + return 1; + } + if (!*d) { + int rv; + /* first call - no data in progress */ + zdata=xmalloc(sizeof(z_stream)); + *d=zdata; + assert(zdata!= NULL); + zdata->zalloc=compcalloc; + zdata->zfree=compfree; + zdata->opaque=NULL; + + rv=deflateInit(zdata, Z_DEFAULT_COMPRESSION); + debug (82,1)("dodeflate: initialising compression library: rv is %d\n",rv); + if (rv != Z_OK) { + /* error initing compressiong */ + debug(82,1)("dodeflate: compression library returned: %s\n",zdata->msg); + return 0; + } + + } + zdata=*d; + assert (!((ibufl==0) && ibuf != NULL)); + zdata->next_in=ibuf; + zdata->avail_in=ibufl; + assert(*obuf==NULL); + /* this code assumes obug starts NULL */ + debug(82,1)("available buffer = %d ibufl = %d\n", DEFLATEBLOCKSIZE,ibufl); + *obuf = xmalloc( DEFLATEBLOCKSIZE); + if (ibufl >0) { + debug(82,1)("dodeflate compressing %d bytes\n",ibufl); + do { + zdata->next_out=*obuf+output; + zdata->avail_out=DEFLATEBLOCKSIZE; + rv=deflate(zdata,Z_NO_FLUSH); + debug(1,1)("first byte of output: %d\n",**obuf); + output+= DEFLATEBLOCKSIZE-zdata->avail_out; + if (zdata->avail_in) { + /* ran out of space */ + debug(82,1)("dodeflate allocating another %d bytes\n",DEFLATEBLOCKSIZE); + tempbuf=*obuf; + *obuf=xmalloc(output+DEFLATEBLOCKSIZE); + memcpy(*obuf,tempbuf,output); + xfree(tempbuf); + } else if (rv != Z_OK) { + xfree(*obuf); + *obuf=0; + *obufl=0; + deflateEnd(zdata); + xfree(zdata); + *d=NULL; + return 0; + } + } while (zdata->avail_in); + debug(82,1)("avail in %d, out %d\n",zdata->avail_in, zdata->avail_out); + debug(82,1)("created block of %d bytes\n",output); + *obufl=output; + } + else { + debug(82,1)("dodeflate flushing buffer at EOF\n"); + /* flush the remaining data */ + do { + zdata->avail_out= DEFLATEBLOCKSIZE; + zdata->next_out=*obuf+output; + rv=deflate (zdata, Z_FINISH); + debug(1,1)("first byte of output: %d\n",**obuf); + output+= DEFLATEBLOCKSIZE-zdata->avail_out; + if (rv==Z_OK && (zdata->avail_out == 0)) { + /* ran out of space */ + debug(82,1)("dodeflate allocating another %d bytes\n",DEFLATEBLOCKSIZE); + tempbuf=*obuf; + *obuf=xmalloc(output+DEFLATEBLOCKSIZE); + memcpy(*obuf,tempbuf,output); + xfree(tempbuf); + } else if (rv != Z_STREAM_END) { + /* wasn't out of space, and not all finished */ + debug(82,1)("dodeflate: error flushing data\n"); + xfree(*obuf); + *obuf=0; + *obufl=0; + deflateEnd(zdata); + xfree(zdata); + *d=NULL; + return 0; + } + } while (rv != Z_STREAM_END); + debug(82,1)("avail in %d, out %d\n",zdata->avail_in, zdata->avail_out); + *obufl=output; + debug(82,1)("obufl = %d\nlast block = %d\n",*obufl, DEFLATEBLOCKSIZE-zdata->avail_out); + deflateEnd(zdata); + xfree(zdata); + *d=NULL; + return TE_BUFFER_ALLOCATED; /* & TE_BUFFERED_OUTPUT */ + + } + return TE_BUFFER_ALLOCATED; /* & TE_BUFFERED_OUTPUT */ + + +#if 0 + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + + if (!m13) + { + if (!ibufl) /* no input, nothing to finish.. */ + { + *obufl = 0; + return 0; + } + + m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); + *d = (void *) m13; + } + + tbl = ibufl+512; + tb = xmalloc (tbl); + + if (ibufl > 0) + { + created = 0; + do + { + created += compression_shrink (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + + } + else /* end signal */ + { + created = compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + + return 1; +#endif +} +/* this is a TE filter */ +static int undodeflate(char *ibuf, int ibufl, char **obuf, int *obufl, void **d) +{ +#if 0 + compression_t *m13; + char *tb; + int tbl, of,created; + + m13 = *((compression_t **) d); + + if (!m13) + { + m13 = compression_init (COMPRESSION_ZLIB,COMPRESSION_STD); /* rfc 1950 */ + *d = (void *) m13; + } + + tbl = ibufl*2+512; + tb = xmalloc (tbl); + + created = 0; + if (ibuf) + { + do + { + created += compression_expand (m13,ibuf,ibufl,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + ibufl = 0; + } + } + while (of>0); + } + + else + { + do + { + created += compression_finish_expand (m13,tb+created,tbl,&of); + if (of>0) + { + tbl = of+16; + tb = xrealloc (tb,created+tbl); + } + } + while (of > 0); + + compression_free (m13,tb); + *d = NULL; + } + + + *obuf = tb; + *obufl = created; + +#endif + return 1; +} + +#endif /*!ATHY_COMPRESSION*/ + + +typedef int TEFILTER (char *ibuf, int ibufl, char **obuf, int *obufl, void **data); +typedef struct _te_coding_t te_coding_t; +struct _te_coding_t { + te_coding_t *next; + char *token; + TEFILTER *encode; + TEFILTER *decode; +}; + +static te_coding_t *codecs=NULL; + +void teAddCoding(char *token, TEFILTER *coder, TEFILTER *decoder) { + te_coding_t * codec; + codec=codecs; + while (codec){ + if (!strcmp(codec->token,token)) { + debug(82,1)("teAddCoding: cannot add already registered codec %s\n",token); + return; + } + codec=codec->next; + } + /* yes yes mempools come after it works */ + codec=xmalloc(sizeof(te_coding_t)); + codec->next=codecs; + codecs=codec; + codec->token=token; + codec->encode=coder; + codec->decode=decoder; +} + void -new_xlat (TE_list **translations, int beg_or_end, - int (*func)(char *, int , char **, int *, void **), - void *data) +new_xlat (TE_list **translations, int beg_or_end, const char * token, int decode, void *data) { TE_list *tp,*tx; + te_coding_t *codec; tp = xmalloc (sizeof (TE_list)); - tp->func = func; + codec=codecs; + while (codec){ + if (!strcmp(codec->token,token)) + break; + codec=codec->next; + } + assert (codec); + debug(1,1)("***************** codec is %s\n",codec->token); + tp->func = decode ? codec->decode : codec->encode; tp->data = data; if (beg_or_end == 0) @@ -335,6 +895,14 @@ const char *pos = NULL; const char *item; int y; + + if (!codecs) { + teAddCoding("chunked", dochunk, undochunked); + teAddCoding("biff", biff, unbiff); + teAddCoding("jones", jones, unjones); + teAddCoding("deflate", dodeflate, undodeflate); + } + if (httpHeaderHas(hdr, HDR_TRANSFER_ENCODING)) { s_transfer_encoding = httpHeaderGetList(hdr, HDR_TRANSFER_ENCODING); @@ -349,7 +917,7 @@ /* need to remove the TE.. and rewrite the header */ debug(82, 7) ("removing chunked\n"); - new_xlat(translations, 0, undochunked, NULL); + new_xlat(translations, 0, "chunked", 1, NULL); } @@ -394,31 +962,146 @@ * by allowing pipelining */ +/* + + The Internet Assigned Numbers Authority (IANA) acts as a registry for + transfer-coding value tokens. Initially, the registry contains the + following tokens: "chunked" (section 3.6.1), "identity" (section + 3.6.2), "gzip" (section 3.5), "compress" (section 3.5), and "deflate" + (section 3.5). +*/ + + if (!codecs) { + teAddCoding("chunked", dochunk, undochunked); + teAddCoding("biff", biff, unbiff); + teAddCoding("jones", jones, unjones); + teAddCoding("deflate", dodeflate, undodeflate); + } + + +#if original_code + /* ADD NEW TRANSFER ENCODINGS.. check announcements */ + if (may_apply_tes && httpHeaderHas(ohdr, HDR_TE)) { + char vlb[128]; + vlb[0] = '\0'; + s_te = httpHeaderGetList(ohdr, HDR_TE); + if ((strListWithParamsIsMember(&s_te, "chunked", ',')) || + ((request->http_ver.major == 1) && (request->http_ver.minor >=1))) { + /* chunked is known.. we can add te's. */ + + if (strListWithParamsIsMember_q(&s_te, "biff", ',')) { + debug(33, 7) ("will add biff\n"); + new_xlat(http, 1, biff, NULL); + + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "biff"); + } + + if (strListIsMember_q(&s_te, "jones", ',')) { + debug(33, 7) ("will add jones\n"); + new_xlat(http, 1, jones, NULL); + + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "jones"); + } + +#ifdef ATHY_COMPRESSION + if ((strListIsMember_q(&s_te, "deflate", ',')) + && (!(may_apply_tes & 0x02))) { /* the ce: compressed */ + debug(33, 7) ("will add deflate\n"); + new_xlat(http, 1, dodeflate, NULL); + + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "deflate"); + } + else /* ONLY IF NOT DEFLATE */ if ((strListIsMember_q(&s_te, + "gzip", ',')) + && (!(may_apply_tes & 0x02))) { /* the ce: compressed */ + debug(33, 7) ("will add gzip\n"); + new_xlat(http, 1, dogzip, NULL); + + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "gzip"); + } +#endif +#endif + + if ((httpHeaderHas(ohdr, HDR_TE) || ((http_ver.major == 1) && (http_ver.minor >=1)))) { char vlb[128]; + int added_te=0; vlb[0] = '\0'; s_te = httpHeaderGetList(ohdr, HDR_TE); + + /* at least some TE's are supported. Chunked is always supported */ + + /* else if constructs are used for mutually exclusive or redundant + * codings*/ /* loop /choose compression te's */ -/* finish with chunked */ + + /* strListIsMember_q returns the value of param q.. but it's broken */ + /* what is used elsewhere in squid to parse headers like type;param=value;param=value.. */ + if (strListIsMember_q(&s_te, "biff", ',')) { + debug(33, 7) ("will add biff\n"); + new_xlat(translations, 1, "biff", 0, NULL); -#if TEMPORARY_HACK - if ((strListIsMember_q(&s_te, "chunked", ',')) || - ((http_ver.major == 1) && (http_ver.minor >=1))) + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "biff"); + } else + if (strListIsMember_q(&s_te, "jones", ',')) { + debug(33, 7) ("will add jones\n"); + new_xlat(translations, 1, "jones", 0, NULL); + + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "jones"); + } + + if ((strListIsMember_q(&s_te, "deflate", ','))){ +#if 0 + /* this needs to be an acl test against content-encoding */ + && (!(may_apply_tes & 0x02))) { /* the ce: compressed */ #endif - { + debug(33, 7) ("will add deflate\n"); + new_xlat(translations, 1, "deflate", 0, NULL); - /* chunked is known.. we can add te's. */ + if (added_te) + strcat(vlb, ", "); + else + added_te = 1; + strcat(vlb, "deflate"); + } /* always add chunked to cover nonterminating encodings */ - debug(82, 7) ("will add chunked\n"); - new_xlat(translations, 1, dochunk, NULL); - strcat(vlb, "chunked"); - httpHeaderPutStr(hdr, HDR_TRANSFER_ENCODING, vlb); - httpHeaderDelById(hdr, HDR_CONTENT_LENGTH); + debug(82, 7) ("will add chunked\n"); + new_xlat(translations, 1, "chunked", 0, NULL); - } + if (added_te) + strcat(vlb, ", "); + strcat(vlb, "chunked"); + httpHeaderPutStr(hdr, HDR_TRANSFER_ENCODING, vlb); + httpHeaderDelById(hdr, HDR_CONTENT_LENGTH); + + stringClean(&s_te); flags->te_encoding=1; s_te = httpHeaderGetList(hdr, HDR_CONNECTION);