cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: 421 I can't accept more than 5 connections as the same user

From: Stefano D. Mtangoo <mwinjilisti_at_gmail.com>
Date: Tue, 31 Dec 2013 19:18:25 +0300

On 31/12/2013 06:32 alasiri, curl-library-request_at_cool.haxx.se wrote:
>
> /> I get this error and I fail to recreate directory structure on ftp
> as I try /
> /> to upload directory. /
>
> ... and you're saying you aren't connecting to the server with more
> than 5
> connections using the same user?
>
What I mean is, It terminates before it finishes recreating the
directory tree
>
> /> I have tried to limit CURLMOPT_MAXCONNECTS, 1 and even I tried /
> /> CURLOPT_MAXCONNECTS to 1 tried both, but did not work. Is there
> anything /
> /> else I can do? /
>
> You need to explain more about what you're trying to do and what's
> actually
Ok, sorry for not expaining. Here is what I want to do actually.
I want to upload directory to FTP server. I do that using a thread
(wxThread)
In that method, I get path and traverse thru dirs and subdir and all
files in them.
For each path (file or dir) I call the function to Queue them in multi
interface.
Once traversing is done I call function that does actual uploading (both
functions are shown below)

> happening. Why do you connect multiple times to the same server at all?
I do not understand why either. see the functions below and see if there
is anything
I'm doing wrong, please help me. I'm new to multi and so I might be wrong
I have uploaded the same code on http://pastebin.com/P5PJyGyA

void Uploader::QueueUpload(const wxString& path, bool isFile, const
wxString& localpath)
{
     curl_multi_setopt(m_curlMultiHandle, CURLMOPT_MAXCONNECTS,
1);//TODO: Set from Config

     wxString url;
     if(!isFile && !path.EndsWith("/"))
     {
         //dirs should end with /
         url = m_ftpOptionsStr[CURLOPT_URL]+path+"/";
     }
     else
     {
         url = m_ftpOptionsStr[CURLOPT_URL]+path;
     }

     const char* urlCstr = url.c_str();

     CURL* handle = curl_easy_init();
     SetHandleOptions(handle);
     curl_easy_setopt(handle, CURLOPT_URL, urlCstr);
     curl_easy_setopt(handle, CURLOPT_FTP_FILEMETHOD,
CURLFTPMETHOD_MULTICWD);
     curl_easy_setopt(handle, CURLOPT_FTP_CREATE_MISSING_DIRS,
CURLFTP_CREATE_DIR);

     FileReader* reader = new FileReader();
     reader->SetUploader(this);

     if(isFile)
     {
         struct stat file_info;
         FILE *fd;

         //open file and read it
         const char* fileCstr = localpath.c_str();
         fd = fopen(fileCstr, "rb"); /* open file to upload */
         if(!fd)
         {
             /* can't continue */
             SendMessage(_("Cannot Open File\n %s\nUpload
Terminated!")+localpath);
             return ;
         }

         /* to get the file size */
         if(fstat(fileno(fd), &file_info) != 0)
         {
             /* can't continue */
             SendMessage(_("Cannot Get File size\n %s\nUpload
Terminated!")+localpath);
             return ;
         }

         //set file to read
         reader->SetFile(fd);

         //save handle in vector
         m_fileHandles.push_back(reader);

         //do file upload here
         curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
         /* and give the size of the upload (optional) */
         curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
         /* set where to read from (on Windows you need to use
READFUNCTION too) */
         curl_easy_setopt(handle, CURLOPT_READFUNCTION,
Uploader::ReadCallback);
         curl_easy_setopt(handle, CURLOPT_READDATA, (void*)reader);

     }
     else
     {
         //its dir, just run MKD indirectly via CWD
         curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,
Uploader::WriteDataCallBack);
         curl_easy_setopt(handle, CURLOPT_WRITEDATA, reader);
     }
     //Queue it to multi handle
     curl_multi_add_handle(m_curlMultiHandle, handle);
}

void Uploader::UploadQueue()
{
     int still_running;

     CURLMsg* msg; /* for picking up messages with the transfer status */
     int msgs_left; /* how many messages are left */

     /* we start some action by calling perform right away */
     curl_multi_perform(m_curlMultiHandle, &still_running);

     do
     {
         struct timeval timeout;
         int rc; /* select() return code */

         fd_set fdread;
         fd_set fdwrite;
         fd_set fdexcep;
         int maxfd = -1;

         long curl_timeo = -1;

         FD_ZERO(&fdread);
         FD_ZERO(&fdwrite);
         FD_ZERO(&fdexcep);

         /* set a suitable timeout to play around with */
         timeout.tv_sec = 1;
         timeout.tv_usec = 0;

         curl_multi_timeout(m_curlMultiHandle, &curl_timeo);
         if(curl_timeo >= 0)
         {
             timeout.tv_sec = curl_timeo / 1000;
             if(timeout.tv_sec > 1)
                 timeout.tv_sec = 1;
             else
                 timeout.tv_usec = (curl_timeo % 1000) * 1000;
         }

         /* get file descriptors from the transfers */
         curl_multi_fdset(m_curlMultiHandle, &fdread, &fdwrite,
&fdexcep, &maxfd);

         /* In a real-world program you OF COURSE check the return code
of the
            function calls. On success, the value of maxfd is
guaranteed to be
            greater or equal than -1. We call select(maxfd + 1, ...),
specially in
            case of (maxfd == -1), we call select(0, ...), which is
basically equal
            to sleep. */

         rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

         switch(rc)
         {
             case -1:
                 /* select error */
                 break;
             case 0:
             default:
                 /* timeout or readable/writable sockets */
                 curl_multi_perform(m_curlMultiHandle, &still_running);
                 break;
         }
     }
     while(still_running);

     curl_multi_cleanup(m_curlMultiHandle);

     /* See how the transfers went */
     while ((msg = curl_multi_info_read(m_curlMultiHandle, &msgs_left)))
     {
         if (msg->msg == CURLMSG_DONE)
         {
             SendMessage(wxString::Format(_("FTP transfer completed with
status: %d: %s"), (int)msg->data.result,
curl_easy_strerror(msg->data.result)));
             curl_easy_cleanup(msg->easy_handle);
         }
     }

     //clean files and all other stuffs
     for(int i=0; i<m_fileHandles.size(); i++)
     {
         fclose(m_fileHandles.at(i)->GetFile());
         delete m_fileHandles.at(i);
     }
     //clear the data structures
     m_fileHandles.clear();
}

-- 
Stefano D. Mtangoo
Mob: +255 754710410
Twitter: @mtangoo
Web. http://hosannahighertech.co.tz
Linkedin: http://www.linkedin.com/pub/stefano-mtangoo/45/644/281
/The purpose of man is to know his Maker Be known by his Maker
And make his Maker known So that others may know his Maker as their 
Maker(Emeal Zwayne) /

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-12-31