diff -Naur curl-7.18.1/include/curl/curl.h curl-7.18.1-ju/include/curl/curl.h
--- curl-7.18.1/include/curl/curl.h	2008-03-30 12:00:51.000000000 +0300
+++ curl-7.18.1-ju/include/curl/curl.h	2008-05-02 10:22:36.000000000 +0300
@@ -289,12 +289,14 @@
   CURLIOE_OK,            /* I/O operation successful */
   CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
   CURLIOE_FAILRESTART,   /* failed to restart the read */
+  CURLIOE_EOF_REACHED,   /* EOF reached in read stream */
   CURLIOE_LAST           /* never use */
 } curlioerr;
 
 typedef enum  {
   CURLIOCMD_NOP,         /* no operation */
   CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+  CURLIOCMD_EOF,         /* EOF reached in read stream */
   CURLIOCMD_LAST         /* never use */
 } curliocmd;
 
diff -Naur curl-7.18.1/lib/transfer.c curl-7.18.1-ju/lib/transfer.c
--- curl-7.18.1/lib/transfer.c	2008-03-23 00:00:21.000000000 +0200
+++ curl-7.18.1-ju/lib/transfer.c	2008-05-02 10:20:55.000000000 +0300
@@ -285,6 +285,40 @@
   return CURLE_OK;
 }
 
+/*
+ * This function returns CURLIOE_EOF_REACHED 
+ * if the read stream's file position is in the end,
+ * i.e. no more data to be read
+ */ 
+CURLcode Curl_readeof(struct connectdata *conn)
+{
+  struct SessionHandle *data = conn->data;
+
+  if(data->set.ioctl) {
+    curlioerr err;
+
+    err = (data->set.ioctl) (data, CURLIOCMD_EOF,
+                             data->set.ioctl_client);
+    if(err) 
+      /* FIXME: convert to a human readable error message */
+      failf(data, "ioctl callback returned error %d\n", (int)err);
+    return err;
+  }
+  else {
+    /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
+       given FILE * stream and we can actually attempt to rewind that
+       ourself with fseek() */
+    if(data->set.fread == (curl_read_callback)fread) {
+      if(feof(data->set.in))
+        /* EOF reached */
+        return CURLIOE_EOF_REACHED;
+      else	
+	return CURLE_OK;
+    }
+  }
+  return CURLIOE_UNKNOWNCMD;
+}
+
 static int data_pending(const struct connectdata *conn)
 {
   /* in the case of libssh2, we can never be really sure that we have emptied
@@ -1413,7 +1447,6 @@
 
       ssize_t i, si;
       ssize_t bytes_written;
-      bool writedone=TRUE;
 
       if((k->bytecount == 0) && (k->writebytecount == 0))
         Curl_pgrsTime(data, TIMER_STARTTRANSFER);
@@ -1465,8 +1498,7 @@
           else if(nread<=0) {
             /* done */
             k->keepon &= ~KEEP_WRITE; /* we're done writing */
-            writedone = TRUE;
-
+    
             if(conn->bits.rewindaftersend) {
               result = Curl_readrewind(conn);
               if(result)
@@ -1552,24 +1584,23 @@
              is to happen */
           data->req.upload_fromhere += bytes_written;
 
-          writedone = TRUE; /* we are done, stop the loop */
         }
         else {
           /* we've uploaded that buffer now */
           data->req.upload_fromhere = k->uploadbuf;
           data->req.upload_present = 0; /* no more bytes left */
 
-          if(k->upload_done) {
+          if(k->upload_done || 
+	     Curl_readeof(conn) == CURLIOE_EOF_REACHED) {
             /* switch off writing, we're done! */
             k->keepon &= ~KEEP_WRITE; /* we're done writing */
-            writedone = TRUE;
           }
         }
 
         k->writebytecount += bytes_written;
         Curl_pgrsSetUploadCounter(data, k->writebytecount);
 
-      } while(!writedone); /* loop until we're done writing! */
+      } while(0); /* loop until we're done writing! */
 
     }
 
diff -Naur curl-7.18.1/lib/transfer.h curl-7.18.1-ju/lib/transfer.h
--- curl-7.18.1/lib/transfer.h	2007-11-15 23:45:45.000000000 +0200
+++ curl-7.18.1-ju/lib/transfer.h	2008-05-02 10:20:55.000000000 +0300
@@ -32,6 +32,7 @@
                         curl_socket_t *socks,
                         int numsocks);
 CURLcode Curl_readrewind(struct connectdata *conn);
+CURLcode Curl_readeof(struct connectdata *conn);
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
 bool Curl_retry_request(struct connectdata *conn, char **url);
 

