Its the job of the stream lib to suppress chunks just consisting of the gzip header.
[citadel.git] / webcit / tcp_sockets.c
index 302c908c1031da4aaf0aedf37ffc27086f7d6e61..33889f665ffc998f81037cbd928aa5232c6cc8ad 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();
 
@@ -575,7 +581,7 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
 
        if (chunked)
        {
-               BufHeader=NewStrBuf();
+               BufHeader = NewStrBuf();
        }
 
        if ((detect_mime != 0) && (bytes_read != 0))
@@ -591,23 +597,45 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
 
                if (ServerRc != 6)
                {
+                       FreeStrBuf(&BufHeader);
                        FreeStrBuf(&Buf);
                        return;
                }
                CT = GuessMimeType(SKEY(WCC->WBuf));
                FlushStrBuf(WCC->WBuf);
                StrBufPlain(MimeType, CT, -1);
+               CheckGZipCompressionAllowed(SKEY(MimeType));
                detect_mime = 0;
                FreeStrBuf(&Buf);
        }
 
+       memset(&WriteBuffer, 0, sizeof(IOBuffer));
+       if (chunked && !DisableGzip && WCC->Hdr->HR.gzip_ok)
+       {
+               is_gzip = 1;
+               SC = StrBufNewStreamContext (eZLibEncode);
+
+               memset(&ReadBuffer, 0, sizeof(IOBuffer));
+               ReadBuffer.Buf = WCC->WBuf;
+
+               WriteBuffer.Buf = NewStrBufPlain(NULL, SIZ*2);;
+               pBuf = WriteBuffer.Buf;
+       }
+       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)
                {
                        FreeStrBuf(&Buf);
+                       FreeStrBuf(&WriteBuffer.Buf);
+                       FreeStrBuf(&BufHeader);
+                       StrBufDestroyStreamContext(eZLibEncode, SC);
                        return;
                }
        }
@@ -620,6 +648,9 @@ void serv_read_binary_to_http(StrBuf *MimeType, size_t total_len, int is_static,
                if (WCC->serv_sock==-1) {
                        FlushStrBuf(WCC->WBuf); 
                        FreeStrBuf(&Buf);
+                       FreeStrBuf(&WriteBuffer.Buf);
+                       FreeStrBuf(&BufHeader);
+                       StrBufDestroyStreamContext(eZLibEncode, SC);
                        return;
                }
 
@@ -637,35 +668,69 @@ 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);
+                       if (is_gzip) {
+                               CheckGZipCompressionAllowed(SKEY(MimeType));
+                               is_gzip = WCC->Hdr->HR.gzip_ok;
+                       }
+                       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)) {
+                               int rc;
+
+                               do {
+                                       rc = StrBufStreamTranscode(eZLibEncode, &WriteBuffer, &ReadBuffer, NULL, -1, SC, done);
+
+                                       if (StrLength (pBuf) > 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(pBuf);
+                                               }
+                                               FlushStrBuf(pBuf);
+                                       }
+                               } while ((rc == 1) && (StrLength(pBuf) > 0));
+                       }
+                       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);
+               }
        }
 
+       StrBufDestroyStreamContext(eZLibEncode, &SC);
+       FreeStrBuf(&WriteBuffer.Buf);
        if ((chunked) && (client_con_state == 0))
        {
                StrBufPlain(BufHeader, HKEY("\r\n0\r\n\r\n"));
                if (send_http(BufHeader) < 0)
                {
                        FreeStrBuf(&Buf);
+                       FreeStrBuf(&BufHeader);
                        return;
                }
        }
+       FreeStrBuf(&BufHeader);
        FreeStrBuf(&Buf);
 }