Question

I'm sending HTTP POST commands to an external device using libCURL library. I have two basic commands. The first tells the device to wipe current content on the device, and the second sends new content. I use identical POST header structures/addresses for both, with the only difference being the attachment of the data during the "send content" command. Both commands execute properly: the first wipes the data, the second sends. HOWEVER, the program infrequently (~30% of the time) crashes after the "send content" command. No error is given. As I said before, it does not crash until the data is sent, and it does not happen all the time which makes it particularly maddening.

The code is attached below. Is there something I'm missing after sending the content which the program needs to consisently exit from the 'curl_easy_perform(curl)' action? I'm still fairly inexperienced with this type of thing and am open to any advice you may have.

int fnSendContent(BMP* pbmpContent)
{
    using namespace std;
    int Error = 0;

    CURL* curl;
    CURLcode res;
    struct curl_slist *headerlist=NULL;
    static const char buf[] = "aaaaaaaaa";
    CString str;
    string sURL;
    long lTimeout = 10;

    //Pass image into char array so that it can be sent to VIP
    ifstream fsContent;
    fsContent.open("MyImage.bmp",ios_base::binary);

    fsContent.seekg(0,ios::end);
    long lBMP_size = fsContent.tellg();
    fsContent.seekg(0,ios::beg);

    char* pcContent = new char[lBMP_size];
    for (int i = 0; i < lBMP_size; i++)
        pcContent[i] = 'F';
    bool bit = fsContent.eof();

    fsContent.read(pcContent,lBMP_size);
    fsContent.close();

    string Content_Length = "Content-Length: " + to_string((long long)lBMP_size);
    curl_global_init(CURL_GLOBAL_ALL);

    curl = curl_easy_init();

    //Build header
    headerlist = curl_slist_append(headerlist, buf);
    headerlist = curl_slist_append(headerlist, "Authorization: MyAuth);
    headerlist = curl_slist_append(headerlist, "Accept: MyAccept");
    headerlist = curl_slist_append(headerlist, "Content-Type: image/bmp");
    headerlist = curl_slist_append(headerlist, "Connection: keep-alive");
    headerlist = curl_slist_append(headerlist, Content_Length.c_str());
    headerlist = curl_slist_append(headerlist, "Expect: "); //Supress "Expect:" heading

    //Set URL to receive POST
    curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
    curl_easy_setopt(curl,CURLOPT_POST, true);
    curl_easy_setopt(curl, CURLOPT_HEADER, true);
    curl_easy_setopt(curl,CURLOPT_TIMEOUT, lTimeout);
    curl_easy_setopt(curl, CURLOPT_URL, "http://URL:Port/Command");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, lBMP_size);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pcContent);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);

    //Send
    res = curl_easy_perform(curl); //Crash occurs on send
    CString str2(curl_easy_strerror(res));//Get Error Explanation

    if(res != CURLE_OK)
    {
        str2.Format(_T("curl_easy_perform() failed: %s [%d]"), str2,res);
        DebugOut->AddString(str2);
        Error = E_SHOW_IMG;
    }

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    curl_slist_free_all(headerlist);

    delete[] pcContent;

    return Error;
}

EDIT: Daniel requested more info:

The crash occurs after I have sent the header and data using through "curl_easy_perform(curl)" but prior to its successful return to the rest of the program. I am coding in VC++ and only receive the generic "An error has occured". The fact that the error occurs after the data is received makes me think I'm not terminating the command properly. A WireShark printout of a POST command which crashes is given below.

    Source     Destination  Protocol  Length       Info
  ------------------------------------------------------------
  |MySourceIP  | MyDestIP |   HTTP  | 16438  |  POST /Command|
  ------------------------------------------------------------

POST /Command HTTP/1.1..Host: URL:Port..Authorization: My Auth..Content-Type:
image/bmp..Accept: MyAccept..Connection: keep-alive..Content-Length: 61
494....BM6.......6...(..........

[Followed by 61,494 bytes of data ending in null]
Était-ce utile?

La solution

The CURLOPT_POSTFIELDSIZE_LARGE option takes a 'curl_off_t' argument but you pass in a 'long'.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top