uploading with curl

Jonas Drewsen jdrewsen at nospam.com
Sat Apr 7 13:14:40 PDT 2012


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

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




More information about the Digitalmars-d mailing list