diff --git a/include/curl/curl.h b/include/curl/curl.h
index 5b39a24..b112bfd 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -302,6 +302,10 @@ typedef int (*curl_seek_callback)(void *instream,
 /* This is a return code for the read callback that, when returned, will
    signal libcurl to pause sending data on the current transfer. */
 #define CURL_READFUNC_PAUSE 0x10000001
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to flush any pending data. This is only applicable when
+   using the file:// protocol. */
+#define CURL_READFUNC_FLUSH 0x10000002
 
 typedef size_t (*curl_read_callback)(char *buffer,
                                       size_t size,
diff --git a/lib/file.c b/lib/file.c
index 1025022..35be265 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -381,7 +381,8 @@ static CURLcode file_upload(struct connectdata *conn)
 
   while(res == CURLE_OK) {
     int readcount;
-    res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
+    bool flush;
+    res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount, &flush);
     if(res)
       break;
 
@@ -415,6 +416,13 @@ static CURLcode file_upload(struct connectdata *conn)
 
     bytecount += nread;
 
+    if (flush) {
+      if (fflush(buf2) == EOF) {
+        res = CURLE_SEND_ERROR;
+        break;
+      }
+    }
+
     Curl_pgrsSetUploadCounter(data, bytecount);
 
     if(Curl_pgrsUpdate(conn))
diff --git a/lib/tftp.c b/lib/tftp.c
index 7202b94..58ff8f7 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -754,7 +754,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
       state->state = TFTP_STATE_FIN;
       return CURLE_OK;
     }
-    res = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
+    res = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes, NULL);
     if(res)
       return res;
     sbytes = sendto(state->sockfd, (void *)state->spacket.data,
diff --git a/lib/transfer.c b/lib/transfer.c
index 73456ec..bf5c838 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -99,11 +99,13 @@
  * 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)
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp,
+                             bool *flushp)
 {
   struct SessionHandle *data = conn->data;
   size_t buffersize = (size_t)bytes;
   int nread;
+  bool dummy;
 #ifdef CURL_DOES_CONVERSIONS
   bool sending_http_headers = FALSE;
 
@@ -115,12 +117,18 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
   }
 #endif
 
+
   if(data->req.upload_chunky) {
     /* if chunked Transfer-Encoding */
     buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
     data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
   }
 
+  if (flushp == NULL) {
+    flushp = &dummy;
+  }
+  *flushp = FALSE;
+
   /* 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,
@@ -142,6 +150,11 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
     *nreadp = 0;
     return CURLE_OK; /* nothing was read */
   }
+  else if(nread == CURL_READFUNC_FLUSH) {
+    *flushp = TRUE;
+    *nreadp = 0;
+    return CURLE_OK; /* nothing was read */
+  }
   else if((size_t)nread > buffersize) {
     /* the read function returned a too large value */
     *nreadp = 0;
@@ -842,7 +855,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data,
             sending_http_headers = FALSE;
         }
 
-        result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount);
+        result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount, NULL);
         if(result)
           return result;
 
diff --git a/lib/transfer.h b/lib/transfer.h
index 68a31c6..1758019 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -45,7 +45,8 @@ int Curl_single_getsock(const struct connectdata *conn,
                         curl_socket_t *socks,
                         int numsocks);
 CURLcode Curl_readrewind(struct connectdata *conn);
-CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp,
+                             bool *flushp);
 CURLcode Curl_reconnect_request(struct connectdata **connp);
 CURLcode Curl_retry_request(struct connectdata *conn, char **url);
 bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc);

