uploading with curl

Gleb s4mmael at gmail.com
Fri Apr 6 06:24:00 PDT 2012


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.

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!?

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 at 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?

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.


More information about the Digitalmars-d mailing list