diff --git a/lib/http.c b/lib/http.c
index dcb5674bc86337fcbc2f4bf8f844566700b3684e..5be8a9e6f080527069a6fa29632a4231fcf48e13 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 ad2c11473108ed417a5c2bd6929a7f0b63c261a3..9136ec189ca915d4d493ecc3ad66dc91b1e6cb3d 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 9702453e5ec6c6f73040f3fcb22a54b458894947..ed758e9a89182b6170ccbf0eb307d1515679ecd8 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 ce83852d4d4f5e12189d1adbd9a6c9fbe365b458..0ff07c34e93c568e4339a3368f1bb649635e6fd9 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 b58fc15767059c25aa9bf88e4906df2e7a3a380a..fc358c15ae0682bb754f4dac8f44a36f25f963f6 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 532418020972dabac6586aaa7f1432caadd151b5..401de7ba0f7a5efa116e53b28f48e7fa6765336a 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 86033c8218da98e2f4079c4244319f8dbe07f8f8..565b30d1db1d00901aad9da15507eeef47cd0f2d 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>