-----Original Message-----
From: Patrik Thunström [mailto:[email protected]] 
Sent: den 18 november 2011 16:43
To: 'libssh2 development'
Subject: RE: Libssh2 usage from cURL with various buffer sizes.

> I'll get back once I've made a test driver!

I sadly have to admit defeat with this task. I've tried to recreate the bug
in a standalone test driver, but without any success.
This is a bit odd, seeing as we're able to log each and every call that go
out through libcURL, but even so recreating every step of the way, no
success.

This leads me to believe that it might be somehow related to compiler flags
(which I also tried to set up in a similar manner as our sharp product), or
something related to differences between building and/or running things as
standalone executables compared to dynamic libraries, as we usually are
loading the libcURL dll, through a wrapper dll to maintain both forwards and
backwards compatibility.

I still do have the same setup as earlier available, so I can still run the
same test in our environment, even though this is not the best solution. :/

What I did manage to get out of this was a small test driver for testing
file transfer iterations of the same file, which would be quite similar to
running our small files test multiple times (as that was what I was trying
to recreate with the test driver). It starts out by uploading a file to the
SFTP and then downloads it a definable number of times over a set number of
iterations.

No rocket science, needs to get include path to and be linked to your choice
of libcURL. I believe I've made it as platform independent as possible, but
there still might be something that's windows specific.

Oh well. Signing out for now. Have a nice weekend!
Best regards
Patrik Thunström / [email protected]
#include "curl/curl.h"

#define TRANSFER_DIRECTION_DOWNLOAD 0
#define TRANSFER_DIRECTION_UPLOAD 1
int transferDirection;

CURL *pConn = NULL;
char currentHost[200];

size_t transferFunction(void *ptr, size_t size, size_t nmemb, void *stream) {
        FILE *filePtr = (FILE*)stream;
        size_t bytesWritten = 0;

        if(transferDirection == TRANSFER_DIRECTION_DOWNLOAD) bytesWritten = 
fwrite(ptr, size, nmemb, filePtr);
        else if(transferDirection == TRANSFER_DIRECTION_UPLOAD) bytesWritten = 
fread(ptr, size, nmemb, filePtr);

        return bytesWritten;
}

