C ++ libcurl, как отправить файл FTP с использованием STOR и REST - PullRequest
0 голосов
/ 10 октября 2018

У меня есть XML, который я хочу постепенно загружать на FTP-сервер.

Проблема в том, что он не работает для меня с APPEND, потому что я должен удалить окончательные метки.Например.

Файл на сервере

   < xml>< root>< a>ssss< /a>< b>kkkkk< /b>< /root>

Файл в локальной сети

   < xml>< root>< a>ssss< /a>< b>kkkkk< /b>< c>hhhhh< /c>< /root>

Мне нужно загрузить из ранее .

   < xml>< root>< a>ssss< /a>< b>kkkkk< /b>< /root>

   ----------------------------------------^

Мой код следующий

    size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
        curl_off_t nread;
        size_t retcode = fread(ptr, size, nmemb, (FILE*) stream);

        nread = (curl_off_t) retcode;

        fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T " bytes from file\n", nread);
        return retcode;
    }

    bool uploadFile(std::string urlFtp, std::string rutaFtp, std::string archivoOrigen, std::string userPassword, long posicion) {
        bool resultado = false;
        try {
            CURL *curl;
            CURLcode res;
            FILE *hd_src;
            struct stat file_info;
            curl_off_t fsize;

            /* get the file size of the local file */
            if (stat(archivoOrigen.c_str(), &file_info)) {
                LOGF_ERROR("Couldn't open '%s': %s\n", archivoOrigen.c_str(), strerror(errno));
                return false;
            }
            fsize = (curl_off_t) file_info.st_size;

            LOGF_INFO("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);

            hd_src = fopen(archivoOrigen.c_str(), "rb"); // get a FILE * of the same file

            curl_global_init(CURL_GLOBAL_ALL); // In windows, this will init the winsock stuff

            curl = curl_easy_init(); // get a curl handle
            if (curl) {
                // build a list of commands to pass to libcurl
                struct curl_slist *headerlist = NULL;
                std::string cadena(rutaFtp);

                curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); // we want to use our own read function
                curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); // enable uploading
                cadena = urlFtp;
                cadena.append(rutaFtp);
                curl_easy_setopt(curl, CURLOPT_URL, cadena.c_str()); // specify target
                curl_easy_setopt(curl, CURLOPT_USERPWD, userPassword.c_str());
                if (posicion > 0) {
                    curl_easy_setopt(curl, CURLOPT_RESUME_FROM, posicion);
                }
                curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); // now specify which file to upload
                curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) fsize);
                curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15L);

                curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); 

                res = curl_easy_perform(curl); // Now run off and do what you've been told!
                if (res != CURLE_OK)
                    LOGF_ERROR("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                else
                    resultado = true;

                curl_slist_free_all(headerlist); // clean up the FTP commands list

                curl_easy_cleanup(curl);
            }
            fclose(hd_src); // close the local file

            curl_global_cleanup();
        } catch (std::exception &e) {
            LOGF_ERROR(e.what());
        }

        return resultado;
    }

1 Ответ

0 голосов
/ 29 октября 2018

Мне не удалось решить проблему с CURL.Чтобы решить эту проблему, я создал класс в C ++, который выполняет загрузку.Я заметил документацию RFC rfc3659, стр. 13.

5.5.  REST Example

Assume that the transfer of a largish file has previously been
interrupted after 802816 octets had been received, that the previous
transfer was with TYPE=I, and that it has been verified that the file
on the server has not since changed.

  C> TYPE I
  S> 200 Type set to I.
  C> PORT 127,0,0,1,15,107
  S> 200 PORT command successful.
  C> REST 802816
  S> 350 Restarting at 802816. Send STORE or RETRIEVE
  C> RETR cap60.pl198.tar
  S> 150 Opening BINARY mode data connection
  [...]
  S> 226 Transfer complete.

Вместо того, чтобы ставить RETR, я поставил STOR, и он работает правильно.

...