Index: lib/file.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/file.c,v
retrieving revision 1.105
diff -U 20 -r1.105 file.c
--- lib/file.c	11 Jan 2008 16:49:35 -0000	1.105
+++ lib/file.c	30 Jan 2008 22:30:47 -0000
@@ -437,41 +437,41 @@
 
   Curl_initinfo(data);
   Curl_pgrsStartNow(data);
 
   if(data->set.upload)
     return file_upload(conn);
 
   /* get the fd from the connection phase */
   fd = conn->data->state.proto.file->fd;
 
   /* VMS: This only works reliable for STREAMLF files */
   if( -1 != fstat(fd, &statbuf)) {
     /* we could stat it, then read out the size */
     expected_size = statbuf.st_size;
     fstated = TRUE;
   }
 
   /* If we have selected NOBODY and HEADER, it means that we only want file
      information. Which for FILE can't be much more than the file size and
      date. */
-  if(conn->bits.no_body && data->set.include_header && fstated) {
+  if(data->set.opt_no_body && data->set.include_header && fstated) {
     CURLcode result;
     snprintf(buf, sizeof(data->state.buffer),
              "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
     result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
     if(result)
       return result;
 
     result = Curl_client_write(conn, CLIENTWRITE_BOTH,
                                (char *)"Accept-ranges: bytes\r\n", 0);
     if(result)
       return result;
 
     if(fstated) {
       const struct tm *tm;
       time_t filetime = (time_t)statbuf.st_mtime;
 #ifdef HAVE_GMTIME_R
       struct tm buffer;
       tm = (const struct tm *)gmtime_r(&filetime, &buffer);
 #else
       tm = gmtime(&filetime);
Index: lib/ftp.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ftp.c,v
retrieving revision 1.464
diff -U 20 -r1.464 ftp.c
--- lib/ftp.c	15 Jan 2008 23:19:02 -0000	1.464
+++ lib/ftp.c	30 Jan 2008 22:30:52 -0000
@@ -1456,41 +1456,41 @@
 {
   CURLcode result = CURLE_OK;
 
   /* We've sent the TYPE, now we must send the list of prequote strings */
 
   result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
 
   return result;
 }
 
 static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct FTP *ftp = conn->data->state.proto.ftp;
   struct SessionHandle *data = conn->data;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   /* If we have selected NOBODY and HEADER, it means that we only want file
      information. Which in FTP can't be much more than the file size and
      date. */
-  if(conn->bits.no_body && ftpc->file &&
+  if(data->set.opt_no_body && ftpc->file &&
      ftp_need_type(conn, data->set.prefer_ascii)) {
     /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
        may not support it! It is however the only way we have to get a file's
        size! */
 
     ftp->transfer = FTPTRANSFER_INFO;
     /* this means no actual transfer will be made */
 
     /* Some servers return different sizes for different modes, and thus we
        must set the proper type before we check the size */
     result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
     if(result)
       return result;
   }
   else
     result = ftp_state_post_type(conn);
 
   return result;
 }
 
@@ -1990,41 +1990,41 @@
       /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
          last .sss part is optional and means fractions of a second */
       int year, month, day, hour, minute, second;
       char *buf = data->state.buffer;
       if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
                      &year, &month, &day, &hour, &minute, &second)) {
         /* we have a time, reformat it */
         time_t secs=time(NULL);
         /* using the good old yacc/bison yuck */
         snprintf(buf, sizeof(conn->data->state.buffer),
                  "%04d%02d%02d %02d:%02d:%02d GMT",
                  year, month, day, hour, minute, second);
         /* now, convert this into a time() value: */
         data->info.filetime = (long)curl_getdate(buf, &secs);
       }
 
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
       /* If we asked for a time of the file and we actually got one as well,
          we "emulate" a HTTP-style header in our output. */
 
-      if(conn->bits.no_body &&
+      if(data->set.opt_no_body &&
          ftpc->file &&
          data->set.get_filetime &&
          (data->info.filetime>=0) ) {
         struct tm *tm;
         time_t filetime = (time_t)data->info.filetime;
 #ifdef HAVE_GMTIME_R
         struct tm buffer;
         tm = (struct tm *)gmtime_r(&filetime, &buffer);
 #else
         tm = gmtime(&filetime);
 #endif
         /* format: "Tue, 15 Nov 1994 12:45:26" */
         snprintf(buf, BUFSIZE-1,
                  "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
                  Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
                  tm->tm_mday,
                  Curl_month[tm->tm_mon],
                  tm->tm_year + 1900,
                  tm->tm_hour,
                  tm->tm_min,
@@ -3558,41 +3558,41 @@
 
 
 /***********************************************************************
  *
  * ftp_perform()
  *
  * This is the actual DO function for FTP. Get a file/directory according to
  * the options previously setup.
  */
 
 static
 CURLcode ftp_perform(struct connectdata *conn,
                      bool *connected,  /* connect status after PASV / PORT */
                      bool *dophase_done)
 {
   /* this is FTP and no proxy */
   CURLcode result=CURLE_OK;
 
   DEBUGF(infof(conn->data, "DO phase starts\n"));
 
-  if(conn->bits.no_body) {
+  if(conn->data->set.opt_no_body) {
     /* requested no body means no transfer... */
     struct FTP *ftp = conn->data->state.proto.ftp;
     ftp->transfer = FTPTRANSFER_INFO;
   }
 
 
   *dophase_done = FALSE; /* not done yet */
 
   /* start the first command in the DO phase */
   result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
   if(result)
     return result;
 
   /* run the state-machine */
   if(conn->data->state.used_interface == Curl_if_multi)
     result = ftp_multi_statemach(conn, dophase_done);
   else {
     result = ftp_easy_statemach(conn);
     *dophase_done = TRUE; /* with the easy interface we are done here */
   }
Index: lib/http.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/http.c,v
retrieving revision 1.359
diff -U 20 -r1.359 http.c
--- lib/http.c	25 Jan 2008 23:33:45 -0000	1.359
+++ lib/http.c	30 Jan 2008 22:30:59 -0000
@@ -825,41 +825,41 @@
  * data. It is used when a huge POST is to be made and the entire chunk wasn't
  * sent in the first send(). This function will then be called from the
  * transfer.c loop when more data is to be sent to the peer.
  *
  * Returns the amount of bytes it filled the buffer with.
  */
 static size_t readmoredata(char *buffer,
                            size_t size,
                            size_t nitems,
                            void *userp)
 {
   struct connectdata *conn = (struct connectdata *)userp;
   struct HTTP *http = conn->data->state.proto.http;
   size_t fullsize = size * nitems;
 
   if(0 == http->postsize)
     /* nothing to return */
     return 0;
 
   /* make sure that a HTTP request is never sent away chunked! */
-  conn->bits.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
+  conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
 
   if(http->postsize <= (curl_off_t)fullsize) {
     memcpy(buffer, http->postdata, (size_t)http->postsize);
     fullsize = (size_t)http->postsize;
 
     if(http->backup.postsize) {
       /* move backup data into focus and continue on that */
       http->postdata = http->backup.postdata;
       http->postsize = http->backup.postsize;
       conn->fread_func = http->backup.fread_func;
       conn->fread_in = http->backup.fread_in;
 
       http->sending++; /* move one step up */
 
       http->backup.postsize=0;
     }
     else
       http->postsize = 0;
 
     return fullsize;
@@ -1940,41 +1940,41 @@
   if(!data->state.proto.http) {
     /* Only allocate this struct if we don't already have it! */
 
     http = (struct HTTP *)calloc(sizeof(struct HTTP), 1);
     if(!http)
       return CURLE_OUT_OF_MEMORY;
     data->state.proto.http = http;
   }
   else
     http = data->state.proto.http;
 
   if( (conn->protocol&(PROT_HTTP|PROT_FTP)) &&
        data->set.upload) {
     httpreq = HTTPREQ_PUT;
   }
 
   /* Now set the 'request' pointer to the proper request string */
   if(data->set.str[STRING_CUSTOMREQUEST])
     request = data->set.str[STRING_CUSTOMREQUEST];
   else {
-    if(conn->bits.no_body)
+    if(data->set.opt_no_body)
       request = (char *)"HEAD";
     else {
       DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
       switch(httpreq) {
       case HTTPREQ_POST:
       case HTTPREQ_POST_FORM:
         request = (char *)"POST";
         break;
       case HTTPREQ_PUT:
         request = (char *)"PUT";
         break;
       default: /* this should never happen */
       case HTTPREQ_GET:
         request = (char *)"GET";
         break;
       case HTTPREQ_HEAD:
         request = (char *)"HEAD";
         break;
       }
     }
@@ -2008,47 +2008,57 @@
   if(data->change.referer && !checkheaders(data, "Referer:"))
     conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
   else
     conn->allocptr.ref = NULL;
 
   if(data->set.str[STRING_COOKIE] && !checkheaders(data, "Cookie:"))
     addcookies = data->set.str[STRING_COOKIE];
 
   if(!checkheaders(data, "Accept-Encoding:") &&
      data->set.str[STRING_ENCODING]) {
     Curl_safefree(conn->allocptr.accept_encoding);
     conn->allocptr.accept_encoding =
       aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
     if(!conn->allocptr.accept_encoding)
       return CURLE_OUT_OF_MEMORY;
   }
 
   ptr = checkheaders(data, "Transfer-Encoding:");
   if(ptr) {
     /* Some kind of TE is requested, check if 'chunked' is chosen */
-    conn->bits.upload_chunky =
+    data->req.upload_chunky =
       Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
   }
   else {
-    if(httpreq == HTTPREQ_GET)
-      conn->bits.upload_chunky = FALSE;
-    if(conn->bits.upload_chunky)
+    if((conn->protocol&PROT_HTTP) &&
+        data->set.upload &&
+        (data->set.infilesize == -1) &&
+        (data->set.httpversion != CURL_HTTP_VERSION_1_0)) {
+      /* HTTP, upload, unknown file size and not HTTP 1.0 */
+      data->req.upload_chunky = TRUE;
+    }
+    else {
+      /* else, no chunky upload */
+      data->req.upload_chunky = FALSE;
+    }
+
+    if(data->req.upload_chunky)
       te = "Transfer-Encoding: chunked\r\n";
   }
 
   Curl_safefree(conn->allocptr.host);
 
   ptr = checkheaders(data, "Host:");
   if(ptr && (!data->state.this_is_a_follow ||
              curl_strequal(data->state.first_host, conn->host.name))) {
 #if !defined(CURL_DISABLE_COOKIES)
     /* If we have a given custom Host: header, we extract the host name in
        order to possibly use it for cookie reasons later on. We only allow the
        custom Host: header if this is NOT a redirect, as setting Host: in the
        redirected request is being out on thin ice. Except if the host name
        is the same as the first one! */
     char *start = ptr+strlen("Host:");
     while(*start && ISSPACE(*start ))
       start++;
     ptr = start; /* start host-scanning here */
 
     /* scan through the string to find the end (space or colon) */
@@ -2477,41 +2487,41 @@
           failf(data, "Failed sending POST request");
         else
           /* setup variables for the upcoming transfer */
           result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
                                        &http->readbytecount,
                                        -1, NULL);
         break;
       }
 
       if(Curl_FormInit(&http->form, http->sendit)) {
         failf(data, "Internal HTTP POST error!");
         return CURLE_HTTP_POST_ERROR;
       }
 
       /* set the read function to read from the generated form data */
       conn->fread_func = (curl_read_callback)Curl_FormReader;
       conn->fread_in = &http->form;
 
       http->sending = HTTPSEND_BODY;
 
-      if(!conn->bits.upload_chunky) {
+      if(!data->req.upload_chunky) {
         /* only add Content-Length if not uploading chunked */
         result = add_bufferf(req_buffer,
                              "Content-Length: %" FORMAT_OFF_T "\r\n",
                              http->postsize);
         if(result)
           return result;
       }
 
       result = expect100(data, req_buffer);
       if(result)
         return result;
 
       {
 
         /* Get Content-Type: line from Curl_formpostheader.
         */
         char *contentType;
         size_t linelength=0;
         contentType = Curl_formpostheader((void *)&http->form,
                                           &linelength);
@@ -2549,41 +2559,41 @@
         Curl_formclean(&http->sendit); /* free that whole lot */
         return result;
       }
 #ifdef CURL_DOES_CONVERSIONS
 /* time to convert the form data... */
       result = Curl_formconvert(data, http->sendit);
       if(result) {
         Curl_formclean(&http->sendit); /* free that whole lot */
         return result;
       }
 #endif /* CURL_DOES_CONVERSIONS */
       break;
 
     case HTTPREQ_PUT: /* Let's PUT the data to the server! */
 
       if(conn->bits.authneg)
         postsize = 0;
       else
         postsize = data->set.infilesize;
 
-      if((postsize != -1) && !conn->bits.upload_chunky) {
+      if((postsize != -1) && !data->req.upload_chunky) {
         /* only add Content-Length if not uploading chunked */
         result = add_bufferf(req_buffer,
                              "Content-Length: %" FORMAT_OFF_T "\r\n",
                              postsize );
         if(result)
           return result;
       }
 
       result = expect100(data, req_buffer);
       if(result)
         return result;
 
       result = add_buffer(req_buffer, "\r\n", 2); /* end of headers */
       if(result)
         return result;
 
       /* set the upload size to the progress meter */
       Curl_pgrsSetUploadSize(data, postsize);
 
       /* this sends the buffer and frees all the buffer resources */
@@ -2595,41 +2605,41 @@
         /* prepare for transfer */
         result = Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
                                      &http->readbytecount,
                                      postsize?FIRSTSOCKET:-1,
                                      postsize?&http->writebytecount:NULL);
       if(result)
         return result;
       break;
 
     case HTTPREQ_POST:
       /* this is the simple POST, using x-www-form-urlencoded style */
 
       if(conn->bits.authneg)
         postsize = 0;
       else
         /* figure out the size of the postfields */
         postsize = (data->set.postfieldsize != -1)?
           data->set.postfieldsize:
           (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
 
-      if(!conn->bits.upload_chunky) {
+      if(!data->req.upload_chunky) {
         /* We only set Content-Length and allow a custom Content-Length if
            we don't upload data chunked, as RFC2616 forbids us to set both
            kinds of headers (Transfer-Encoding: chunked and Content-Length) */
 
         if(!checkheaders(data, "Content-Length:")) {
           /* we allow replacing this header, although it isn't very wise to
              actually set your own */
           result = add_bufferf(req_buffer,
                                "Content-Length: %" FORMAT_OFF_T"\r\n",
                                postsize);
           if(result)
             return result;
         }
       }
 
       if(!checkheaders(data, "Content-Type:")) {
         result = add_bufferf(req_buffer,
                              "Content-Type: application/x-www-form-urlencoded\r\n");
         if(result)
           return result;
@@ -2645,41 +2655,41 @@
           return result;
       }
       else
         data->state.expect100header = FALSE;
 
       if(data->set.postfields) {
 
         if(!data->state.expect100header &&
            (postsize < MAX_INITIAL_POST_SIZE))  {
           /* if we don't use expect: 100  AND
              postsize is less than MAX_INITIAL_POST_SIZE
 
              then append the post data to the HTTP request header. This limit
              is no magic limit but only set to prevent really huge POSTs to
              get the data duplicated with malloc() and family. */
 
           result = add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
           if(result)
             return result;
 
-          if(!conn->bits.upload_chunky) {
+          if(!data->req.upload_chunky) {
             /* We're not sending it 'chunked', append it to the request
                already now to reduce the number if send() calls */
             result = add_buffer(req_buffer, data->set.postfields,
                                 (size_t)postsize);
             included_body = postsize;
           }
           else {
             /* Append the POST data chunky-style */
             result = add_bufferf(req_buffer, "%x\r\n", (int)postsize);
             if(CURLE_OK == result)
               result = add_buffer(req_buffer, data->set.postfields,
                                   (size_t)postsize);
             if(CURLE_OK == result)
               result = add_buffer(req_buffer,
                                   "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
                                   /* CR  LF   0  CR  LF  CR  LF */
             included_body = postsize + 7;
           }
           if(result)
             return result;
Index: lib/http_chunks.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/http_chunks.c,v
retrieving revision 1.42
diff -U 20 -r1.42 http_chunks.c
--- lib/http_chunks.c	2 Jan 2008 22:30:34 -0000	1.42
+++ lib/http_chunks.c	30 Jan 2008 22:30:59 -0000
@@ -164,41 +164,41 @@
         ch->datasize=strtoul(ch->hexbuffer, NULL, 16);
         ch->state = CHUNK_POSTHEX;
       }
       break;
 
     case CHUNK_POSTHEX:
       /* In this state, we're waiting for CRLF to arrive. We support
          this to allow so called chunk-extensions to show up here
          before the CRLF comes. */
       if(*datap == 0x0d)
         ch->state = CHUNK_CR;
       length--;
       datap++;
       break;
 
     case CHUNK_CR:
       /* waiting for the LF */
       if(*datap == 0x0a) {
         /* we're now expecting data to come, unless size was zero! */
         if(0 == ch->datasize) {
-          if(conn->bits.trailerhdrpresent!=TRUE) {
+          if(k->trailerhdrpresent!=TRUE) {
             /* No Trailer: header found - revert to original Curl processing */
             ch->state = CHUNK_STOPCR;
 
             /* We need to increment the datap here since we bypass the
                increment below with the immediate break */
             length--;
             datap++;
 
             /* This is the final byte, continue to read the final CRLF */
             break;
           }
           else {
             ch->state = CHUNK_TRAILER; /* attempt to read trailers */
             conn->trlPos=0;
           }
         }
         else {
           ch->state = CHUNK_DATA;
         }
       }
Index: lib/transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.381
diff -U 20 -r1.381 transfer.c
--- lib/transfer.c	16 Jan 2008 12:24:00 -0000	1.381
+++ lib/transfer.c	30 Jan 2008 22:31:24 -0000
@@ -102,65 +102,65 @@
 #include "easyif.h" /* for Curl_convert_to_network prototype */
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
 /* The last #include file should be: */
 #include "memdebug.h"
 
 #define CURL_TIMEOUT_EXPECT_100 1000 /* counting ms here */
 
 /*
  * This function will call the read callback to fill our buffer with data
  * to upload.
  */
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
 {
   struct SessionHandle *data = conn->data;
   size_t buffersize = (size_t)bytes;
   int nread;
 
-  if(conn->bits.upload_chunky) {
+  if(data->req.upload_chunky) {
     /* if chunked Transfer-Encoding */
     buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
     data->req.upload_fromhere += 10; /* 32bit hex + CRLF */
   }
 
   /* this function returns a size_t, so we typecast to int to prevent warnings
      with picky compilers */
   nread = (int)conn->fread_func(data->req.upload_fromhere, 1,
                                 buffersize, conn->fread_in);
 
   if(nread == CURL_READFUNC_ABORT) {
     failf(data, "operation aborted by callback");
     return CURLE_ABORTED_BY_CALLBACK;
   }
   else if(nread == CURL_READFUNC_PAUSE) {
     struct SingleRequest *k = &data->req;
     k->keepon |= KEEP_READ_PAUSE; /* mark reading as paused */
     return CURLE_OK; /* nothing was read */
   }
   else if((size_t)nread > buffersize)
     /* the read function returned a too large value */
     return CURLE_READ_ERROR;
 
-  if(!conn->bits.forbidchunk && conn->bits.upload_chunky) {
+  if(!data->req.forbidchunk && data->req.upload_chunky) {
     /* if chunked Transfer-Encoding */
     char hexbuffer[11];
     int hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
                           "%x\r\n", nread);
     /* move buffer pointer */
     data->req.upload_fromhere -= hexlen;
     nread += hexlen;
 
     /* copy the prefix to the buffer */
     memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
 
     /* always append CRLF to the data */
     memcpy(data->req.upload_fromhere + nread, "\r\n", 2);
 
     if((nread - hexlen) == 0) {
       /* mark this as done once this chunk is transfered */
       data->req.upload_done = TRUE;
     }
 
     nread+=2; /* for the added CRLF */
@@ -577,41 +577,41 @@
               if(100 == k->httpcode) {
                 /*
                  * We have made a HTTP PUT or POST and this is 1.1-lingo
                  * that tells us that the server is OK with this and ready
                  * to receive the data.
                  * However, we'll get more headers now so we must get
                  * back into the header-parsing state!
                  */
                 k->header = TRUE;
                 k->headerline = 0; /* restart the header line counter */
                 /* if we did wait for this do enable write now! */
                 if(k->write_after_100_header) {
 
                   k->write_after_100_header = FALSE;
                   k->keepon |= KEEP_WRITE;
                 }
               }
               else {
                 k->header = FALSE; /* no more header to parse! */
 
-                if((k->size == -1) && !conn->bits.chunk && !conn->bits.close &&
+                if((k->size == -1) && !k->chunk && !conn->bits.close &&
                    (k->httpversion >= 11) ) {
                   /* On HTTP 1.1, when connection is not to get closed, but no
                      Content-Length nor Content-Encoding chunked have been
                      received, according to RFC2616 section 4.4 point 5, we
                      assume that the server will close the connection to
                      signal the end of the document. */
                   infof(data, "no chunk, no close, no size. Assume close to "
                         "signal end\n");
                   conn->bits.close = TRUE;
                 }
               }
 
               if(417 == k->httpcode) {
                 /*
                  * we got: "417 Expectation Failed" this means:
                  * we have made a HTTP call and our Expect Header
                  * seems to cause a problem => abort the write operations
                  * (or prevent them from starting).
                  */
                 k->write_after_100_header = FALSE;
@@ -666,57 +666,57 @@
 
                 if(result)
                   return result;
 
                 if(conn->bits.rewindaftersend) {
                   /* We rewind after a complete send, so thus we continue
                      sending now */
                   infof(data, "Keep sending data to get tossed away!\n");
                   k->keepon |= KEEP_WRITE;
                 }
               }
 #endif   /* CURL_DISABLE_HTTP */
 
               if(!k->header) {
                 /*
                  * really end-of-headers.
                  *
                  * If we requested a "no body", this is a good time to get
                  * out and return home.
                  */
-                if(conn->bits.no_body)
+                if(data->set.opt_no_body)
                   stop_reading = TRUE;
                 else {
                   /* If we know the expected size of this document, we set the
                      maximum download size to the size of the expected
                      document or else, we won't know when to stop reading!
 
                      Note that we set the download maximum even if we read a
                      "Connection: close" header, to make sure that
                      "Content-Length: 0" still prevents us from attempting to
                      read the (missing) response-body.
                   */
                   /* According to RFC2616 section 4.4, we MUST ignore
                      Content-Length: headers if we are now receiving data
                      using chunked Transfer-Encoding.
                   */
-                  if(conn->bits.chunk)
+                  if(k->chunk)
                     k->size=-1;
 
                 }
                 if(-1 != k->size) {
                   /* We do this operation even if no_body is true, since this
                      data might be retrieved later with curl_easy_getinfo()
                      and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
 
                   Curl_pgrsSetDownloadSize(data, k->size);
                   k->maxdownload = k->size;
                 }
                 /* If max download size is *zero* (nothing) we already
                    have nothing and can safely return ok now! */
                 if(0 == k->maxdownload)
                   stop_reading = TRUE;
 
                 if(stop_reading) {
                   /* we make sure that this socket isn't read more now */
                   k->keepon &= ~KEEP_READ;
                 }
@@ -985,57 +985,57 @@
             }
             else if(Curl_compareheader(k->p, "Connection:", "close")) {
               /*
                * [RFC 2616, section 8.1.2.1]
                * "Connection: close" is HTTP/1.1 language and means that
                * the connection will close when this request has been
                * served.
                */
               conn->bits.close = TRUE; /* close when done */
             }
             else if(Curl_compareheader(k->p,
                                         "Transfer-Encoding:", "chunked")) {
               /*
                * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
                * means that the server will send a series of "chunks". Each
                * chunk starts with line with info (including size of the
                * coming block) (terminated with CRLF), then a block of data
                * with the previously mentioned size. There can be any amount
                * of chunks, and a chunk-data set to zero signals the
                * end-of-chunks. */
-              conn->bits.chunk = TRUE; /* chunks coming our way */
+              k->chunk = TRUE; /* chunks coming our way */
 
               /* init our chunky engine */
               Curl_httpchunk_init(conn);
             }
 
             else if(checkprefix("Trailer:", k->p) ||
                      checkprefix("Trailers:", k->p)) {
               /*
                * This test helps Curl_httpchunk_read() to determine to look
                * for well formed trailers after the zero chunksize record. In
                * this case a CRLF is required after the zero chunksize record
                * when no trailers are sent, or after the last trailer record.
                *
                * It seems both Trailer: and Trailers: occur in the wild.
                */
-              conn->bits.trailerhdrpresent = TRUE;
+              k->trailerhdrpresent = TRUE;
             }
 
             else if(checkprefix("Content-Encoding:", k->p) &&
                      data->set.str[STRING_ENCODING]) {
               /*
                * Process Content-Encoding. Look for the values: identity,
                * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
                * x-compress are the same as gzip and compress. (Sec 3.5 RFC
                * 2616). zlib cannot handle compress.  However, errors are
                * handled further down when the response body is processed
                */
               char *start;
 
               /* Find the first non-space letter */
               for(start=k->p+17;
                   *start && ISSPACE(*start);
                   start++)
                 ;  /* empty loop */
 
               /* Record the content-encoding for later use */
@@ -1241,41 +1241,41 @@
 
             } /* this is HTTP */
           } /* this is the first time we write a body part */
           k->bodywrites++;
 
           /* pass data to the debug function before it gets "dechunked" */
           if(data->set.verbose) {
             if(k->badheader) {
               Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
                          (size_t)k->hbuflen, conn);
               if(k->badheader == HEADER_PARTHEADER)
                 Curl_debug(data, CURLINFO_DATA_IN,
                            k->str, (size_t)nread, conn);
             }
             else
               Curl_debug(data, CURLINFO_DATA_IN,
                          k->str, (size_t)nread, conn);
           }
 
 #ifndef CURL_DISABLE_HTTP
-          if(conn->bits.chunk) {
+          if(k->chunk) {
             /*
              * Here comes a chunked transfer flying and we need to decode this
              * properly.  While the name says read, this function both reads
              * and writes away the data. The returned 'nread' holds the number
              * of actual data it wrote to the client.
              */
 
             CHUNKcode res =
               Curl_httpchunk_read(conn, k->str, nread, &nread);
 
             if(CHUNKE_OK < res) {
               if(CHUNKE_WRITE_ERROR == res) {
                 failf(data, "Failed writing data");
                 return CURLE_WRITE_ERROR;
               }
               failf(data, "Received problem %d in the chunky parser", res);
               return CURLE_RECV_ERROR;
             }
             else if(CHUNKE_STOP == res) {
               size_t dataleft;
@@ -1309,41 +1309,41 @@
                     "Rewinding stream by : %d"
                     " bytes on url %s (size = %" FORMAT_OFF_T
                     ", maxdownload = %" FORMAT_OFF_T
                     ", bytecount = %" FORMAT_OFF_T ", nread = %d)\n",
                     excess, data->state.path,
                     k->size, k->maxdownload, k->bytecount, nread);
               read_rewind(conn, excess);
             }
 
             nread = (ssize_t) (k->maxdownload - k->bytecount);
             if(nread < 0 ) /* this should be unusual */
               nread = 0;
 
             k->keepon &= ~KEEP_READ; /* we're done reading */
           }
 
           k->bytecount += nread;
 
           Curl_pgrsSetDownloadCounter(data, k->bytecount);
 
-          if(!conn->bits.chunk && (nread || k->badheader || is_empty_data)) {
+          if(!k->chunk && (nread || k->badheader || is_empty_data)) {
             /* If this is chunky transfer, it was already written */
 
             if(k->badheader && !k->ignorebody) {
               /* we parsed a piece of data wrongly assuming it was a header
                  and now we output it as body instead */
               result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                          data->state.headerbuff,
                                          k->hbuflen);
               if(result)
                 return result;
             }
             if(k->badheader < HEADER_ALLBAD) {
               /* This switch handles various content encodings. If there's an
                  error here, be sure to check over the almost identical code
                  in http_chunks.c.
                  Make sure that ALL_CONTENT_ENCODINGS contains all the
                  encodings handled here. */
 #ifdef HAVE_LIBZ
               switch (conn->data->set.http_ce_skip ?
                       IDENTITY : k->content_encoding) {
@@ -1611,57 +1611,57 @@
   if(data->set.timeout &&
       (Curl_tvdiff(k->now, k->start) >= data->set.timeout)) {
     if(k->size != -1) {
       failf(data, "Operation timed out after %ld milliseconds with %"
             FORMAT_OFF_T " out of %" FORMAT_OFF_T " bytes received",
             data->set.timeout, k->bytecount, k->size);
     } else {
       failf(data, "Operation timed out after %ld milliseconds with %"
             FORMAT_OFF_T " bytes received",
             data->set.timeout, k->bytecount);
     }
     return CURLE_OPERATION_TIMEDOUT;
   }
 
   if(!k->keepon) {
     /*
      * The transfer has been performed. Just make some general checks before
      * returning.
      */
 
-    if(!(conn->bits.no_body) && (k->size != -1) &&
+    if(!(data->set.opt_no_body) && (k->size != -1) &&
        (k->bytecount != k->size) &&
 #ifdef CURL_DO_LINEEND_CONV
        /* Most FTP servers don't adjust their file SIZE response for CRLFs,
           so we'll check to see if the discrepancy can be explained
           by the number of CRLFs we've changed to LFs.
         */
        (k->bytecount != (k->size + data->state.crlf_conversions)) &&
 #endif /* CURL_DO_LINEEND_CONV */
        !data->req.newurl) {
       failf(data, "transfer closed with %" FORMAT_OFF_T
             " bytes remaining to read",
             k->size - k->bytecount);
       return CURLE_PARTIAL_FILE;
     }
-    else if(!(conn->bits.no_body) &&
-            conn->bits.chunk &&
+    else if(!(data->set.opt_no_body) &&
+            k->chunk &&
             (conn->chunk.state != CHUNK_STOP)) {
       /*
        * In chunked mode, return an error if the connection is closed prior to
        * the empty (terminiating) chunk is read.
        *
        * The condition above used to check for
        * conn->proto.http->chunk.datasize != 0 which is true after reading
        * *any* chunk, not just the empty chunk.
        *
        */
       failf(data, "transfer closed with outstanding read data remaining");
       return CURLE_PARTIAL_FILE;
     }
     if(Curl_pgrsUpdate(conn))
       return CURLE_ABORTED_BY_CALLBACK;
   }
 
   /* Now update the "done" boolean we return */
   *done = (bool)(0 == (k->keepon&(KEEP_READ|KEEP_WRITE|KEEP_READ_PAUSE|KEEP_WRITE_PAUSE)));
 
@@ -1730,41 +1730,41 @@
  * That buffer can be enlarged on demand, but it is never shrunken again.
  *
  * Parts of this function was once written by the friendly Mark Butler
  * <butlerm@xmission.com>.
  */
 
 static CURLcode
 Transfer(struct connectdata *conn)
 {
   CURLcode result;
   struct SessionHandle *data = conn->data;
   struct SingleRequest *k = &data->req;
   bool done=FALSE;
 
   if((conn->sockfd == CURL_SOCKET_BAD) &&
      (conn->writesockfd == CURL_SOCKET_BAD))
     /* nothing to read, nothing to write, we're already OK! */
     return CURLE_OK;
 
   /* we want header and/or body, if neither then don't do this! */
-  if(!conn->bits.getheader && conn->bits.no_body)
+  if(!k->getheader && data->set.opt_no_body)
     return CURLE_OK;
 
   while(!done) {
     curl_socket_t fd_read;
     curl_socket_t fd_write;
 
     /* limit-rate logic: if speed exceeds threshold, then do not include fd in
        select set. The current speed is recalculated in each Curl_readwrite()
        call */
     if((k->keepon & KEEP_WRITE) &&
         (!data->set.max_send_speed ||
          (data->progress.ulspeed < data->set.max_send_speed) )) {
       fd_write = conn->writesockfd;
       k->keepon &= ~KEEP_WRITE_HOLD;
     }
     else {
       fd_write = CURL_SOCKET_BAD;
       if(k->keepon & KEEP_WRITE)
         k->keepon |= KEEP_WRITE_HOLD; /* hold it */
     }
@@ -2300,41 +2300,41 @@
   } while(urlchanged && res == CURLE_OK);
 
   return res;
 }
 
 /* Returns TRUE and sets '*url' if a request retry is wanted */
 bool Curl_retry_request(struct connectdata *conn,
                         char **url)
 {
   bool retry = FALSE;
   struct SessionHandle *data = conn->data;
 
   /* if we're talking upload, we can't do the checks below, unless the protocol
      is HTTP as when uploading over HTTP we will still get a response */
   if(data->set.upload && !(conn->protocol&PROT_HTTP))
     return retry;
 
   if((data->req.bytecount +
       data->req.headerbytecount == 0) &&
      conn->bits.reuse &&
-     !conn->bits.no_body) {
+     !data->set.opt_no_body) {
     /* We got no data, we attempted to re-use a connection and yet we want a
        "body". This might happen if the connection was left alive when we were
        done using it before, but that was closed when we wanted to read from
        it again. Bad luck. Retry the same request on a fresh connect! */
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
 
     conn->bits.close = TRUE; /* close this connection */
     conn->bits.retry = TRUE; /* mark this as a connection we're about
                                 to retry. Marking it this way should
                                 prevent i.e HTTP transfers to return
                                 error just because nothing has been
                                 transfered! */
     retry = TRUE;
   }
 
   return retry;
 }
 
 /*
@@ -2469,57 +2469,57 @@
   int writesockindex,       /* socket index to write to, it may very well be
                                the same we read from. -1 disables */
   curl_off_t *writecountp   /* return number of bytes written or NULL */
   )
 {
   struct SessionHandle *data;
   struct SingleRequest *k;
 
   DEBUGASSERT(conn != NULL);
 
   data = conn->data;
   k = &data->req;
 
   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
 
   /* now copy all input parameters */
   conn->sockfd = sockindex == -1 ?
       CURL_SOCKET_BAD : conn->sock[sockindex];
   conn->writesockfd = writesockindex == -1 ?
       CURL_SOCKET_BAD:conn->sock[writesockindex];
-  conn->bits.getheader = getheader;
+  k->getheader = getheader;
 
   k->size = size;
   k->bytecountp = bytecountp;
   k->writebytecountp = writecountp;
 
   /* The code sequence below is placed in this function just because all
      necessary input is not always known in do_complete() as this function may
      be called after that */
 
-  if(!conn->bits.getheader) {
+  if(!k->getheader) {
     k->header = FALSE;
     if(size > 0)
       Curl_pgrsSetDownloadSize(data, size);
   }
   /* we want header and/or body, if neither then don't do this! */
-  if(conn->bits.getheader || !conn->bits.no_body) {
+  if(k->getheader || !data->set.opt_no_body) {
 
     if(conn->sockfd != CURL_SOCKET_BAD) {
       k->keepon |= KEEP_READ;
     }
 
     if(conn->writesockfd != CURL_SOCKET_BAD) {
       /* HTTP 1.1 magic:
 
          Even if we require a 100-return code before uploading data, we might
          need to write data before that since the REQUEST may not have been
          finished sent off just yet.
 
          Thus, we must check if the request has been sent before we set the
          state info where we wait for the 100-return code
       */
       if(data->state.expect100header &&
           (data->state.proto.http->sending == HTTPSEND_BODY)) {
         /* wait with write until we either got 100-continue or a timeout */
         k->write_after_100_header = TRUE;
         k->start100 = k->start;
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.697
diff -U 20 -r1.697 url.c
--- lib/url.c	29 Jan 2008 12:58:25 -0000	1.697
+++ lib/url.c	30 Jan 2008 22:31:28 -0000
@@ -3521,41 +3521,40 @@
   conn->bits.httpproxy = (bool)(conn->bits.proxy
                                 && (conn->proxytype == CURLPROXY_HTTP));
 
 
   /* Default protocol-independent behavior doesn't support persistent
      connections, so we set this to force-close. Protocols that support
      this need to set this to FALSE in their "curl_do" functions. */
   conn->bits.close = TRUE;
 
   conn->readchannel_inuse = FALSE;
   conn->writechannel_inuse = FALSE;
 
   conn->read_pos = 0;
   conn->buf_len = 0;
 
   /* Store creation time to help future close decision making */
   conn->created = Curl_tvnow();
 
   conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERPWD]);
   conn->bits.proxy_user_passwd = (bool)(NULL != data->set.str[STRING_PROXYUSERPWD]);
-  conn->bits.no_body = data->set.opt_no_body;
   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
 
   if(data->multi && Curl_multi_canPipeline(data->multi) &&
       !conn->master_buffer) {
     /* Allocate master_buffer to be used for pipelining */
     conn->master_buffer = calloc(BUFSIZE, sizeof (char));
     if(!conn->master_buffer)
       return CURLE_OUT_OF_MEMORY;
   }
 
   /* Initialize the pipeline lists */
   conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
   conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
   conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
   if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe)
     return CURLE_OUT_OF_MEMORY;
 
   /* This initing continues below, see the comment "Continue connectdata
@@ -3990,43 +3989,40 @@
 
     conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
     if(conn->bits.proxy_user_passwd) {
       /* use the new proxy user name and proxy password though */
       Curl_safefree(conn->proxyuser);
       Curl_safefree(conn->proxypasswd);
       conn->proxyuser = old_conn->proxyuser;
       conn->proxypasswd = old_conn->proxypasswd;
       old_conn->proxyuser = NULL;
       old_conn->proxypasswd = NULL;
     }
 
     /* host can change, when doing keepalive with a proxy ! */
     if(conn->bits.proxy) {
       free(conn->host.rawalloc);
       conn->host=old_conn->host;
     }
     else
       free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
 
-    /* get the newly set value, not the old one */
-    conn->bits.no_body = old_conn->bits.no_body;
-
     /* re-use init */
     conn->bits.reuse = TRUE; /* yes, we're re-using here */
 
     Curl_safefree(old_conn->user);
     Curl_safefree(old_conn->passwd);
     Curl_safefree(old_conn->proxyuser);
     Curl_safefree(old_conn->proxypasswd);
     Curl_llist_destroy(old_conn->send_pipe, NULL);
     Curl_llist_destroy(old_conn->recv_pipe, NULL);
     Curl_llist_destroy(old_conn->pend_pipe, NULL);
     Curl_safefree(old_conn->master_buffer);
 
     free(old_conn);          /* we don't need this anymore */
 
     *in_connect = conn;      /* return this instead! */
 
     infof(data, "Re-using existing connection! (#%ld) with host %s\n",
           conn->connectindex,
           conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
   }
@@ -4036,52 +4032,40 @@
      * cache of ours!
      */
     ConnectionStore(data, conn);
   }
 
   result = setup_range(data);
   if(result)
     return result;
 
   /* Continue connectdata initialization here. */
 
   /*
    *
    * Inherit the proper values from the urldata struct AFTER we have arranged
    * the persistent connection stuff */
   conn->fread_func = data->set.fread_func;
   conn->fread_in = data->set.in;
   conn->seek_func = data->set.seek_func;
   conn->seek_client = data->set.seek_client;
 
-  if((conn->protocol&PROT_HTTP) &&
-      data->set.upload &&
-      (data->set.infilesize == -1) &&
-      (data->set.httpversion != CURL_HTTP_VERSION_1_0)) {
-    /* HTTP, upload, unknown file size and not HTTP 1.0 */
-    conn->bits.upload_chunky = TRUE;
-  }
-  else {
-    /* else, no chunky upload */
-    conn->bits.upload_chunky = FALSE;
-  }
-
 #ifndef USE_ARES
   /*************************************************************
    * Set timeout if that is being used, and we're not using an asynchronous
    * name resolve.
    *************************************************************/
   if((data->set.timeout || data->set.connecttimeout) && !data->set.no_signal) {
     /*************************************************************
      * Set signal handler to catch SIGALRM
      * Store the old value to be able to set it back later!
      *************************************************************/
 
 #ifdef SIGALRM
 #ifdef HAVE_ALARM
     long shortest;
 #endif
 #ifdef HAVE_SIGACTION
     struct sigaction sigact;
     sigaction(SIGALRM, NULL, &sigact);
     keep_sigact = sigact;
     keep_copysig = TRUE; /* yes, we have a copy */
@@ -4525,42 +4509,42 @@
   k->hbufp = data->state.headerbuff;
   k->ignorebody=FALSE;
 
   Curl_pgrsTime(data, TIMER_PRETRANSFER);
   Curl_speedinit(data);
 
   Curl_pgrsSetUploadCounter(data, 0);
   Curl_pgrsSetDownloadCounter(data, 0);
 
   return CURLE_OK;
 }
 
 /*
  * do_complete is called when the DO actions are complete.
  *
  * We init chunking and trailer bits to their default values here immediately
  * before receiving any header data for the current request in the pipeline.
  */
 static void do_complete(struct connectdata *conn)
 {
-  conn->bits.chunk=FALSE;
-  conn->bits.trailerhdrpresent=FALSE;
+  conn->data->req.chunk=FALSE;
+  conn->data->req.trailerhdrpresent=FALSE;
 
   conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
                                conn->sockfd:conn->writesockfd)+1;
 }
 
 CURLcode Curl_do(struct connectdata **connp, bool *done)
 {
   CURLcode result=CURLE_OK;
   struct connectdata *conn = *connp;
   struct SessionHandle *data = conn->data;
 
   /* setup and init stuff before DO starts, in preparing for the transfer */
   do_init(conn);
 
   if(conn->handler->do_it) {
     /* generic protocol-specific function pointer set in curl_connect() */
     result = conn->handler->do_it(conn, done);
 
     /* This was formerly done in transfer.c, but we better do it here */
     if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.372
diff -U 20 -r1.372 urldata.h
--- lib/urldata.h	21 Jan 2008 23:48:58 -0000	1.372
+++ lib/urldata.h	30 Jan 2008 22:31:30 -0000
@@ -535,94 +535,81 @@
 #endif /* USE_LIBSSH2 */
 };
 
 
 /****************************************************************************
  * FILE unique setup
  ***************************************************************************/
 struct FILEPROTO {
   char *path; /* the path we operate on */
   char *freepath; /* pointer to the allocated block we must free, this might
                      differ from the 'path' pointer */
   int fd;     /* open file descriptor to read from! */
 };
 
 /*
  * Boolean values that concerns this connection.
  */
 struct ConnectBits {
   bool close; /* if set, we close the connection after this request */
   bool reuse; /* if set, this is a re-used connection */
-  bool chunk; /* if set, this is a chunked transfer-encoding */
   bool proxy; /* if set, this transfer is done through a proxy - any type */
   bool httpproxy;    /* if set, this transfer is done through a http proxy */
   bool user_passwd;    /* do we use user+password for this connection? */
   bool proxy_user_passwd; /* user+password for the proxy? */
   bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
                    IP address */
   bool ipv6;    /* we communicate with a site using an IPv6 address */
 
   bool do_more; /* this is set TRUE if the ->curl_do_more() function is
                    supposed to be called, after ->curl_do() */
 
-  bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
-                         on upload */
-  bool getheader;     /* TRUE if header parsing is wanted */
-
-  bool forbidchunk;   /* used only to explicitly forbid chunk-upload for
-                         specific upload buffers. See readmoredata() in
-                         http.c for details. */
-
   bool tcpconnect;    /* the TCP layer (or simimlar) is connected, this is set
                          the first time on the first connect function call */
   bool protoconnstart;/* the protocol layer has STARTED its operation after
                          the TCP layer connect */
 
   bool retry;         /* this connection is about to get closed and then
                          re-attempted at another connection. */
-  bool no_body;       /* CURLOPT_NO_BODY (or similar) was set */
   bool tunnel_proxy;  /* if CONNECT is used to "tunnel" through the proxy.
                          This is implicit when SSL-protocols are used through
                          proxies, but can also be enabled explicitly by
                          apps */
   bool tunnel_connecting; /* TRUE while we're still waiting for a proxy CONNECT
                            */
   bool authneg;       /* TRUE when the auth phase has started, which means
                          that we are creating a request with an auth header,
                          but it is not the final request in the auth
                          negotiation. */
   bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
                           though it will be discarded. When the whole send
                           operation is done, we must call the data rewind
                           callback. */
   bool ftp_use_epsv;  /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
                          EPSV doesn't work we disable it for the forthcoming
                          requests */
 
   bool ftp_use_eprt;  /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
                          EPRT doesn't work we disable it for the forthcoming
                          requests */
   bool netrc;         /* name+password provided by netrc */
 
-  bool trailerhdrpresent; /* Set when Trailer: header found in HTTP response.
-                             Required to determine whether to look for trailers
-                             in case of Transfer-Encoding: chunking */
   bool done;          /* set to FALSE when Curl_do() is called and set to TRUE
                          when Curl_done() is called, to prevent Curl_done() to
                          get invoked twice when the multi interface is
                          used. */
   bool stream_was_rewound; /* Indicates that the stream was rewound after a
                               request read past the end of its response byte
                               boundary */
   bool proxy_connect_closed; /* set true if a proxy disconnected the
                                 connection in a CONNECT request with auth, so
                                 that libcurl should reconnect and continue. */
   bool bound; /* set true if bind() has already been done on this socket/
                  connection */
 };
 
 struct hostname {
   char *rawalloc; /* allocated "raw" version of the name */
   char *encalloc; /* allocated IDN-encoded version of the name */
   char *name;     /* name to use internally, might be encoded, might be raw */
   char *dispname; /* name to display, as 'name' might be encoded */
 };
@@ -756,40 +743,52 @@
 
   bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
                        and we're uploading the last chunk */
 
   bool ignorebody;  /* we read a response-body but we ignore it! */
   bool ignorecl;    /* This HTTP response has no body so we ignore the Content-
                        Length: header */
 
   char *newurl; /* This can only be set if a Location: was in the
                    document headers */
 
   /* 'upload_present' is used to keep a byte counter of how much data there is
      still left in the buffer, aimed for upload. */
   ssize_t upload_present;
 
    /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
       buffer, so the next read should read from where this pointer points to,
       and the 'upload_present' contains the number of bytes available at this
       position */
   char *upload_fromhere;
+
+  bool chunk; /* if set, this is a chunked transfer-encoding */
+  bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
+                         on upload */
+  bool getheader;     /* TRUE if header parsing is wanted */
+
+  bool forbidchunk;   /* used only to explicitly forbid chunk-upload for
+                         specific upload buffers. See readmoredata() in
+                         http.c for details. */
+  bool trailerhdrpresent; /* Set when Trailer: header found in HTTP response.
+                             Required to determine whether to look for trailers
+                             in case of Transfer-Encoding: chunking */
 };
 
 /*
  * Specific protocol handler.
  */
 
 struct Curl_handler {
   const char * scheme;        /* URL scheme name. */
 
   /* Complement to setup_connection_internals(). */
   CURLcode (*setup_connection)(struct connectdata *);
 
   /* These two functions MUST be set to be protocol dependent */
   CURLcode (*do_it)(struct connectdata *, bool *done);
   Curl_done_func done;
 
   /* If the curl_do() function is better made in two halves, this
    * curl_do_more() function will be called afterwards, if set. For example
    * for doing the FTP stuff after the PASV/PORT command.
    */
