From 498666bdc3673e97a0a1bea97ecb358af05d1c2e Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 5 Mar 2004 12:54:18 +0000
Subject: [PATCH] issue 12 fix

---
 lib/http.c        | 53 +++++++++++++++++++++++++++++++++--------------
 tests/data/test10 |  1 +
 tests/data/test33 |  1 +
 tests/data/test58 |  1 +
 tests/data/test60 |  1 +
 tests/data/test88 |  6 ++++++
 tests/data/test98 |  1 +
 7 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index dcb5674bc8..5be8a9e6f0 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1067,7 +1067,6 @@ CURLcode Curl_http(struct connectdata *conn)
   char *ptr;
   char *request;
   bool authdone=TRUE; /* if the authentication phase is done */
-  Curl_HttpReq httpreq;  /* type of HTTP request */
 
   if(!conn->proto.http) {
     /* Only allocate this struct if we don't already have it! */
@@ -1467,13 +1466,11 @@ CURLcode Curl_http(struct connectdata *conn)
     http->postdata = NULL;  /* nothing to post at this point */
     Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
 
-    if(!authdone)
-      /* until the auth is done, pretend we only do GET */
-      httpreq = HTTPREQ_GET;
-    else
-      httpreq = data->set.httpreq;
+    /* If 'authdone' is still FALSE, we must not set the write socket index to
+       the Curl_transfer() call below, as we're not ready to actually upload
+       any data yet. */
 
-    switch(httpreq) {
+    switch(data->set.httpreq) {
 
     case HTTPREQ_POST_FORM:
       if(Curl_FormInit(&http->form, http->sendit)) {
@@ -1538,8 +1535,8 @@ CURLcode Curl_http(struct connectdata *conn)
         /* setup variables for the upcoming transfer */
         result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
                                &http->readbytecount,
-                               FIRSTSOCKET,
-                               &http->writebytecount);
+                               authdone?FIRSTSOCKET:-1,
+                               authdone?&http->writebytecount:NULL);
       if(result) {
         Curl_formclean(http->sendit); /* free that whole lot */
         return result;
@@ -1554,7 +1551,16 @@ CURLcode Curl_http(struct connectdata *conn)
                     "Content-Length: %" FORMAT_OFF_T "\r\n", /* size */
                     data->set.infilesize );
 
-      add_bufferf(req_buffer, "\r\n");
+      if(!checkheaders(data, "Expect:")) {
+        /* if not disabled explicitly we add a Expect: 100-continue
+           to the headers which actually speeds up post operations (as
+           there is one packet coming back from the web server) */
+        add_bufferf(req_buffer,
+                    "Expect: 100-continue\r\n");
+        data->set.expect100header = TRUE;
+      }
+
+      add_buffer(req_buffer, "\r\n", 2); /* end of headers */
 
       /* set the upload size to the progress meter */
       Curl_pgrsSetUploadSize(data, (double)data->set.infilesize);
@@ -1568,8 +1574,8 @@ CURLcode Curl_http(struct connectdata *conn)
         /* prepare for transfer */
         result = Curl_Transfer(conn, FIRSTSOCKET, -1, TRUE,
                                &http->readbytecount,
-                               FIRSTSOCKET,
-                               &http->writebytecount);
+                               authdone?FIRSTSOCKET:-1,
+                               authdone?&http->writebytecount:NULL);
       if(result)
         return result;
       break;
@@ -1597,15 +1603,19 @@ CURLcode Curl_http(struct connectdata *conn)
         add_bufferf(req_buffer,
                     "Content-Type: application/x-www-form-urlencoded\r\n");
 
-      add_buffer(req_buffer, "\r\n", 2);
-
       if(data->set.postfields) {
 
-        if(postsize < (100*1024)) {
+        if(authdone && (postsize < (100*1024))) {
+          /* If we're not done with the authentication phase, we don't expect
+             to actually send off any data yet. Hence, we delay the sending of
+             the body until we receive that friendly 100-continue response */
+             
           /* The post data is less than 100K, then append it to the header.
              This limit is no magic limit but only set to prevent really huge
              POSTs to get the data duplicated with malloc() and family. */
 
+          add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+
           if(!conn->bits.upload_chunky)
             /* We're not sending it 'chunked', append it to the request
                already now to reduce the number if send() calls */
@@ -1630,9 +1640,22 @@ CURLcode Curl_http(struct connectdata *conn)
 
           /* set the upload size to the progress meter */
           Curl_pgrsSetUploadSize(data, http->postsize);
+
+          if(!authdone && !checkheaders(data, "Expect:")) {
+            /* if not disabled explicitly we add a Expect: 100-continue to the
+               headers which actually speeds up post operations (as there is
+               one packet coming back from the web server) */
+            add_bufferf(req_buffer,
+                        "Expect: 100-continue\r\n");
+            data->set.expect100header = TRUE;
+          }
+
+          add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
         }
       }
       else {
+        add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+
         /* set the upload size to the progress meter */
         Curl_pgrsSetUploadSize(data, (double)data->set.infilesize);
 
diff --git a/tests/data/test10 b/tests/data/test10
index ad2c114731..9136ec189c 100644
--- a/tests/data/test10
+++ b/tests/data/test10
@@ -45,6 +45,7 @@ Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
 Content-Length: 78
+Expect: 100-continue
 
 Weird
      file
diff --git a/tests/data/test33 b/tests/data/test33
index 9702453e5e..ed758e9a89 100644
--- a/tests/data/test33
+++ b/tests/data/test33
@@ -44,6 +44,7 @@ Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
 Content-Length: 50
+Expect: 100-continue
 
 012345678
 012345678
diff --git a/tests/data/test58 b/tests/data/test58
index ce83852d4d..0ff07c34e9 100644
--- a/tests/data/test58
+++ b/tests/data/test58
@@ -37,6 +37,7 @@ Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
 Content-Length: 12
+Expect: 100-continue
 
 a few bytes
 </protocol>
diff --git a/tests/data/test60 b/tests/data/test60
index b58fc15767..fc358c15ae 100644
--- a/tests/data/test60
+++ b/tests/data/test60
@@ -38,6 +38,7 @@ Pragma: no-cache
 Accept: */*
 Transfer-Encoding: chunked
 Content-Length: 1
+Expect: 100-continue
 
 13
 more than one byte
diff --git a/tests/data/test88 b/tests/data/test88
index 5324180209..401de7ba0f 100644
--- a/tests/data/test88
+++ b/tests/data/test88
@@ -1,5 +1,8 @@
 # Server-side
 <reply>
+<servercmd>
+auth_required
+</servercmd>
 <data>
 HTTP/1.1 401 Authorization Required swsclose
 Server: Apache/1.3.27 (Darwin) PHP/4.1.2
@@ -63,6 +66,8 @@ PUT /88 HTTP/1.1
 Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
+Content-Length: 85
+Expect: 100-continue
 
 PUT /88 HTTP/1.1
 Authorization: Digest username="testuser", realm="testrealm", nonce="1053604145", uri="/88", response="78a49fa53d0c228778297687d4168e71"
@@ -71,6 +76,7 @@ Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
 Content-Length: 85
+Expect: 100-continue
 
 This is data we upload with PUT
 a second line
diff --git a/tests/data/test98 b/tests/data/test98
index 86033c8218..565b30d1db 100644
--- a/tests/data/test98
+++ b/tests/data/test98
@@ -40,6 +40,7 @@ Host: 127.0.0.1:8999
 Pragma: no-cache
 Accept: */*
 Content-Length: 14
+Expect: 100-continue
 
 data on stdin
 </protocol>
-- 
GitLab