Doxyfile file description. Indentation. No change of code.
[yaz-moved-to-github.git] / src / comstack.c
index 96b841c..c943c46 100644 (file)
@@ -2,7 +2,12 @@
  * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
  *
- * $Id: comstack.c,v 1.5 2004-02-19 23:20:44 adam Exp $
+ * $Id: comstack.c,v 1.13 2004-10-15 00:19:00 adam Exp $
+ */
+
+/** 
+ * \file comstack.c
+ * \brief Implements Generic COMSTACK functions
  */
 
 #include <string.h>
@@ -101,8 +106,8 @@ COMSTACK cs_create_host(const char *type_and_host, int blocking, void **vp)
     {
        t = tcpip_type;
         host = type_and_host + 5;
-        if (host[0] == '/' && host[1] == '/')
-            host = host + 2;
+        while (host[0] == '/')
+            host++;
         proto = PROTO_HTTP;
     }
     else if (strncmp(type_and_host, "https:", 6) == 0)
@@ -110,8 +115,8 @@ COMSTACK cs_create_host(const char *type_and_host, int blocking, void **vp)
 #if HAVE_OPENSSL_SSL_H
        t = ssl_type;
         host = type_and_host + 6;
-        if (host[0] == '/' && host[1] == '/')
-            host = host + 2;
+        while (host[0] == '/')
+            host++;
         proto = PROTO_HTTP;
 #else
        return 0;
@@ -121,7 +126,6 @@ COMSTACK cs_create_host(const char *type_and_host, int blocking, void **vp)
     {
        t = tcpip_type;
        host = type_and_host;
-        
     }
     cs = cs_create (t, blocking, proto);
     if (!cs)
@@ -149,11 +153,18 @@ int cs_complete_auto(const unsigned char *buf, int len)
     {
         /* deal with HTTP request/response */
        int i = 2, content_len = 0, chunked = 0;
+       
+       /* if dealing with HTTP responses - then default
+          content length is unlimited (socket close) */
+       if (!memcmp(buf, "HTTP/", 5))
+           content_len = -1; 
 
         while (i <= len-4)
         {
            if (i > 8192)
+           {
                return i;  /* do not allow more than 8K HTTP header */
+           }
             if (buf[i] == '\r' && buf[i+1] == '\n')
             {
                 i += 2;
@@ -164,7 +175,7 @@ int cs_complete_auto(const unsigned char *buf, int len)
                        /* inside chunked body .. */
                         while(1)
                         {
-                            int chunk_len = 0;
+                            int j, chunk_len = 0;
                             i += 2;
 #if CHUNK_DEBUG
 /* debugging */
@@ -177,6 +188,7 @@ int cs_complete_auto(const unsigned char *buf, int len)
                                 printf (">>>\n");
                             }
 #endif
+                           /* read chunk length */
                             while (1)
                                 if (i >= len-2) {
 #if CHUNK_DEBUG
@@ -196,54 +208,67 @@ int cs_complete_auto(const unsigned char *buf, int len)
                                         (buf[i++] - ('a'-10));
                                 else
                                     break;
-                            if (buf[i] != '\r' || buf[i+1] != '\n' ||
-                                chunk_len < 0)
-                                return i+2;    /* bad. stop now */
+                           /* move forward until CRLF - skip chunk ext */
+                           j = 0;
+                           while (buf[i] != '\r' && buf[i+1] != '\n')
+                           {
+                               if (i >= len-2)
+                                   return 0;   /* need more buffer .. */
+                               if (++j > 1000)
+                                   return i; /* enough.. stop */
+                               i++;
+                           }
+                           /* got CRLF */
 #if CHUNK_DEBUG
                            printf ("XXXXXX chunk_len=%d\n", chunk_len);
 #endif                     
+                           if (chunk_len < 0)
+                               return i+2;    /* bad chunk_len */
                             if (chunk_len == 0)
-                            {
-                                /* consider trailing headers .. */
-                                while(i <= len-4)
-                                {
-                                    if (buf[i] == '\r' &&  buf[i+1] == '\n' &&
-                                        buf[i+2] == '\r' && buf[i+3] == '\n')
-                                        if (len >= i+4)
-                                            return i+4;
-                                    i++;
-                                }
+                               break;
+                            i += chunk_len+2;
+                        }
+                       /* consider trailing headers .. */
+                       while(i <= len-4)
+                       {
+                           if (buf[i] == '\r' &&  buf[i+1] == '\n' &&
+                               buf[i+2] == '\r' && buf[i+3] == '\n')
+                               if (len >= i+4)
+                                   return i+4;
+                           i++;
+                       }
 #if CHUNK_DEBUG
 /* debugging */
-                                printf ("XXXXXXXXX not there yet 2\n");
-                                printf ("i=%d len=%d\n", i, len);
+                       printf ("XXXXXXXXX not there yet 2\n");
+                       printf ("i=%d len=%d\n", i, len);
 #endif
-                                return 0;
-                            }
-                            i += chunk_len+2;
-                        }
+                       return 0;
                     }
                     else
                     {   /* not chunked ; inside body */
                         /* i += 2 seems not to work with GCC -O2 .. 
                            so i+2 is used instead .. */
-                        if (len >= (i+2)+ content_len)
+                       if (content_len == -1)
+                           return 0;   /* no content length */
+                        else if (len >= (i+2)+ content_len)
+                       {
                             return (i+2)+ content_len;
+                       }
                     }
                     break;
                 }
                 else if (i < len - 20 && 
-                         !strncasecmp(buf+i, "Transfer-Encoding:", 18))
+                         !strncasecmp((const char *) buf+i, "Transfer-Encoding:", 18))
                 {
                     i+=18;
                     while (buf[i] == ' ')
                         i++;
                     if (i < len - 8)
-                        if (!strncasecmp(buf+i, "chunked", 7))
+                        if (!strncasecmp((const char *) buf+i, "chunked", 7))
                             chunked = 1;
                 }
                 else if (i < len - 17 &&
-                         !strncasecmp(buf+i, "Content-Length:", 15))
+                         !strncasecmp((const char *)buf+i, "Content-Length:", 15))
                 {
                     i+= 15;
                     while (buf[i] == ' ')