--- fopen.c.original	2011-05-19 14:49:39.430474525 -0400
+++ fopen.c.rbanfield	2011-05-19 15:40:13.959474466 -0400
@@ -53,6 +53,8 @@
 
 #include <curl/curl.h>
 
+#define MAX_BUFFER_SIZE 4194304
+
 enum fcurl_type_e {
   CFTYPE_NONE=0,
   CFTYPE_FILE=1,
@@ -71,6 +73,7 @@ struct fcurl_data
   size_t buffer_len;          /* currently allocated buffers length */
   size_t buffer_pos;          /* end of data in buffer*/
   int still_running;          /* Is background url fetch still in progress */
+  int paused;                 /* Paused due to max buffer size reached */
 };
 
 typedef struct fcurl_data URL_FILE;
@@ -98,6 +101,12 @@ static size_t write_callback(char *buffe
   URL_FILE *url = (URL_FILE *)userp;
   size *= nitems;
 
+  /* pause transfer when buffer reaches MAX_BUFFER_SIZE in unread data */
+  if(url->buffer_pos > MAX_BUFFER_SIZE) {
+    url->paused=1;
+    return CURL_WRITEFUNC_PAUSE;
+  }
+
   rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
 
   if(size > rembuff) {
@@ -160,6 +169,12 @@ static int fill_buffer(URL_FILE *file, s
     /* get file descriptors from the transfers */
     curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
 
+    /* if maxfd==-1, then all transfers are either done or paused */
+    if(maxfd==-1) {
+      file->still_running=0;
+      return 0;
+    }
+
     /* In a real-world program you OF COURSE check the return code of the
        function calls.  On success, the value of maxfd is guaranteed to be
        greater or equal than -1.  We call select(maxfd + 1, ...), specially
@@ -339,6 +354,12 @@ size_t url_fread(void *ptr, size_t size,
 
     use_buffer(file,want);
 
+    /* restart paused transfer when half of max buffer size reached */
+    if(file->paused && file->buffer_pos < MAX_BUFFER_SIZE/2) {
+      file->paused=0;
+      curl_easy_pause(file->handle.curl, CURLPAUSE_CONT);
+    }
+
     want = want / size;     /* number of items */
     break;
 
@@ -388,6 +409,12 @@ char *url_fgets(char *ptr, size_t size, 
 
     use_buffer(file,want);
 
+    /* restart paused transfer when half of max buffer size reached */
+    if(file->paused && file->buffer_pos < MAX_BUFFER_SIZE/2) {
+      file->paused=0;
+      curl_easy_pause(file->handle.curl, CURLPAUSE_CONT);
+    }
+
     break;
 
   default: /* unknown or supported type - oh dear */
@@ -420,6 +447,10 @@ void url_rewind(URL_FILE *file)
     file->buffer=NULL;
     file->buffer_pos=0;
     file->buffer_len=0;
+    file->paused=0;
+
+    /* lets start the fetch */
+    curl_multi_perform(multi_handle, &file->still_running);
 
     break;
 
@@ -476,9 +507,9 @@ int main(int argc, char *argv[])
     return 1;
   }
 
-  handle = url_fopen("testfile", "r");
+  handle = url_fopen(url, "r");
   if(!handle) {
-    printf("couldn't url_fopen() testfile\n");
+    printf("couldn't url_fopen() %s\n", url);
     fclose(outf);
     return 2;
   }
@@ -500,7 +531,7 @@ int main(int argc, char *argv[])
     return 1;
   }
 
-  handle = url_fopen("testfile", "r");
+  handle = url_fopen(url, "r");
   if(!handle) {
     printf("couldn't url_fopen() testfile\n");
     fclose(outf);
@@ -517,7 +548,6 @@ int main(int argc, char *argv[])
   nread = url_fread(buffer, 1,sizeof(buffer), handle);
   fwrite(buffer,1,nread,outf);
 
-
   url_fclose(handle);
 
   fclose(outf);

