Gzip stream chunked encoding is working now.
authorWilfried Goesgens <dothebart@citadel.org>
Tue, 6 Jan 2015 23:59:43 +0000 (00:59 +0100)
committerWilfried Goesgens <dothebart@citadel.org>
Tue, 6 Jan 2015 23:59:43 +0000 (00:59 +0100)
libcitadel/lib/stringbuf.c
webcit/tcp_sockets.c
webcit/webcit.c
webcit/webcit.h

index 5d196112385d5a11883126692be869720b585d90..9ebc2dd593616ef94b2c9f94cd46563e8d188c87 100644 (file)
@@ -2898,25 +2898,21 @@ void *StrBufNewStreamContext(eStreamType type)
                memset(stream, 0, sizeof(z_enc_stream));
                stream->OutBuf.BufSize = 4*SIZ; /// todo 64
                stream->OutBuf.buf = (char*)malloc(stream->OutBuf.BufSize);
-               /* write gzip header * /
+               /* write gzip header */
                stream->OutBuf.BufUsed = snprintf
                        (stream->OutBuf.buf,
                         stream->OutBuf.BufSize, 
                         "%c%c%c%c%c%c%c%c%c%c",
                         gz_magic[0], gz_magic[1], Z_DEFLATED,
-                        0 /*flags * / , 0, 0, 0, 0 /*time * / , 0 /* xflags * / ,
+                        0 /*flags */ , 0, 0, 0, 0 /*time */ , 0 /* xflags */ ,
                         OS_CODE);
-/*
+
                err = deflateInit2(&stream->zstream,
                                   ZLibCompressionRatio,
                                   Z_DEFLATED,
                                   -MAX_WBITS,
                                   DEF_MEM_LEVEL,
                                   Z_DEFAULT_STRATEGY);
-*/
-               err = deflateInit(&stream->zstream,
-                                 ZLibCompressionRatio);
-
                if (err != Z_OK)
                        return NULL;/// tODO cleanup
                return stream;
index 302c908c1031da4aaf0aedf37ffc27086f7d6e61..f744090b4b20ba3bb6c9c519b39ff968487818a3 100644 (file)
@@ -555,8 +555,14 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
        int first = 1;
        int client_con_state = 0;
        int chunked = 0;
+       int is_gzip = 0;
        StrBuf *BufHeader = NULL;
        StrBuf *Buf;
+       StrBuf *pBuf = NULL;
+       void *SC = NULL;
+       IOBuffer ReadBuffer;
+       IOBuffer WriteBuffer;
+       
 
        Buf = NewStrBuf();
 
@@ -601,9 +607,25 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
                FreeStrBuf(&Buf);
        }
 
+       if (chunked && !DisableGzip && WCC->Hdr->HR.gzip_ok)
+       {
+               is_gzip = 1;
+               SC = StrBufNewStreamContext (eZLibEncode);
+
+               memset(&ReadBuffer, 0, sizeof(IOBuffer));
+               ReadBuffer.Buf = WCC->WBuf;
+
+               memset(&WriteBuffer, 0, sizeof(IOBuffer));
+               WriteBuffer.Buf = NewStrBufPlain(NULL, SIZ*2);;
+       }
+       else
+       {
+               pBuf = WCC->WBuf;
+       }
+
        if (!detect_mime)
        {
-               http_transmit_headers(ChrPtr(MimeType), is_static, chunked);
+               http_transmit_headers(ChrPtr(MimeType), is_static, chunked, is_gzip);
                
                if (send_http(WCC->HBuf) < 0)
                {
@@ -637,24 +659,43 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
                        
                        CT = GuessMimeType(SKEY(WCC->WBuf));
                        StrBufPlain(MimeType, CT, -1);
-                       http_transmit_headers(ChrPtr(MimeType), is_static, chunked);
+                       http_transmit_headers(ChrPtr(MimeType), is_static, chunked, is_gzip);
                        
                        client_con_state = send_http(WCC->HBuf);
                }
 
-               if ((chunked) && (client_con_state == 0))
+               if (is_gzip)
                {
-                       StrBufPrintf(BufHeader, "%s%x\r\n", 
-                                    (first)?"":"\r\n",
-                                    StrLength (WCC->WBuf));
-                       first = 0;
-                       client_con_state = send_http(BufHeader);
+                       int done = (bytes_read == total_len);
+                       while ((IOBufferStrLength(&ReadBuffer) > 0) && (client_con_state == 0)) {
+                               StrBufStreamTranscode(eZLibEncode, &WriteBuffer, &ReadBuffer, NULL, -1, SC, done);
+
+                               StrBufPrintf(BufHeader, "%s%x\r\n", 
+                                            (first)?"":"\r\n",
+                                            StrLength (pBuf));
+                               first = 0;
+                               client_con_state = send_http(BufHeader);
+                               if (client_con_state == 0) {
+                                       client_con_state = send_http(pBuf);
+                               }
+                       }
+                       FlushStrBuf(WCC->WBuf);
                }
+               else {
+                       if ((chunked) && (client_con_state == 0))
+                       {
+                               StrBufPrintf(BufHeader, "%s%x\r\n", 
+                                            (first)?"":"\r\n",
+                                            StrLength (pBuf));
+                               first = 0;
+                               client_con_state = send_http(BufHeader);
+                       }
 
-               if (client_con_state == 0)
-                   client_con_state = send_http(WCC->WBuf);
+                       if (client_con_state == 0)
+                               client_con_state = send_http(pBuf);
 
-               FlushStrBuf(WCC->WBuf);
+                       FlushStrBuf(pBuf);
+               }
        }
 
        if ((chunked) && (client_con_state == 0))
index dd0043d29dd0794af9f2cb43d80e5fe760413dcb..8a0ba58a98cb1d31dac5b5d3b397f312beccfda1 100644 (file)
@@ -249,12 +249,15 @@ void http_transmit_thing(const char *content_type, int is_static)
        end_burst();
 }
 
-void http_transmit_headers(const char *content_type, int is_static, long is_chunked)
+void http_transmit_headers(const char *content_type, int is_static, long is_chunked, int is_gzip)
 {
        wcsession *WCC = WC;
        syslog(LOG_DEBUG, "http_transmit_thing(%s)%s", content_type, ((is_static > 0) ? " (static)" : ""));
        output_headers(0, 0, 0, 0, 0, is_static);
 
+       if (is_gzip)
+               hprintf("Content-encoding: gzip\r\n");
+
        if (WCC->Hdr->HaveRange)
                hprintf("Accept-Ranges: bytes\r\n"
                        "Content-Range: bytes %ld-%ld/%ld\r\n",
index 5df65fe1b886156505db89f1f46d2a8053c98bbf..64034c777eb9f2afe842a23952d93d55714b1d82 100644 (file)
@@ -692,7 +692,7 @@ extern char *days[];
 long locate_user_vcard_in_this_room(message_summary **VCMsg,
                                    wc_mime_attachment **VCAtt);
 void http_transmit_thing(const char *content_type, int is_static);
-void http_transmit_headers(const char *content_type, int is_static, long is_chunked);
+void http_transmit_headers(const char *content_type, int is_static, long is_chunked, int is_gzip);
 long unescape_input(char *buf);
 void check_thread_pool_size(void);
 void StrEndTab(StrBuf *Target, int tabnum, int num_tabs);