TVA van Hesteren
TVA van Hesteren

Reputation: 1251

C++ libcurl FTP upload over proxy not working

I have a c++ application, which has to upload files. When not on a proxy, the FTP-upload works great. However, when the client is uploading using a proxy, LibCurl fails to build a good request. At least, I don't know how to give it the right information. Of course I tell LibCurl the proxy-address, which works great with HTTP-requests. However, the FTP-upload fails. The code I'm using:

struct curl_slist *LibcurlHeaders = NULL;
curl = curl_easy_init();
string ProxyAddress = "ProxyURL";
string JSONFileName = "dataonserver.json";
FILE* JSONFile = fopen("data.json", "rb");
if (curl) {
     CurlResponse = "";
     host = "ftp://host.com/" + JSONFileName;
     if (ProxyAddress.length() > 0) {
          curl_easy_setopt(curl, CURLOPT_PROXY, ProxyAddress.c_str());
          }
     curl_easy_setopt(curl, CURLOPT_URL, host.c_str());
     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , 1);
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 1);
     LibcurlHeaders = curl_slist_append(LibcurlHeaders, "Expect:");
     curl_easy_setopt(curl, CURLOPT_USERPWD, (FTPUsername + ":" + FTPPassword).c_str());
     curl_easy_setopt(curl, CURLOPT_CAINFO, FilePathSSLCertificate.c_str());
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, LibcurlHeaders);
     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
     curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
     curl_easy_setopt(curl, CURLOPT_READDATA, JSONFile);
     res = curl_easy_perform(curl);
     if (res != CURLE_OK) {
          LibcurlError(curl_easy_strerror(res), host);
          }
     curl_slist_free_all(LibcurlHeaders);
     curl_easy_cleanup(curl);
     }
fclose(JSONFile);

The response I get:

* timeout on name lookup is not supported
*   Trying host IP...
* TCP_NODELAY set
* Connected to host (host IP) port 21 (#0)
* Server auth using Basic with user '[email protected]'
> PUT ftp://[email protected]:[email protected]/FileName HTTP/1.1
Host: domain.com:21
Authorization: Basic Q2xpZW50VXBsb2FkQGdvZmlsZXIub3JnOkNsaWVudFVwbG9hZDE=
Accept: */*
Proxy-Connection: Keep-Alive
Transfer-Encoding: chunked

220-  This is the xxxx FTP proxy server.
220-  My external IP address is xxxx and I have
220-  a backup ftp proxy in xxxx. When setting up
220-  access to 3rd parties, be sure to allow both source
220-  addresses.
220-
220-  All requests will come from one of the sources IP's below:
220-   xxxxx (xxx Proxy)
220-   xxxxx (xxx Proxy)
220-
220-  To connect to a site:
220-
220-  Enter the username and site name at the User: prompt.
220-  For example, to log into ftp.uu.net as anonymous, you
220-  would give [email protected] at the User: prompt.
220-  Enter the site password at the Password: prompt.
220-  If you are connecting as anonymous, give your email address.
220-
220   Type quit to disconnect.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.
500 Syntax error, command unrecognized.

Upvotes: 0

Views: 821

Answers (1)

Daniel Stenberg
Daniel Stenberg

Reputation: 58094

You can normally only do FTP uploads over a HTTP proxy by "tunneling through" it. You ask libcurl to do this by setting the CURLOPT_HTTPPROXYTUNNEL option.

Without that option set, libcurl will convert your FTP upload to a HTTP PUT over the proxy.

With that option set, libcurl will issue a CONNECT to the proxy and ask for a tunnel to the destination server and then issue "ordinary FTP" commands to the server. Do note however that many HTTP proxies are not set up to allow CONNECT through proxies to other ports than 443 or perhaps a few more. Port 21 that is needed for a typical FTP transfer is rarely accepted.

Upvotes: 1

Related Questions