Robson Braga Araujo filed bug report #1776235
authorDaniel Stenberg <daniel@haxx.se>
Fri, 17 Aug 2007 22:22:43 +0000 (22:22 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 17 Aug 2007 22:22:43 +0000 (22:22 +0000)
(http://curl.haxx.se/bug/view.cgi?id=1776235) about ftp requests with NOBODY
on a directory would do a "SIZE (null)" request. This is now fixed and test
case 1000 was added to verify.

CHANGES
RELEASE-NOTES
lib/ftp.c
tests/data/Makefile.am
tests/data/test1000 [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 2ecec5b..632d538 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@
 
                                   Changelog
 
+Daniel S (18 August 2007)
+- Robson Braga Araujo filed bug report #1776235
+  (http://curl.haxx.se/bug/view.cgi?id=1776235) about ftp requests with NOBODY
+  on a directory would do a "SIZE (null)" request. This is now fixed and test
+  case 1000 was added to verify.
+
 Daniel S (17 August 2007)
 - Song Ma provided a patch that cures a problem libcurl has when doing resume
   HTTP PUT using Digest authentication. Test case 5320 and 5322 were also
index 85fb3ef..0f70afe 100644 (file)
@@ -41,6 +41,7 @@ This release includes the following bugfixes:
  o memory leak when handling compressed data streams from broken servers
  o no NTLM unicode response
  o resume HTTP PUT using Digest authentication
+ o FTP NOBODY requests on directories sent "SIZE (null)"
 
 This release includes the following known bugs:
 
@@ -64,6 +65,6 @@ advice from friends like these:
  Daniel Cater, Colin Hogben, Jofell Gallardo, Daniel Johnson,
  Ralf S. Engelschall, James Housley, Chris Flerackers, Patrick Monnerat,
  Jayesh A Shah, Greg Zavertnik, Peter O'Gorman, Greg Morse, Dmitriy Sergeyev,
- Scott Cantor, Allen Pulsifer, Andrew Wansink
+ Scott Cantor, Allen Pulsifer, Andrew Wansink, Robson Braga Araujo
  
         Thanks! (and sorry if I forgot to mention someone)
index 6958eb7..9301b55 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -140,6 +140,19 @@ static int ftp_need_type(struct connectdata *conn,
 #define NBFTPSENDF(x,y,z)  if ((result = Curl_nbftpsendf(x,y,z)) != CURLE_OK) \
                               return result
 
+
+/*
+ * NOTE: back in the old days, we added code in the FTP code that made NOBODY
+ * requests on files respond with headers passed to the client/stdout that
+ * looked like HTTP ones.
+ *
+ * This approach is not very elegant, it causes confusion and is error-prone.
+ * It is subject for removal at the next (or at least a future) soname bump.
+ * Until then you can test the effects of the removal by undefining the
+ * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ */
+#define CURL_FTP_HTTPSTYLE_HEAD 1
+
 static void freedirs(struct connectdata *conn)
 {
   struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -1303,8 +1316,8 @@ static CURLcode ftp_state_post_size(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct FTP *ftp = conn->data->reqdata.proto.ftp;
 
-  if(ftp->no_transfer) {
-    /* if a "head"-like request is being made */
+  if(ftp->no_transfer && ftp->file) {
+    /* if a "head"-like request is being made (on a file) */
 
     /* Determine if server can respond to REST command and therefore
        whether it supports range */
@@ -1323,8 +1336,8 @@ static CURLcode ftp_state_post_type(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   struct FTP *ftp = conn->data->reqdata.proto.ftp;
 
-  if(ftp->no_transfer) {
-    /* if a "head"-like request is being made */
+  if(ftp->no_transfer && ftp->file) {
+    /* if a "head"-like request is being made (on a file) */
 
     /* we know ftp->file is a valid pointer to a file name */
     NBFTPSENDF(conn, "SIZE %s", ftp->file);
@@ -1898,6 +1911,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
         data->info.filetime = (long)curl_getdate(buf, &secs);
       }
 
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
       /* If we asked for a time of the file and we actually got one as well,
          we "emulate" a HTTP-style header in our output. */
 
@@ -1928,6 +1942,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
         if(result)
           return result;
       } /* end of a ridiculous amount of conditionals */
+#endif
     }
     break;
   default:
@@ -2096,6 +2111,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
   filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1;
 
   if(instate == FTP_SIZE) {
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
     if(-1 != filesize) {
       snprintf(buf, sizeof(data->state.buffer),
                "Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
@@ -2103,6 +2119,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
       if(result)
         return result;
     }
+#endif
     result = ftp_state_post_size(conn);
   }
   else if(instate == FTP_RETR_SIZE)
@@ -2125,13 +2142,14 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
   switch(instate) {
   case FTP_REST:
   default:
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
     if (ftpcode == 350) {
       result = Curl_client_write(conn, CLIENTWRITE_BOTH,
                                (char *)"Accept-ranges: bytes\r\n", 0);
       if(result)
         return result;
     }
-
+#endif
     result = ftp_state_post_rest(conn);
     break;
 
index aa396a2..2674c03 100644 (file)
@@ -43,4 +43,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46           \
  test296 test297 test298 test610 test611 test612 test406 test407 test408   \
  test409 test613 test614 test700 test701 test702 test704 test705 test703   \
  test706 test707 test350 test351 test352 test353 test289 test540 test354   \
- test231 test1001 test1002
+ test231 test1000 test1001 test1002
diff --git a/tests/data/test1000 b/tests/data/test1000
new file mode 100644 (file)
index 0000000..32d5c29
--- /dev/null
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+LIST
+NOBODY
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+# When doing LIST, we get the default list output hard-coded in the test
+# FTP server
+<datacheck>
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP dir list PASV with -I
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/1000/ -I
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous\r
+PASS ftp@example.com\r
+PWD\r
+CWD 1000\r
+QUIT\r
+</protocol>
+</verify>
+</testcase>