Mod aaa-12 1. 增加HTTP访问网络失败处理。2. 更正ZTP认证服务器返回数据类型。

RCA:
SOL:
修改人:huangxin
检视人:huangxin
This commit is contained in:
huangxin 2019-12-03 11:05:13 +08:00
parent ac282c9fdb
commit 274428e9ce
9 changed files with 289 additions and 157 deletions

View File

@ -13,11 +13,13 @@
#define SSL_CA_FILE ("/etc/ssl/certs/ca-certificates.crt")
#define CURL_TIMEOUT (5)
typedef struct {
char *pReqUrl;
char sPath[MAX_PATH];
char sDlPath[MAX_PATH];
unsigned int reqResult[4096];
unsigned char reqResult[4096];
unsigned int dlSize;
OnHttpResponse onRspCb;
CURL *pCurl;
@ -36,15 +38,20 @@ static size_t __writeDataCb(void *pData, size_t size, size_t nmemb, void *pParam
return (iMemSize);
}
int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onRespCb)
int http_post_request_async(const char *pURL, const char *pPost, OnHttpResponse onRespCb)
{
long flag = (long)CURL_GLOBAL_ALL;
int value = 1;
int value = 1, timeout = CURL_TIMEOUT;
CURL *pCurl = NULL;
int ret = 0;
struct curl_slist *pList;
PHTTP_REQ_PARAMS pParams = NULL;
if(pURL == NULL || strlen(pURL) == 0) {
LOG_EX(LOG_Error, "Input URL error\n");
return -ERR_INPUTERR;
}
pParams = (PHTTP_REQ_PARAMS)malloc(sizeof(HTTP_REQ_PARAMS));
if(pParams == NULL) {
@ -72,13 +79,10 @@ int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onResp
memset(pParams, 0, sizeof(HTTP_REQ_PARAMS));
pParams->onRspCb = onRespCb;
pParams->pReqUrl = (char *)malloc(strlen(pURL) + 1);
pParams->pReqUrl = strdup(pURL);
pParams->dlSize = 0;
pParams->pCurl = pCurl;
memset(pParams->pReqUrl, 0, strlen(pURL) + 1);
strcpy(pParams->pReqUrl, pURL);
pList = curl_slist_append(NULL, "Content-Type:application/json;charset=UTF-8");
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb);
@ -86,6 +90,7 @@ int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onResp
curl_easy_setopt(pCurl, CURLOPT_PRIVATE, pParams);
curl_easy_setopt(pCurl, CURLOPT_URL, pURL);
curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, value);
curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, timeout);
curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList);
@ -125,16 +130,19 @@ int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onResp
ret = curl_easy_perform(pCurl);
if(ret != CURLE_OK) {
LOG_EX(LOG_Error, "Http Post error: %u\n", ret);
LOG_EX(LOG_Error, "Http Post error(%u): %s\n", ret, curl_easy_strerror(ret));
}
curl_slist_free_all(pList);
curl_easy_cleanup(pCurl);
curl_global_cleanup();
if(onRespCb) {
if(onRespCb && ret == CURLE_OK) {
onRespCb(pParams->reqResult, pParams->dlSize, pParams->pReqUrl, pParams->sPath,
NULL, -pParams->errCode, pParams->pData);
NULL, CURLE_OK, pParams->pData);
} else {
onRespCb(NULL, 0, pParams->pReqUrl, pParams->sPath,
NULL, -ret, pParams->pData);
}
if(pParams->pReqUrl) {
@ -145,3 +153,118 @@ int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onResp
return ret;
}
int http_post_request(const char *pURL, const char *pPost, unsigned char* pBuf, unsigned int *pOutSize)
{
long flag = (long)CURL_GLOBAL_ALL;
int value = 1, timeout = CURL_TIMEOUT;
CURL *pCurl = NULL;
int ret = 0;
struct curl_slist *pList;
PHTTP_REQ_PARAMS pParams = NULL;
if(pURL == NULL || strlen(pURL) == 0 || pBuf == NULL || pOutSize == NULL) {
LOG_EX(LOG_Error, "Input params error\n");
return -ERR_NOMEM;
}
pParams = (PHTTP_REQ_PARAMS)malloc(sizeof(HTTP_REQ_PARAMS));
if(pParams == NULL) {
LOG_EX(LOG_Error, "Malloc %u memory error\n", sizeof(HTTP_REQ_PARAMS));
return -ERR_NOMEM;
}
ret = curl_global_init(flag);
if(ret != CURLE_OK) {
LOG_EX(LOG_Error, "Init curl global error: %d\n", ret);
free(pParams);
return -ERR_ERR;
}
pCurl = curl_easy_init();
if(!pCurl) {
LOG_EX(LOG_Error, "Init easy curl error: %d\n", ret);
curl_global_cleanup();
free(pParams);
return -ERR_ERR;
}
memset(pParams, 0, sizeof(HTTP_REQ_PARAMS));
pParams->pReqUrl = strdup(pURL);
pParams->dlSize = 0;
pParams->pCurl = pCurl;
pList = curl_slist_append(NULL, "Content-Type:application/json;charset=UTF-8");
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pParams);
curl_easy_setopt(pCurl, CURLOPT_PRIVATE, pParams);
curl_easy_setopt(pCurl, CURLOPT_URL, pURL);
curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, value);
curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, timeout);
curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList);
if(pPost != NULL && strlen(pPost) > 0) {
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, pPost);
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE, (long)strlen(pPost));
pParams->pData = (void*)pPost;
}
#ifdef SKIP_PEER_VERIFICATION
/*
* If you want to connect to a site who isn't using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the
* verification of the server's certificate. This makes the connection
* A LOT LESS SECURE.
*
* If you have a CA cert for the server stored someplace else than in the
* default bundle, then the CURLOPT_CAPATH option might come handy for
* you.
*/
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
#else
curl_easy_setopt(pCurl, CURLOPT_CAINFO, SSL_CA_FILE);
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, value);
#endif
#ifdef SKIP_HOSTNAME_VERIFICATION
/*
* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure.
*/
curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
ret = curl_easy_perform(pCurl);
if(ret != CURLE_OK) {
LOG_EX(LOG_Error, "Http Post error(%u): %s\n", ret, curl_easy_strerror(ret));
}
curl_slist_free_all(pList);
curl_easy_cleanup(pCurl);
curl_global_cleanup();
if(*pOutSize < pParams->dlSize) {
ret = -ERR_OUTSIZE;
} else {
*pOutSize = pParams->dlSize;
}
memcpy(pBuf, pParams->reqResult, *pOutSize);
if(pParams->pReqUrl) {
free(pParams->pReqUrl);
}
free(pParams);
return ret;
}

