title: Recursively scan a Windows FTP server using PHP hangs midway... why?
body: <p>I needed to map a FTP server (running on Windows) using PHP, so I made a function that essentially navigates through the FTP's folder structure, listing everything inside it and calls itself recursively when it encounters a subfolder.</p>
  
  <p>Everything worked fine in my development environment, but things took a sour turn once I migrated everything to the client's infrastructure. Their FTP server holds 30GB of data (a lot of files, but not as many as you would expect, since many are > 100MB), so I was expecting it to be "slowish", but 90 to 120 seconds seemed a lot.</p>
  
  <p>Therefore, I did some investigating with tcpdump and it is perfectly visible that the FTP server has some kind of <strong>anti-flood protection</strong> because at a given point every request gets stalled for at least 60 seconds. This behavior <strong>also happens</strong> if I attempt to map the server recursively <strong>using lftp</strong>.</p>
  
  <p>I am currently using active mode because passive threw the following error:</p>
  
  <pre><code>Warning: ftp_rawlist() [function.ftp-rawlist]: php_connect_nonb() failed: Operation now in progress (115) in /home/user/public_html/sync.php on line 35
  </code></pre>
  
  <p>Line 35 refers to a ftp_rawlist of the current directory.</p>
  
  <p>I not really sure it'll help, but here's the code I'm using anyway:</p>
  
  <pre><code>function ftp_get_recursive_paths($conn, $path, $root, $max_level = 0) {
      $files = array();
      $contents = ftp_rawlist($conn, $path);
  
      if(is_array($contents)) {
          foreach($contents as $line) {
              (...) Parsing the results (...)
              if ((strpos($f, ".DS_Store") === false) &amp;&amp; (strpos($f, ".dropbox") === false) &amp;&amp; (strpos($f, "Thumbs.db") === false)) {
  
                  if(!strpos($f, '.')) {
                      $init = microtime(true);
                      $files[$f] = (object) array('name' =&gt; $f, 'date' =&gt; $date, 'path' =&gt; $path . $f, 'content' =&gt; ftp_get_recursive_paths($conn, $path . $f, $path));
                      $end = microtime(true);
                      echo '&lt;p&gt; Folder ' . $path . $f . ' scanned in '. ($end - $init), ' seconds. &lt;/p&gt;';
                  }
                  else {
                      $files[] = (object) array('name' =&gt; $f, 'date' =&gt; $date, 'path' =&gt; $path .  $f);
                  }
              }
          }
      }
  
      return $files;
  }
  </code></pre>
  
  <p>Does anyone know how this anti-flood thing can be prevented? Is it a firewall? Some kind of configuration in the client's server?</p>
  
  <p>I can confirm that the client is using Filezilla Server on Windows.</p>