2015-03-09 3 views
1

У меня есть программа, которая отправляет некоторые XML-данные, используя cURL через http to the cloud. Перед выполнением curl_easy_perform(), когда я печатаю эти данные на консоль, которые выглядят нормально, но на стороне приема xml поврежден, либо он усечен, либо искажен. Я не в состоянии выяснить причину, так как проблема прерывистыйcURL - Получение частичных данных о приемнике (400 плохих запросов)

XML отправлено:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><plugin><macAddress>08863B6CAEF8</macAddress><serialNumber>221212K01008A4</serialNumber><friendlyName>WeMo Switch</friendlyName><udnName>uuid:Socket-1_0-221212K01008A4</udnName><homeId>700511319</homeId><deviceType>Switch</deviceType><status>0</status><statusTS>1425892983</statusTS><firmwareVersion>WeMo_WW_2.00.8337.DVT-OWRT-SNS</firmwareVersion><fwUpgradeStatus>4</fwUpgradeStatus><signalStrength>96</signalStrength><attributeLists action="notify"><attribute><name>RuleAutoOffTime</name><value>0</value></attribute></attributeLists></plugin> 

На приемной стороне я получаю эту

tatusTS>1423077095</statusTS><firmwareVersion>WeMo_WW_2.00.7284.PVT</firmwareVersion><fwUpgradeStatus>4</fwUpgradeStatus><signalStrength>100</signalStrength><eventDuration>123</eventDuration><startTime>1378302633</startTime></plugin> 

Вот фрагмент кода, который несет из вышеуказанной задачи

//Actual data being sent is inData[] array in *pUsrAppData 

// user Application data 
typedef struct userAppData { 
    char url[SIZE_256B]; // url to which the session needs to be established 
    KeyValue keyVal[SIZE_32B]; // html content heaer specifying the key and value 
    int keyValLen;  //Number of pairs in keyValue 
    char inData[DATA_BUF_LEN]; // file path or data which needs to be sent 
    int inDataLength; // length of data which needs to be sent, if <=0 then indata contains file path 
        // or if it is >0 then it should contain length of data in indata 
    int inDataCount; /**This is added for thread access problem 400 and 500 bad request*/ 
    char *outData; // pointer to the data which is received in response from the server 
    //char outData[DATA_BUF_LEN]; // pointer to the data which is received in response from the server 
    int outDataLength; // data length of the out data 
    char outHeader[DATA_BUF_LEN]; // pointer to the header data which is received in response from the server 
    int outHeaderLength; // data length of the out header data 
    int httpsFlag; //Flag to identify https or http, should be set to 1 for https and 0 for http 
    int disableFlag; //Flag to identify whether error handling is to be enabled or disabled 
    int partNumber; //Specifies the current file part 
    char eTag[SIZE_4B][SIZE_128B]; // eTag for file uploads 
    char mac[KEY_BUF_LEN]; //max address used internally for posting transaction info for PUT case 
    char cookie_data[KEY_VAL_LEN]; 
    int outResp; //Response value in outHeader 
    int nStatusCode;  //HTTP Status Code 
}UserAppData; 


// user session data 
typedef struct userAppSessionData { 
    int sessionId; // id corresponding to the session created 
    CURL * curl; // pointer to curl SessionHandle structure 
}UserAppSessionData; 

typedef struct webSessionListNode{ 
    UserAppData *pUsrAppData; 
    UserAppSessionData *pUsrAppSsnData; 
}WebSessionListNode; 


    WebSessionListNode *pWebSsnListNode = NULL; 




    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_URL, pWebSsnListNode->pUsrAppData->url); 

    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_HTTPHEADER, slist); 



    /* specify we want to POST data */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_POST, 1L); 

    /* Write and header callback */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_HEADERFUNCTION, header_callback); 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_WRITEHEADER, pWebSsnListNode->pUsrAppSsnData); 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_WRITEFUNCTION, write_callback); 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_WRITEDATA, pWebSsnListNode->pUsrAppSsnData); 
    /* verbose debug output option */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_VERBOSE, 1L); 



    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_READFUNCTION, read_callback); 
    /* pointer to pass to our read function */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_READDATA, pWebSsnListNode->pUsrAppData); 
    /* Set the expected POST size. */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_POSTFIELDSIZE, (long)(pUsrAppData->inDataLength)); 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_NOSIGNAL,1L); 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_CONNECTTIMEOUT, 60L);/* 60 seconds - timeout when connecting to web server */ 
    curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_TIMEOUT, 60L);/* 60 seconds - read timeout */ 
    res = curl_easy_perform(pWebSsnListNode->pUsrAppSsnData->curl); 

    //Here, xml being print is always sane 
    APP_LOG("HTTPSWRAPPER", LOG_DEBUG, "Sent XML is : %s\n", pUsrAppData->inData); 

Версия cURL, которую я использую, является 7.29 и буфером I a m для хранения данных имеет достаточную длину.

+0

Вы должны опубликовать код, который фактически отправляет данные. – thomasb

+0

@ cosmo0 добавлен ... спасибо, что напомнил – cbinder

+0

Почему этот помеченный PHP, если я могу спросить? Выглядит больше как C, не так ли? Может быть, код на принимающей стороне отсутствует? и это PHP? Также read_callback не является частью вопроса, который, скорее всего, является причиной проблем .... – hakre

ответ

0

С (по-видимому) ваши данные POST простой \0 завершённая строка вместо потока, вы можете использовать следующее:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pUsrAppData->inData); 

вместо звонков:

curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_READFUNCTION, read_callback); 
curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_READDATA, pWebSsnListNode->pUsrAppData); 
curl_easy_setopt(pWebSsnListNode->pUsrAppSsnData->curl, CURLOPT_POSTFIELDSIZE, (long)(pUsrAppData->inDataLength)); 

Кроме того, в зависимости от получателя может потребоваться явный вызов:

curl_easy_setopt(CURL *handle, CURLOPT_HTTPHEADER, struct curl_slist *headers); 

, чтобы установить заголовок Content-Type на что-то вроде application/xml.

+0

Это будет просто альтернатива операции POST ... правильно? или это повлияет на передачу данных в некоторой степени – cbinder

+0

, это простая альтернатива POST; это не повлияет на передачу данных, но я предполагаю, что ваш 'read_callback' является неправильным, поэтому он бы не вызывал эту процедуру –

+0

. Я буду проверять изменения в настройке выносливости ... если он будет работать, примет ваш ответ. – cbinder

Смежные вопросы