summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2008-03-03 13:10:53 +0000
committerBenjamin Otte <otte@src.gnome.org>2008-03-03 13:10:53 +0000
commit05983f5fcadd7a32528e1733247a6351a2b12c3a (patch)
treeb21dfc9f777af95b3f26653ed75a25736f856310
parentb589c6044d5fb2d4635393cf3f431439042d410d (diff)
downloadgvfs-05983f5fcadd7a32528e1733247a6351a2b12c3a.tar.gz
dynamically resize the read buffer. This allows receiving the huge welcome
2008-03-03 Benjamin Otte <otte@gnome.org> * daemon/gvfsbackendftp.c: (ftp_connection_receive): dynamically resize the read buffer. This allows receiving the huge welcome messages some ftp servers think are cool. svn path=/trunk/; revision=1503
-rw-r--r--ChangeLog6
-rw-r--r--daemon/gvfsbackendftp.c47
2 files changed, 36 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 85fb11cd..5089ada9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2008-03-03 Benjamin Otte <otte@gnome.org>
+ * daemon/gvfsbackendftp.c: (ftp_connection_receive):
+ dynamically resize the read buffer. This allows receiving the huge
+ welcome messages some ftp servers think are cool.
+
+2008-03-03 Benjamin Otte <otte@gnome.org>
+
* daemon/gvfsbackendftp.c: (ftp_connection_parse_features),
(ftp_connection_use), (ftp_connection_ensure_data_connection):
implement EPSV. This should make IPv6 work.
diff --git a/daemon/gvfsbackendftp.c b/daemon/gvfsbackendftp.c
index 01909601..94d94327 100644
--- a/daemon/gvfsbackendftp.c
+++ b/daemon/gvfsbackendftp.c
@@ -108,7 +108,8 @@ struct _FtpConnection
FtpFeatures features;
SoupSocket * commands;
- gchar read_buffer[256];
+ gchar * read_buffer;
+ gsize read_buffer_size;
gsize read_bytes;
SoupSocket * data;
@@ -285,31 +286,55 @@ ftp_connection_receive (FtpConnection *conn,
DONE
} reply_state = FIRST_LINE;
guint response = 0;
- gsize bytes_left;
if (ftp_connection_in_error (conn))
return 0;
conn->read_bytes = 0;
- bytes_left = sizeof (conn->read_buffer) - conn->read_bytes - 1;
- while (reply_state != DONE && bytes_left >= 6)
+ while (reply_state != DONE)
{
+ DEBUG ("%u %u\n", conn->read_buffer_size, conn->read_bytes);
+ 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 (&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,
- bytes_left,
+ /* -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);
+
switch (status)
{
case SOUP_SOCKET_OK:
case SOUP_SOCKET_EOF:
if (got_boundary)
break;
+ if (n_bytes > 0)
+ continue;
g_set_error (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Invalid reply"));
/* fall through */
@@ -322,11 +347,6 @@ ftp_connection_receive (FtpConnection *conn,
break;
}
- bytes_left -= n_bytes;
- conn->read_bytes += n_bytes;
- conn->read_buffer[conn->read_bytes] = 0;
- DEBUG ("<-- %s", last_line);
-
if (reply_state == FIRST_LINE)
{
if (n_bytes < 4 ||
@@ -361,13 +381,6 @@ ftp_connection_receive (FtpConnection *conn,
}
}
- if (reply_state != DONE)
- {
- g_set_error (&conn->error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Invalid reply"));
- return 0;
- }
-
switch (STATUS_GROUP (response))
{
case 0: