diff options
author | Benjamin Otte <otte@gnome.org> | 2008-03-03 13:10:53 +0000 |
---|---|---|
committer | Benjamin Otte <otte@src.gnome.org> | 2008-03-03 13:10:53 +0000 |
commit | 05983f5fcadd7a32528e1733247a6351a2b12c3a (patch) | |
tree | b21dfc9f777af95b3f26653ed75a25736f856310 | |
parent | b589c6044d5fb2d4635393cf3f431439042d410d (diff) | |
download | gvfs-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-- | ChangeLog | 6 | ||||
-rw-r--r-- | daemon/gvfsbackendftp.c | 47 |
2 files changed, 36 insertions, 17 deletions
@@ -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: |