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