SFTP: Increase speed and datasize in SFTP read

The function sftp_read never return more then 2000 bytes (as it should
when I asked Daniel). I increased the MAX_SFTP_READ_SIZE to 30000 but
didn't get the same speed as a sftp read in SecureSSH. I analyzed the
code and found that a return always was dona when a chunk has been read.
I changed it to a sliding buffer and worked on all available chunks. I
got an increase in speed and non of the test I have done has failed
(both local net and over Internet). Please review and test. I think
30000 is still not the optimal MAX_SFTP_READ_SIZE, my next goal is to
make an API to enable changing this value (The SecureSSH sftp_read has
more complete filled packages when comparing the network traffic)
diff --git a/src/sftp.c b/src/sftp.c
index b0cd445..b0a3f1d 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -204,7 +204,8 @@
     LIBSSH2_SFTP_PACKET *packet;
     uint32_t request_id;
 
-    _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
+    _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
+                   "Received packet type %d (len %d)",
                    (int) data[0], data_len);
 
     /*
@@ -250,6 +251,9 @@
 
     request_id = _libssh2_ntohu32(&data[1]);
 
+    _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet id %d",
+                   request_id);
+
     /* Don't add the packet if it answers a request we've given up on. */
     if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA)
         && find_zombie_request(sftp, request_id)) {
@@ -1245,6 +1249,8 @@
     ssize_t rc;
     struct _libssh2_sftp_handle_file_data *filep =
         &handle->u.file;
+    size_t bytes_in_buffer = 0;
+    char *sliding_bufferp = buffer;
 
     /* This function can be interrupted in three different places where it
        might need to wait for data from the network.  It returns EAGAIN to
@@ -1305,7 +1311,7 @@
            without having been acked - until we reach EOF. */
         if(!filep->eof) {
             /* Number of bytes asked for that haven't been acked yet */
-            size_t already = (filep->offset_sent - filep->offset);
+            size_t already = (size_t)(filep->offset_sent - filep->offset);
 
             size_t max_read_ahead = buffer_size*4;
             unsigned long recv_window;
@@ -1391,6 +1397,7 @@
             _libssh2_list_add(&handle->packet_list, &chunk->node);
             count -= size; /* deduct the size we used, as we might have
                               to create more packets */
+            _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "read request id %d sent", request_id);
         }
 
     case libssh2_NB_state_sent:
@@ -1475,7 +1482,7 @@
 
                 if (rc32 == LIBSSH2_FX_EOF) {
                     filep->eof = TRUE;
-                    return 0;
+                    return bytes_in_buffer;
                 }
                 else {
                     sftp->last_errno = rc32;
@@ -1505,13 +1512,13 @@
                     filep->offset_sent -= (chunk->len - rc32);
                 }
 
-                if(rc32 > buffer_size) {
+                if((bytes_in_buffer + rc32) > buffer_size) {
                     /* figure out the overlap amount */
-                    filep->data_left = rc32 - buffer_size;
+                    filep->data_left = (bytes_in_buffer + rc32) - buffer_size;
 
                     /* getting the full packet would overflow the buffer, so
                        only get the correct amount and keep the remainder */
-                    rc32 = (uint32_t)buffer_size;
+                    rc32 = (uint32_t)buffer_size - bytes_in_buffer;
 
                     /* store data to keep for next call */
                     filep->data = data;
@@ -1522,7 +1529,7 @@
 
                 /* copy the received data from the received FXP_DATA packet to
                    the buffer at the correct index */
-                memcpy(buffer, data + 9, rc32);
+                memcpy(sliding_bufferp, data + 9, rc32);
                 filep->offset += rc32;
 
                 if(filep->data_len == 0)
@@ -1538,8 +1545,10 @@
                 chunk = NULL;
 
                 if(rc32 > 0) {
-                    /* we must return as we wrote some data to the buffer */
-                    return rc32;
+                    /* continue to the next chunk */
+                    bytes_in_buffer += rc32;
+                    sliding_bufferp += rc32;
+                    chunk = next;
                 } else {
                     /* A zero-byte read is not necessarily EOF so we must not
                      * return 0 (that would signal EOF to the caller) so
@@ -1555,6 +1564,9 @@
             }
         }
 
+        if (bytes_in_buffer > 0)
+            return bytes_in_buffer;
+
         break;
 
     default:
@@ -1827,7 +1839,7 @@
            acked but we haven't been able to return as such yet, so we will
            get that data as well passed in here again.
         */
-        already = (handle->u.file.offset_sent - handle->u.file.offset)+
+        already = (size_t) (handle->u.file.offset_sent - handle->u.file.offset)+
             handle->u.file.acked;
 
         if(count >= already) {
@@ -2767,7 +2779,7 @@
     st->f_ffree = _libssh2_ntohu64(data + 53);
     st->f_favail = _libssh2_ntohu64(data + 61);
     st->f_fsid = _libssh2_ntohu64(data + 69);
-    flag = _libssh2_ntohu64(data + 77);
+    flag = (unsigned int)_libssh2_ntohu64(data + 77);
     st->f_namemax = _libssh2_ntohu64(data + 85);
 
     st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY)
@@ -2893,7 +2905,7 @@
     st->f_ffree = _libssh2_ntohu64(data + 53);
     st->f_favail = _libssh2_ntohu64(data + 61);
     st->f_fsid = _libssh2_ntohu64(data + 69);
-    flag = _libssh2_ntohu64(data + 77);
+    flag = (unsigned int)_libssh2_ntohu64(data + 77);
     st->f_namemax = _libssh2_ntohu64(data + 85);
 
     st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY)
diff --git a/src/sftp.h b/src/sftp.h
index 63e8139..b553b16 100644
--- a/src/sftp.h
+++ b/src/sftp.h
@@ -48,7 +48,7 @@
 /* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
  * packets.
  */
-#define MAX_SFTP_READ_SIZE 2000
+#define MAX_SFTP_READ_SIZE 30000
 
 struct sftp_pipeline_chunk {
     struct list_node node;