View File

@ -24,6 +24,7 @@
#define ERR_SRCERR (15)
#define ERR_JSONERR (16)
#define ERR_USED (17)
#define ERR_OUTSIZE (18)
#define ERR_READFILE (100)
@ -34,45 +35,27 @@ static inline char *err2string(int err)
}
switch(err) {
case ERR_OK: return "OK";
case ERR_ERR: return "Error";
case ERR_UNKNOWN: return "Unkown";
case ERR_SYSERR: return "SystemError";
case ERR_NOTFOUND: return "NotFound";
case ERR_TIMEOUT: return "Timeout";
case ERR_NULLP: return "NullPointer" ;
case ERR_NOMEM: return "NotEnoughMemory";
case ERR_CHKERR: return "CheckError";
case ERR_NOTSUPPORT: return "NotSupport";
case ERR_INPUTERR: return "InputError";
case ERR_EXIST: return "AlreadyExist";
case ERR_FULL: return "Full";
case ERR_SENDERR: return "SendErr";
case ERR_NOCMID: return "CanNotFindConfig";
case ERR_SRCERR: return "ConfigSourceErr";
case ERR_JSONERR: return "JsonFormatErr";
case ERR_USED: return "ItemUsed";
case ERR_READFILE: return "Read File Error";
default: return "Unknown err code";
case ERR_OK: return (char*) "OK";
case ERR_ERR: return (char*) "Error";
case ERR_UNKNOWN: return (char*) "Unkown";
case ERR_SYSERR: return (char*) "SystemError";
case ERR_NOTFOUND: return (char*) "NotFound";
case ERR_TIMEOUT: return (char*) "Timeout";
case ERR_NULLP: return (char*) "NullPointer" ;
case ERR_NOMEM: return (char*) "NotEnoughMemory";
case ERR_CHKERR: return (char*) "CheckError";
case ERR_NOTSUPPORT: return (char*) "NotSupport";
case ERR_INPUTERR: return (char*) "InputError";
case ERR_EXIST: return (char*) "AlreadyExist";
case ERR_FULL: return (char*) "Full";
case ERR_SENDERR: return (char*) "SendErr";
case ERR_NOCMID: return (char*) "CanNotFindConfig";
case ERR_SRCERR: return (char*) "ConfigSourceErr";
case ERR_JSONERR: return (char*) "JsonFormatErr";
case ERR_USED: return (char*) "ItemUsed";
case ERR_READFILE: return (char*) "Read File Error";
case ERR_OUTSIZE: return (char*) "Out of memory size";
default: return (char*) "Unknown err code";
}
}

