gvfs r2238 - in trunk: . daemon



Author: otte
Date: Thu Feb 19 15:54:57 2009
New Revision: 2238
URL: http://svn.gnome.org/viewvc/gvfs?rev=2238&view=rev

Log:
2009-02-19  Benjamin Otte  <otte gnome org>

	reviewed by: Andreas Henriksson <andreas fatal se>

	Bug 525283 - handle short reads in ftp

	* daemon/gvfsbackendftp.c: (ftp_connection_receive):
	account for cases where soup_socket_read_until() would not read up to
	the boundary on the first read.



Modified:
   trunk/ChangeLog
   trunk/daemon/gvfsbackendftp.c

Modified: trunk/daemon/gvfsbackendftp.c
==============================================================================
--- trunk/daemon/gvfsbackendftp.c	(original)
+++ trunk/daemon/gvfsbackendftp.c	Thu Feb 19 15:54:57 2009
@@ -364,58 +364,56 @@
   conn->read_bytes = 0;
   while (reply_state != DONE)
     {
-      if (conn->read_buffer_size - conn->read_bytes < 128)
-	{
-	  gsize new_size = conn->read_buffer_size + 1024;
-	  /* FIXME: upper limit for size? */
-	  gchar *new = g_try_realloc (conn->read_buffer, new_size);
-	  if (new)
-	    {
-	      conn->read_buffer = new;
-	      conn->read_buffer_size = new_size;
-	    }
-	  else
-	    {
-	      g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED,
-				   _("Invalid reply"));
-	      return 0;
-	    }
-	}
       last_line = conn->read_buffer + conn->read_bytes;
-      status = soup_socket_read_until (conn->commands,
-				       last_line,
-				       /* -1 byte for nul-termination */
-				       conn->read_buffer_size - conn->read_bytes - 1,
-				       "\r\n",
-				       2,
-				       &n_bytes,
-				       &got_boundary,
-				       conn->job->cancellable,
-				       &conn->error);
-
-      conn->read_bytes += n_bytes;
-      conn->read_buffer[conn->read_bytes] = 0;
-      DEBUG ("<-- %s", last_line);
+      do {
+        /* the available size must at least allow for boundary size (2)
+         * bytes to be available for reading */
+        if (conn->read_buffer_size - conn->read_bytes < 128)
+          {
+            gsize new_size = conn->read_buffer_size + 1024;
+            /* FIXME: upper limit for size? */
+            gchar *new = g_try_realloc (conn->read_buffer, new_size);
+            if (new)
+              {
+                /* make last line relative to new allocation */
+                last_line = new + (last_line - conn->read_buffer);
+                conn->read_buffer = new;
+                conn->read_buffer_size = new_size;
+              }
+            else
+              {
+                g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                     _("Invalid reply"));
+                return 0;
+              }
+          }
+        status = soup_socket_read_until (conn->commands,
+                                         conn->read_buffer + conn->read_bytes,
+                                         /* -1 byte for nul-termination */
+                                         conn->read_buffer_size - conn->read_bytes - 1,
+                                         "\r\n",
+                                         2,
+                                         &n_bytes,
+                                         &got_boundary,
+                                         conn->job->cancellable,
+                                         &conn->error);
+
+        conn->read_bytes += n_bytes;
+        conn->read_buffer[conn->read_bytes] = 0;
+
+        g_assert (status != SOUP_SOCKET_WOULD_BLOCK);
+        if (status == SOUP_SOCKET_ERROR)
+          return 0;
 
-      switch (status)
-	{
-	  case SOUP_SOCKET_OK:
-	  case SOUP_SOCKET_EOF:
-	    if (got_boundary)
-	      break;
-	    if (n_bytes > 0)
-	      continue;
+        if (n_bytes == 0)
+          {
 	    g_set_error_literal (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED,
 				 _("Invalid reply"));
-	    /* fall through */
-	  case SOUP_SOCKET_ERROR:
-	    conn->read_buffer[conn->read_bytes] = 0;
-	    return 0;
-	  case SOUP_SOCKET_WOULD_BLOCK:
-	  default:
-	    g_assert_not_reached ();
-	    break;
-	}
+            return 0;
+          }
+      } while (!got_boundary);
+
+      DEBUG ("<-- %s", last_line);
 
       if (reply_state == FIRST_LINE)
 	{



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]