CURLcode SetOption(CURL *conn, CURLoption option, char *value) {
        CURLcode result;

        result = curl_easy_setopt(conn, option, value);

        if(result != CURLE_OK) {
                printf("curl_easy_setopt returned with error code: %d. Option 
to set: %d.", result, option);
                printf("Error description: %s", curl_easy_strerror(result));
        }

        return result;
}

int Connect(char *userhost, char *user,
                                char *password, int portnumber) {
        CURLcode result;
        char connectString[300];
        int authMode = CURLSSH_AUTH_NONE;


        pConn = curl_easy_init();
        if(!pConn) {
                return FALSE;
        }
        sprintf(connectString, "sftp://%s:%d/";, userhost, portnumber);

        // Set options for the connection before connecting.
        SetOption(pConn, CURLOPT_URL, connectString);
        SetOption(pConn, CURLOPT_USERNAME, user);
        if(password && *password) {
                SetOption(pConn, CURLOPT_PASSWORD, password);
                authMode |= CURLSSH_AUTH_PASSWORD;
                authMode |= CURLSSH_AUTH_KEYBOARD;
        }
        SetOption(pConn, CURLOPT_SSH_AUTH_TYPES, (char*)authMode);

        // Tell curl not to report progress
        SetOption(pConn, CURLOPT_NOPROGRESS, (char*)TRUE);

        // Setup timeouts
        SetOption(pConn, CURLOPT_CONNECTTIMEOUT, (char*)60);
        SetOption(pConn, CURLOPT_FTP_RESPONSE_TIMEOUT, (char*)60);

        SetOption(pConn, CURLOPT_TCP_NODELAY, (char*)TRUE);
        SetOption(pConn, CURLOPT_NOBODY, (char*)TRUE);

        result = curl_easy_perform(pConn);
        if(result == CURLE_OK) {
                sprintf(currentHost, "sftp://%s:%d";, userhost, portnumber);
                return TRUE;
        }
        else {
                curl_easy_cleanup(pConn);
                pConn = NULL;
        }

        if(pConn)
                return TRUE;

        return FALSE;
}

BOOL transferFile(char *source, char *target, int direction) {
        CURLcode result;
        FILE *file;
        char *escapedUrl;
        char urlString[1000];

        if(!pConn)
                return FALSE;

        // Set options depending on transfer direction
        if(direction == TRANSFER_DIRECTION_DOWNLOAD) {
                file = fopen(target,"w");
                SetOption(pConn, CURLOPT_WRITEFUNCTION, 
(char*)&transferFunction);
                SetOption(pConn, CURLOPT_WRITEDATA, (char*)file);

                escapedUrl = curl_escape(source, 0);
        }
        else if(direction == TRANSFER_DIRECTION_UPLOAD) {
                file = fopen(source, "r");
                SetOption(pConn, CURLOPT_READFUNCTION, 
(char*)&transferFunction);
                SetOption(pConn, CURLOPT_READDATA, (char*)file);
                SetOption(pConn, CURLOPT_UPLOAD, (char*)TRUE);

                escapedUrl = curl_escape(target, 0);
        }
        else
                return FALSE;

        // Validate the file handle
        if(file == NULL) {
                printf("File transfer failed. Could not open file %s for %s.", 
direction == TRANSFER_DIRECTION_UPLOAD ? target : source, transferDirection == 
TRANSFER_DIRECTION_UPLOAD ? "reading" : "writing");
                return FALSE;
        }

        transferDirection = direction;

        // Use the escaped URL to set the curl uption
        sprintf(urlString, "%s/%s", currentHost, escapedUrl);
        curl_free(escapedUrl);
        SetOption(pConn, CURLOPT_URL, urlString);

        // Set the common options
        SetOption(pConn, CURLOPT_NOBODY, (char*)FALSE);

        result = curl_easy_perform(pConn);

        // Reset options depending on transfer direction
        if(direction == TRANSFER_DIRECTION_DOWNLOAD) {
                SetOption(pConn, CURLOPT_WRITEFUNCTION, NULL);
                SetOption(pConn, CURLOPT_WRITEDATA, NULL);
        }
        else {
                SetOption(pConn, CURLOPT_READFUNCTION, NULL);
                SetOption(pConn, CURLOPT_READDATA, NULL);
                SetOption(pConn, CURLOPT_UPLOAD, (char*)FALSE);
        }

        fclose(file);

        if(result != CURLE_OK) {
                printf("File transfer failed with error code: %d. Error 
description: %s", result, curl_easy_strerror(result));
                return FALSE;
        }

        return TRUE;
}

#define REMOTE_FILEPATH "home/teste/testfile.dat"

void UploadFile() {
        transferFile("testfile.dat", REMOTE_FILEPATH, 
TRANSFER_DIRECTION_UPLOAD);
}

void TransferFileset(int numIterations, int numFiles) {
        int i, j;
        time_t startTime, endTime;
        for(i = 0; i < numIterations; i++) {
                printf("Current iteration: %d. ", i + 1);
                // Clock in
                startTime = time(NULL);
                for(j = 0; j < numFiles; j++) {
                        if(!transferFile(REMOTE_FILEPATH, "tmpfile.down", 
TRANSFER_DIRECTION_DOWNLOAD)) {
                                printf("Transfer batch failed. Aborting.");
                                return;
                        }
                }
                // Clock out, print
                endTime = time(NULL);
                printf("Used time: %d.\n", endTime - startTime);
        }
}

int main(int argc, char **argv) {
        curl_global_init(CURL_GLOBAL_ALL);
        //      host,          username, password, port
        Connect("10.10.24.14", "teste", "tuster", 22);
        UploadFile();
        //              Iterations, Files per iteration
        TransferFileset(10, 2000);

        return 1;
}
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to