View File

@ -17,8 +17,8 @@ typedef struct {
typedef struct {
char *status;
unsigned int iptype;
unsigned int ip;
int iptype;
char *ip;
char *code;
} AUTH_ZTH_RSP, *PAUTH_ZTH_RSP;

View File

@ -8,5 +8,7 @@
typedef void (*OnHttpResponse)(void *pData, unsigned int size, const char *pReqUrl,
const char *pDlPath, const char *pTaskUuid, int iFinished, void *pUserData);
int http_post_request(const char *pURL, const char *pPost, OnHttpResponse onRespCb);
int http_post_request_async(const char *pURL, const char *pPost, OnHttpResponse onRespCb);
int http_post_request(const char *pURL, const char *pPost, unsigned char* pBuf, unsigned int *pOutSize);
#endif //ZTP_CLIENT_RESTFUL_H

View File

@ -67,13 +67,14 @@ static int __ztp_auth_decode(const char *pJsonS, void **pStruct)
pVal = cJSON_GetObjectItem(pRoot, "iptype");
if(cJSON_IsString(pVal)) {
pData->iptype = (unsigned int)strtoul(pVal->valuestring, 0, 10);
pData->iptype = (int)strtoul(pVal->valuestring, 0, 10);
}
pVal = cJSON_GetObjectItem(pRoot, "ip");
if(cJSON_IsString(pVal)) {
pData->ip = (unsigned int)strtoul(pVal->valuestring, 0, 10);
pData->ip = strdup(pVal->valuestring);
//(unsigned int)strtoul(pVal->valuestring, 0, 10);
}
pVal = cJSON_GetObjectItem(pRoot, "code");

View File

@ -11,10 +11,9 @@ using namespace std;
extern "C" {
#include "err_code.h"
#include "json_interface.h"
#include "restful.h"
}
TEST(json_encode_test, retOK)
TEST(json_test, encode)
{
int ret = 0;
const char *pJson;
@ -32,7 +31,7 @@ TEST(json_encode_test, retOK)
ASSERT_EQ(ERR_OK, ret);
}
TEST(json_decode_test, retOK)
TEST(json_test, decode)
{
#define JSON_STR ("{\"code\":\"fBBx8Q\",\"ip\":\"172.28.73.38\",\"iptype\":\"1\",\"status\":\"SUCCESS\"}")
int ret = 0;
@ -59,77 +58,6 @@ TEST(json_decode_test, retOK)
ASSERT_EQ(0, ret);
}
TEST(ztp_auth, success)
{
#define JSON_REQ ("{\"ESN\": \"tt21\"}")
#define REQ_URL ("http://172.28.73.43:8088/device/esn")
int ret;
int size = 4096;
char buf[4096];
PAUTH_ZTH_RSP pZTPRsp;
memset(buf, 0, 4096);
ret = http_post_request(REQ_URL, JSON_REQ, (unsigned char*)buf, &size);
EXPECT_EQ(ERR_OK, ret);
ret = Json2Struct(buf, &pZTPRsp, JE_AUTH_ZTP, false);
ASSERT_EQ(ERR_OK, ret);
ASSERT_STRCASEEQ(pZTPRsp->status, "SUCCESS");
if(pZTPRsp) {
if(pZTPRsp->status) {
free(pZTPRsp->status);
}
if(pZTPRsp->code) {
free(pZTPRsp->code);
}
if(pZTPRsp->ip) {
free(pZTPRsp->ip);
}
free(pZTPRsp);
}
}
TEST(ztp_auth, failed)
{
#define JSON_REQ_FAIL ("{\"ESN\": \"ace08484843\"}")
int ret;
int size = 4096;
char buf[4096];
PAUTH_ZTH_RSP pZTPRsp;
memset(buf, 0, 4096);
ret = http_post_request(REQ_URL, JSON_REQ_FAIL, (unsigned char*)buf, &size);
EXPECT_EQ(ERR_OK, ret);
ret = Json2Struct(buf, &pZTPRsp, JE_AUTH_ZTP, false);
ASSERT_EQ(ERR_OK, ret);
ASSERT_STRCASEEQ(pZTPRsp->status, "FAILED");
if(pZTPRsp) {
if(pZTPRsp->status) {
free(pZTPRsp->status);
}
if(pZTPRsp->code) {
free(pZTPRsp->code);
}
if(pZTPRsp->ip) {
free(pZTPRsp->ip);
}
free(pZTPRsp);
}
}
auto main(int argc, char *argv[]) -> int
{
testing::InitGoogleTest(&argc, argv);

View File

@ -0,0 +1,92 @@
//
// Created by xajhu on 2019/12/2 0002.
//
#include <iostream>
using namespace std;
#include "gtest/gtest.h"
extern "C" {
#include "err_code.h"
#include "json_interface.h"
#include "restful.h"
}
TEST(ztp_auth, authorized_success)
{
#define JSON_REQ ("{\"ESN\": \"tt21\"}")
#define REQ_URL ("http://172.28.73.43:8088/device/esn")
int ret;
unsigned int size = 4096;
char buf[4096];
PAUTH_ZTH_RSP pZTPRsp;
memset(buf, 0, 4096);
ret = http_post_request(REQ_URL, JSON_REQ, (unsigned char *)buf, &size);
EXPECT_EQ(ERR_OK, ret);
ret = Json2Struct(buf, &pZTPRsp, JE_AUTH_ZTP, false);
ASSERT_EQ(ERR_OK, ret);
ASSERT_STRCASEEQ(pZTPRsp->status, "SUCCESS") << "\nValue-->["
<< "status: " << pZTPRsp->status
<< ", code: " << pZTPRsp->code
<< ", ip: " << pZTPRsp->ip
<< ", iptype: " << pZTPRsp->iptype << "]" <<endl;
if(pZTPRsp) {
if(pZTPRsp->status) {
free(pZTPRsp->status);
}
if(pZTPRsp->code) {
free(pZTPRsp->code);
}
if(pZTPRsp->ip) {
free(pZTPRsp->ip);
}
free(pZTPRsp);
}
}
TEST(ztp_auth, unauthorized_failed)
{
#define JSON_REQ_FAIL ("{\"ESN\": \"ace08484843\"}")
int ret;
unsigned int size = 4096;
char buf[4096];
PAUTH_ZTH_RSP pZTPRsp;
memset(buf, 0, 4096);
ret = http_post_request(REQ_URL, JSON_REQ_FAIL, (unsigned char *)buf, &size);
EXPECT_EQ(ERR_OK, ret);
ret = Json2Struct(buf, &pZTPRsp, JE_AUTH_ZTP, false);
ASSERT_EQ(ERR_OK, ret);
ASSERT_STRCASEEQ(pZTPRsp->status, "FAILED");
if(pZTPRsp) {
if(pZTPRsp->status) {
free(pZTPRsp->status);
}
if(pZTPRsp->code) {
free(pZTPRsp->code);
}
if(pZTPRsp->ip) {
free(pZTPRsp->ip);
}
free(pZTPRsp);
}
}

View File

@ -28,6 +28,8 @@ void __onPost(void *pData, unsigned int size, const char *pReqUrl,
if(pUserData && strlen(pUserData) > 0) {
LOG_EX(LOG_Info, "Post Data: [%s]\n", pUserData);
}
if(pData) {
LOG_EX(LOG_Info, "Post Result: [%s]\n", (char *)pData);
ret = Json2Struct(pData, &pZTPRsp, JE_AUTH_ZTP, FALSE);
@ -57,6 +59,7 @@ void __onPost(void *pData, unsigned int size, const char *pReqUrl,
free(pZTPRsp);
}
}
}
int main(int argc, char **argv)
{