Answers below:

On Friday, 6 April 2012 at 13:24:03 UTC, Gleb wrote:
Hello guys,

I'm trying to use curl library to satisfy my file transfer needs
under Windows 7. I've spent all the day and the most of
functionality I have already tried works like a charm. But I have
a few issues with "upload" function.

First of all, if I try to use something like:
   auto client = FTP("192.168.110.58");
or:
   upload!FTP("file.zip", "192.168.110.58");
curl wrapper does not understand we are trying to use
ftp-protocol and uses http instead, returning something like:
   <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
   <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en"
lang="en">
    <head>
     <title>400 - Bad Request</title>
    </head>
    <body>
     <h1>400 - Bad Request</h1>
    </body>
   </html>
Not a big deal, I'll use "ftp://xx.xx.xx.xx"; format everywhere
below.

This is not how it should be. Github url with fixes below...

Here is the code I'm trying to use to upload a local file to the
ftp-host with an authentication:
   auto client = FTP();
   client.setAuthentication("login", "pass");
   upload!FTP("file.zip", "ftp://192.168.110.58/file.zip";,
client);
This will pass the authentication but won't upload the file.

Then I decided to take a look to the code of std.net.curl.upload
function and use a low-level API the same way to find the
solution. Here is what I got:
auto f = new std.stream.BufferedFile("file.zip", FileMode.In);
   scope (exit) f.close();
   auto client = FTP("ftp://192.168.110.58";);
   client.verbose(true);
   client.setAuthentication("login", "pass");
   client.onSend = (void[] data)
   {
      return f.read(cast(ubyte[])data);
   };
   client.contentLength = cast(size_t)f.size;
   client.perform();
It's basically the same as "upload" function. This authenticates
correctly, gets directory listing and then nothing happens:
   * Connection #0 to host 192.168.110.58 left intact
   > QUIT
   < 221 Goodbye.
   * Closing connection #0
And it looks correct for me, why should it upload any file!?

I can reproduce this and included the fix for it.

So I decided to replace the last line of the code with the
following:
   client.addCommand("epsv");
   client.addCommand("stor file.zip");
   client.perform();
Here are the results:
   > epsv
   < 229 Entering Extended Passive Mode (|||12761|)
   > stor file.zip
   * FTP response timeout
   * Connection #0 to host 192.168.110.58 left intact
   * Timeout was reached
   > QUIT
   * server response timeout
   * Closing connection #0
   std.net.curl.CurlTimeoutException@std\net\curl.d(3333):
6B2BD8C6 on handle 166CB60
This way the file was created on the server, but it's empty. It
looks like client.onSend statements are never executed.
Unfortunately, I didn't managed to find out why, it's somewhere
in object "private RefCounted!Impl p" (curl.d:1956), but I didn't
find where it is.

So, what am I doing wrong? Does std.net.curl.upload work for you
correctly? How do I upload a file to the ftp-host with
authentication? What is "RefCounted!Impl p" and where do I find
it's "p.curl.perform()" method?

RefCount!Impl p is a reference counted struct Impl defined above the declaration in the source file.

The p.curl is an instance of the Curl struct defined later in the source file. That struct has a perform() method.

P.S.: Firewall is not the case, other ftp clients and
std.net.curl.download function work fine, rules for the program
are created (just in case).

Thank you in advance, any advice is really appreciated.

You have identified a couple of bugs. A corrected version of curl.d is located at https://github.com/jcd/phobos/blob/curlfixes/std/net/curl.d

I've created a pull requests to get it upstream.

/Jonas


Reply via email to