webcomm与前端的通讯-goahead服务器流程图
#ifndef __CET_WEBCOMM_H__
#define __CET_WEBCOMM_H__
// 0x0000FFFF
typedef enum eWebSubOptionType
{
WSOT_DASHBOARD = 0X00000001,
WSOT_INTERFACE = 0X00000002,
WSOT_CONNECTION = 0X00000004,
WSOT_NETWORK = 0X00000008,
WSOT_WLAN = 0X00000010,
WSOT_PARAMETERS = 0X00000020,
WSOT_EXPORT = 0X00000040,
WSOT_RESET = 0X00000080,
WSOT_FW_UPDATE = 0X00000100,
WSOT_DEBUG = 0X00000200,
WSOT_LOGS = 0X00000400,
WSOT_USERS = 0X00000800,
WSOT_DATE_AND_TIME = 0X00001000,
WSOT_LOAD_CERT = 0X00002000,
WSOT_IPFILTER = 0X00004000,
WSOT_ABOUT = 0X00008000,
WSOT_MUST_SUPPORT = 0XFFFFFFFF,
} WebSubOptionType_t;
#ifndef WEBCOMM_ACCOUNT_PERMISSION_CHECK
#define WEBCOMM_ACCOUNT_PERMISSION_CHECK ( 1 )
#endif
#ifndef WEBCOMM_ACCOUNT_MAX_NUM
#define WEBCOMM_ACCOUNT_MAX_NUM ( 16 )
#endif
typedef void * WEBHANDLE;
typedef BYTE WebcommResult_t;
enum eWebcommResult
{
WEBERR_RSN_OK = 0, /**< 操作成功 */
WEBERR_RSN_OK_NOTRSP = 1, /**< 操作成功但无回复 */
WEBERR_RSN_ACCOUNT_PASSWORD_ERROR = 11, /**< 账号或密码错误 */
WEBERR_RSN_ACCOUNT_LOGIN_TIMEOUT = 12, /**< 账号登入超时 */
WEBERR_RSN_ACCOUNT_DISABLE = 13, /**< 账号被禁用 */
WEBERR_RSN_ACCOUNT_OUT_NUMBER = 14, /**< 账号数量超出最大值(默认最大16个) */
WEBERR_RSN_ACCOUNT_NOT_PERISSION = 15, /**< 账号没有访问权限 */
WEBERR_RSN_ACCOUNT_ALREADY_EXIST = 16, /**< 账号已存在 */
WEBERR_RSN_ACCOUNT_PASSWORD_SAME = 17, /**< 账号和密码一样 */
WEBERR_RSN_FILES_NOT_EXIST = 18, /**< 文件不存在 */
WEBERR_RSN_FILES_CANNOT_OPEN = 19, /**< 文件不能被打开 */
WEBERR_RSN_FILES_FORMAT_ERROR = 20, /**< 文件格式错误 */
WEBERR_RSN_FILES_CHECKSUM_FAIL = 21, /**< 文件校验失败 */
WEBERR_RSN_DATABASE_OPERATE_FAIL = 22, /**< 数据库操作失败 */
WEBERR_RSN_NOT_FLASH_SPACE = 23, /**< FLASH空间不足 */
WEBERR_RSN_HUB_COMM_FAIL = 24, /**< HUB通信失败 */
WEBERR_RSN_PARAMETER_MISSING = 25, /**< 请求的参数缺失 */
WEBERR_RSN_PARAMETER_VALUE_OUTOFRANGE = 26, /**< 请求的参数值超出范围 */
WEBERR_RSN_MEMORY_ALLOCATION_FAIL = 27, /**< 内存分配失败 */
WEBERR_RSN_URL_NOT_SUPPORT = 28, /**< URL请求路径不支持 */
WEBERR_RSN_REQUEST_NOT_METHOD = 29, /**< 请求不支持该方法 */
WEBERR_RSN_PORT_ALREADY_OCCUPIED = 30, /**< 端口已被占用 */
WEBERR_RSN_UNKNOWN = 60, /**< 未知错误 */
};
typedef struct sReasonInfo
{
WebcommResult_t code; /**< 错误的原因编号 */
const char *message; /**< 编号的字符串形式 */
} GCC_PACKED ReasonInfo_t;
// Webcomm Result Response
#define WEBRES_CODE "code"
#define WEBRES_MESSAGE "message"
#define WEBRES_DATA "data"
#define WEBCOMM_METHOD "method"
#define WEBCOMM_LOGIN_USER "username"
#define WEBCOMM_LOGIN_PASS "password"
#define WEBCOMM_LOGIN_LAST "last_time"
#define WEBCOMM_TOKEN_ACCESS "access_token"
#define WEBMETHOD_POST "POST" // 创建(更新,删除)
#define WEBMETHOD_GET "GET" // 读取
#define POSTMETHOD_CREATE "create" // 创建
#define POSTMETHOD_UPDATE "update" // 更新
#define POSTMETHOD_DELETE "delete" // 删除
#define POSTMETHOD_IMPORT "import" // 导入
#define POSTMETHOD_EXPORT "export" // 导出
#define POSTMETHOD_LOAD "load" // 加载
#define POSTMETHOD_EXECUTE "execute" // 执行
typedef WebcommResult_t (*fHandler_t)(WEBHANDLE webHandle, const char *uriPath, Webs *wp);
// create webcomm object
WEBHANDLE WebcommCreate(void);
// destroy webcomm object
void WebcommDestroy(WEBHANDLE webHandle);
// send result from webcomm data
int WebcommSendResult(WEBHANDLE webHandle, Webs *wp);
// check User account and password
WebcommResult_t WebcommLoginCheck(WEBHANDLE webHandle, int alreaylogin, const char *cname, const char *cpasswd);
// New Session
WebcommResult_t WebcommNewSession(WEBHANDLE webHandle, Webs *wp, const char *cname, const char *cvalue);
WebcommResult_t WebcommGetSession(WEBHANDLE webHandle, Webs *wp, const char *cname);
WebcommResult_t WebcommDeleteSession(WEBHANDLE webHandle, Webs *wp, const char *cname);
WebcommResult_t WebcommExecuteHandler(WEBHANDLE webHandle, Webs *wp, const char *cname);
const char *ReasonInfo(WebcommResult_t code);
///
#endif /* __CET_WEBCOMM_H__ */
/*
* File name : webcommsdk.c
*
* Created on : 2020年3月12日09:35:10
* Author : Firmware of xiyuan255
* Version : 1.0
* Language : C
* Copyright : Copyright (C) 2019, xiyuan255 Inc.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include "goahead.h"
#include "cetwebcomm.h"
/
typedef struct sWebHandler
{
HANDLE dbHandle; /**< 数据库操作是句柄 */
ReasonInfo_t rsi;
cJSON *pData; /**< data数据块的指针 */
} WebHandler_t;
typedef struct sCallbackSet
{
const char *wpMethod; // POST or GET
union
{
/* POST方法的函数映射 */
struct
{
const char *method; // execute import ...
WebcommResult_t (*callback)(WEBHANDLE, const char *, Webs *);
} post;
/* GET方法的函数映射 */
WebcommResult_t (*callback)(WEBHANDLE, const char *, Webs *);
} symbol;
} CallbackSet_t;
#define CALLBACKSET_END(METHOD, name) \
{ METHOD, { .callback = name }, }
#define CALLBACKSET_INIT(WMETHOD, name) \
{ WEBMETHOD_##WMETHOD, { .callback = WEB##WMETHOD##_##name }, }
#define CALLBACKSET_POSTINIT(PMETHOD, name) \
{ WEBMETHOD_POST, { { .method = POSTMETHOD_##PMETHOD, .callback = WEB##PMETHOD##_##name } }, }
#define CALLBACKSET_NAME(cstring) sg_callbackset_##cstring
#define WEBCOMM_FRAME_WITH_SUB(OPTION, WSOT, cstring, csubstring) \
{ OPTION, WSOT, #cstring"/"#csubstring, CALLBACKSET_NAME(cstring##_##csubstring) }
#define WEBCOMM_FRAME(OPTION, WSOT, cstring) \
{ OPTION, WSOT, #cstring, CALLBACKSET_NAME(cstring) }
#define DEFINE_STATIC_GLBVAR(type, name) static type name
typedef struct sWebcommFrame
{
const char *options;
WebSubOptionType_t suboptions;
const char *uriLabel; /**< url的路径 */
CallbackSet_t *callbackSet; /**< 对应的回调集合 */
} GCC_PACKED WebcommFrame_t;
typedef struct sWebOptionMap
{
const char *webOption; /**< web的主选项 */
const char *webSubOption; /**< web的子选项 */
WebSubOptionType_t subOption;
} GCC_PACKED WebOptionMap_t;
#define CHECK_WEBHANDLE_DATA_OBJECT(pWebHandler) \
do { \
if (NULL == (pWebHandler)->pData) { \
(pWebHandler)->pData = cJSON_CreateObject(); \
} \
if (NULL == (pWebHandler)->pData) { \
return WebErrReason(pWebHandler, WEBERR_RSN_MEMORY_ALLOCATION_FAIL); \
} \
} while (0)
static const ReasonInfo_t sg_WebRsnInfo[] =
{
{WEBERR_RSN_OK, "success"},
{WEBERR_RSN_ACCOUNT_PASSWORD_ERROR, "account or password error"},
{WEBERR_RSN_ACCOUNT_LOGIN_TIMEOUT, "account login timeout"},
{WEBERR_RSN_ACCOUNT_DISABLE, "account is disabled"},
{WEBERR_RSN_ACCOUNT_OUT_NUMBER, "number of accounts exceeds"},
{WEBERR_RSN_ACCOUNT_NOT_PERISSION, "account has no access rights"},
{WEBERR_RSN_ACCOUNT_ALREADY_EXIST, "account already exists"},
{WEBERR_RSN_ACCOUNT_PASSWORD_SAME, "account is the same as the password"},
{WEBERR_RSN_FILES_NOT_EXIST, "file does not exist"},
{WEBERR_RSN_FILES_CANNOT_OPEN, "file cannot be opened"},
{WEBERR_RSN_FILES_FORMAT_ERROR, "file format error"},
{WEBERR_RSN_FILES_CHECKSUM_FAIL, "file validation failed"},
{WEBERR_RSN_DATABASE_OPERATE_FAIL, "database operation failed"},
{WEBERR_RSN_NOT_FLASH_SPACE, "not flash space"},
{WEBERR_RSN_HUB_COMM_FAIL, "hub communication failure"},
{WEBERR_RSN_PARAMETER_MISSING, "request parameter exception"},
{WEBERR_RSN_PARAMETER_VALUE_OUTOFRANGE, "request parameter values are out of range"},
{WEBERR_RSN_MEMORY_ALLOCATION_FAIL, "memory allocation failure"},
{WEBERR_RSN_URL_NOT_SUPPORT, "url request path is not supported"},
{WEBERR_RSN_REQUEST_NOT_METHOD, "request does not support the method"},
{WEBERR_RSN_PORT_ALREADY_OCCUPIED, "the port is already occupied"},
{WEBERR_RSN_UNKNOWN, "unknown error"},
};
static WebOptionMap_t sg_WebOptionMap[] =
{
{WEBOVERIVEW_OPTION, SUBOPTION_DASHBOARD, WSOT_DASHBOARD},
{WEBOVERIVEW_OPTION, SUBOPTION_INTERFACE, WSOT_INTERFACE},
{WEBCONNECTIVITY_OPTION, SUBOPTION_CONNECTION, WSOT_CONNECTION},
{WEBCONNECTIVITY_OPTION, SUBOPTION_NETWORK, WSOT_NETWORK},
{WEBCONNECTIVITY_OPTION, SUBOPTION_WLAN, WSOT_WLAN},
{WEBCONNECTIVITY_OPTION, SUBOPTION_PARAMETERS, WSOT_PARAMETERS},
{WEBMAINTENANCE_OPTION, SUBOPTION_EXPORT, WSOT_EXPORT},
{WEBMAINTENANCE_OPTION, SUBOPTION_RESET, WSOT_RESET},
{WEBMAINTENANCE_OPTION, SUBOPTION_FIRMWARE_UPDATE, WSOT_FW_UPDATE},
{WEBMAINTENANCE_OPTION, SUBOPTION_DEBUG, WSOT_DEBUG},
{WEBMAINTENANCE_OPTION, SUBOPTION_LOGS, WSOT_LOGS},
{WEBSYSTEM_OPTION, SUBOPTION_USERS, WSOT_USERS},
{WEBSYSTEM_OPTION, SUBOPTION_DATE_AND_TIME, WSOT_DATE_AND_TIME},
{WEBSYSTEM_OPTION, SUBOPTION_LOAD_CERTIFICATE, WSOT_LOAD_CERT},
{WEBSYSTEM_OPTION, SUBOPTION_IPFILTER, WSOT_IPFILTER},
{WEBSYSTEM_OPTION, SUBOPTION_ABOUT, WSOT_ABOUT},
{NULL, NULL, 0},
};
const char *ReasonInfo(WebcommResult_t code)
{
int idx = 0;
int length = 0;
length = sizeof(sg_WebRsnInfo)/sizeof(sg_WebRsnInfo[0]);
for (idx = 0; idx < length; idx++)
{
if (sg_WebRsnInfo[idx].code == code) {
return sg_WebRsnInfo[idx].message;
}
}
return NULL;
}
static inline int WebErrReason(WebHandler_t *pWebHandler, WebcommResult_t code)
{
pWebHandler->rsi.code = code;
pWebHandler->rsi.message = ReasonInfo(code);
return code;
}
inline void *GetCallback(CallbackSet_t CallbackSet[], const char *wpMethod, const char *method)
{
void *callback = NULL;
CallbackSet_t *pCbSet = NULL;
for (pCbSet = CallbackSet; (pCbSet && pCbSet->wpMethod); pCbSet++)
{
// 校验HTTP方法是否匹配
if (0 != strcmp1(wpMethod, pCbSet->wpMethod)) {
continue;
}
if (0 == strcmp1(WEBMETHOD_POST, pCbSet->wpMethod))
{
// 校验POST方法的method字段是否匹配
if (0 == strcmp1(method, pCbSet->symbol.post.method)) {
callback = (void *)pCbSet->symbol.post.callback;
break;
}
}
else if (0 == strcmp1(WEBMETHOD_GET, pCbSet->wpMethod))
{
callback = (void *)pCbSet->symbol.callback;
break;
}
}
return callback;
}
void WebsResponseHeadSafePolicy(Webs *wp)
{
websWriteHeader(wp, "Pragma", "no-cache");
websWriteHeader(wp, "Cache-Control", "no-store");
websWriteHeader(wp, "X-Content-Type-Options", "nosniff");
websWriteHeader(wp, "X-XSS-Protection", "%d; mode=block", 1);
websWriteHeader(wp, "Content-Security-Policy", "default-src 'self'; frame-ancestors 'self'");
websWriteHeader(wp, "Content-Type", "application/json; charset=utf-8");
websWriteHeader(wp, "Strict-Transport-Security", "max-age=%d; includeSubDomains", 31536000);
}
static int WebSetParam(void *arg, cJSON *mJson, cJSON *childJson)
{
Webs *wp = NULL;
cchar *prior = NULL;
WebsKey *sp = NULL;
char *keyword = NULL;
char value[MAX_LEN_1024] = {0};
assert(arg);
assert(mJson);
assert(childJson);
keyword = childJson->string? childJson->string : mJson->string;
if (cJSON_Number == childJson->type) {
snprintf(value, MAX_LEN_1024, "%d", childJson->valueint);
} else if (cJSON_String == childJson->type) {
snprintf(value, MAX_LEN_1024, "%s", childJson->valuestring);
}
wp = (Webs *)arg;
if (*keyword) {
/*
If keyword has already been set, append the new value to what has been stored.
*/
if ((prior = websGetVar(wp, keyword, NULL)) != 0) {
sp = websSetVarFmt(wp, keyword, "%s,%s", prior, value);
} else {
sp = websSetVar(wp, keyword, value);
}
/* Flag as untrusted keyword by setting arg to 1. This is used by CGI to prefix this keyword */
sp->arg = 0;
return 0;
}
return -1;
}
static int WebReplaceKey(void *arg, cJSON *mJson, cJSON *childJson)
{
char *temp = NULL;
struct sKey {
const char *oldkey;
const char *newkey;
};
struct sKey *pKey = (struct sKey *)arg;
assert(arg);
assert(mJson);
assert(childJson);
if (mJson->string && 0 == strcmp(mJson->string, pKey->oldkey)) {
temp = calloc(sizeof(char), strlen(pKey->newkey) + 1);
if (NULL == temp)
return -1;
free(mJson->string);
mJson->string = temp;
strcpy(mJson->string, pKey->newkey);
return 0;
}
return -1;
}
/**
递归遍历json串的数据
*/
static void RecursiveTraversal(int isBreak, void *arg, cJSON *mJson, cJSON *childJson,
int (*callback)(void *arg, cJSON *mJson, cJSON *childJson))
{
int ret = -1;
while (childJson)
{
if ((cJSON_Number == childJson->type)||(cJSON_String == childJson->type)) {
if (NULL != callback) {
ret = callback(arg, mJson, childJson);
if (0 == ret && isBreak)
return;
}
} else if ((cJSON_Array == childJson->type)||(cJSON_Object == childJson->type)) {
RecursiveTraversal(isBreak, arg, childJson, childJson->child, callback);
}
childJson = childJson->next;
}
}
/**
KEY相同的VALUE会以空格间隔的形式被放在一起,也是因为这样,
要避免出现的不同对象中定义相同的KEY的情况,造成VALUE存在到一起
*/
int WebcommAddJsonVars(Webs *wp, char *vars)
{
cJSON *cJson = NULL;
char *strData = NULL;
assert(wp);
assert(vars);
if (NULL != (cJson = cJSON_Parse(vars)))
{
strData = cJSON_Print(cJson);
//cJSON_Minify(strData);
PrintInfo("JsonVars=%s", strData);
RecursiveTraversal(0, wp, cJson, cJson->child, WebSetParam);
cJSON_Delete(cJson);
free(strData);
return 0;
}
return -1;
}
/**
使用新key替换json中的key=value形式的旧key
*/
int WebcommReplaceJsonKey(cJSON *cJson, const char *oldkey, const char *newkey)
{
struct sKey {
const char *oldkey;
const char *newkey;
};
char *strData = NULL;
struct sKey Key;
assert(cJson);
assert(oldkey);
assert(newkey);
strData = cJSON_Print(cJson);
cJSON_Minify(strData);
PrintInfo("JsonVars=%s", strData);
Key.oldkey = oldkey;
Key.newkey = newkey;
RecursiveTraversal(1, &Key, cJson, cJson->child, WebReplaceKey);
free(strData);
return 0;
}
//
static WebcommResult_t WEBGET_DeviceUseSituation(WEBHANDLE webHandle, const char *uriPath, Webs *wp)
{
WebHandler_t *pWebHandler = NULL;
assert(webHandle);
assert(uriPath);
assert(wp);
pWebHandler = (WebHandler_t *)webHandle;
JsonGetDeviceUseSituation(pWebHandler->pData, pWebHandler->dbHandle, 0);
return WebErrReason(pWebHandler, WEBERR_RSN_OK);
}
DEFINE_STATIC_GLBVAR(CallbackSet_t, CALLBACKSET_NAME(use_situation))[] = {
CALLBACKSET_INIT(GET, DeviceUseSituation),
CALLBACKSET_END(NULL, NULL),
};
DEFINE_STATIC_GLBVAR(WebcommFrame_t, sg_WebAssemble)[] =
{
// 资源对象的回调函数 可在此添加
WEBCOMM_FRAME(WEBOVERIVEW_OPTION, WSOT_DASHBOARD, use_situation),
{NULL, 0, NULL, NULL},
};
WEBHANDLE WebcommCreate(void)
{
WebHandler_t *pWebHandler = NULL;
pWebHandler = (WebHandler_t *)calloc(sizeof(char), sizeof(WebHandler_t));
return (WEBHANDLE)pWebHandler;
}
void WebcommDestroy(WEBHANDLE webHandle)
{
WebHandler_t *pWebHandler = NULL;
pWebHandler = (WebHandler_t *)webHandle;
if (NULL != pWebHandler) {
if (NULL != pWebHandler->pData) {
cJSON_Delete(pWebHandler->pData);
}
free(pWebHandler);
}
}
// send result from webcomm data
int WebcommSendResult(WEBHANDLE webHandle, Webs *wp)
{
int code = 0;
int payloadLen = 0;
char *payload = NULL;
cJSON *resJson = NULL;
WebHandler_t *pWebHandler = NULL;
assert(webHandle);
assert(wp);
pWebHandler = (WebHandler_t *)webHandle;
if (WEBERR_RSN_OK_NOTRSP == pWebHandler->rsi.code) {
if (NULL != pWebHandler->pData) {
cJSON_Delete(pWebHandler->pData);
pWebHandler->pData = NULL;
}
WebErrReason(pWebHandler, WEBERR_RSN_UNKNOWN);
return 0;
}
switch (pWebHandler->rsi.code)
{
case WEBERR_RSN_OK:
case WEBERR_RSN_PARAMETER_VALUE_OUTOFRANGE:
code = HTTP_CODE_OK;
break;
case WEBERR_RSN_URL_NOT_SUPPORT:
case WEBERR_RSN_PARAMETER_MISSING:
code = HTTP_CODE_BAD_REQUEST;
break;
case WEBERR_RSN_ACCOUNT_PASSWORD_ERROR:
code = HTTP_CODE_UNAUTHORIZED;
break;
case WEBERR_RSN_REQUEST_NOT_METHOD:
code = HTTP_CODE_BAD_METHOD;
break;
default:
code = HTTP_CODE_INTERNAL_SERVER_ERROR;
break;
}
resJson = cJSON_CreateObject();
cJSON_AddNumberToObject(resJson, WEBRES_CODE, pWebHandler->rsi.code);
cJSON_AddStringToObject(resJson, WEBRES_MESSAGE, pWebHandler->rsi.message);
cJSON_AddItemToObject(resJson, WEBRES_DATA, pWebHandler->pData);
if (NULL == (payload = cJSON_Print(resJson))) {
return -1;
}
payloadLen = strlen(payload);
PrintInfo("[WebcommSendResult:%d] %s ", pWebHandler->rsi.code, payload);
websSetStatus(wp, code);
websWriteHeaders(wp, payloadLen, 0);
WebsResponseHeadSafePolicy(wp);
websWriteEndHeaders(wp);
websWriteBlock(wp, payload, payloadLen);
websWriteBlock(wp, "\r\n", 2);
websDone(wp);
cJSON_Delete(resJson);
free(payload);
pWebHandler->pData = NULL;
WebErrReason(pWebHandler, WEBERR_RSN_UNKNOWN);
return 0;
}
WebcommResult_t WebcommLoginCheck(WEBHANDLE webHandle, int alreaylogin, const char *cname, const char *cpasswd)
{
WebPermitUser_t *pPermitUser = NULL;
WebcommResult_t webResult = WEBERR_RSN_ACCOUNT_PASSWORD_ERROR;
assert(webHandle);
assert(cname);
assert(cpasswd);
if (NULL != (pPermitUser = WebsGetPermitUser(cname))) {
if (0 == pPermitUser->state) { // 账户是否被禁用
webResult = WEBERR_RSN_ACCOUNT_DISABLE;
} else {
webResult = (0 == strcmp1(pPermitUser->password, cpasswd)) ?
WEBERR_RSN_OK : WEBERR_RSN_ACCOUNT_PASSWORD_ERROR;
}
} else if (alreaylogin) { // 登入过,获取不到,说明超时,已被删除
webResult = WEBERR_RSN_ACCOUNT_LOGIN_TIMEOUT;
}
return WebErrReason((WebHandler_t *)webHandle, webResult);
}
// New Session
WebcommResult_t WebcommNewSession(WEBHANDLE webHandle, Webs *wp, const char *cname, const char *cvalue)
{
WebHandler_t *pWebHandler = NULL;
WebPermitUser_t *pPermitUser = NULL;
char currenttime[MAX_LEN_256] = {0};
assert(wp);
assert(webHandle);
wfree(wp->username);
wp->username = sclone(cname);
wfree(wp->password);
wp->password = sclone(cvalue);
pWebHandler = (WebHandler_t *)webHandle;
CHECK_WEBHANDLE_DATA_OBJECT(pWebHandler);
websCreateSession(wp);
websSetSessionVar(wp, WEBCOMM_LOGIN_USER, wp->username);
websSetSessionVar(wp, WEBCOMM_LOGIN_PASS, wp->password);
websSetSessionVar(wp, WEBCOMM_LOGIN_LAST, GetCurrentTime(currenttime, MAX_LEN_256));
if (NULL != (pPermitUser = WebsGetPermitUser(wp->username))) {
/* 同一个账号新登入的session会将之前的会话替换掉 */
if (wp->session && 0 != strcmp(pPermitUser->cookieId, wp->session->id)) {
if (*pPermitUser->cookieId) {
websDeleteSessionByCookie(pPermitUser->cookieId);
}
strcpy(pPermitUser->cookieId, wp->session->id);
}
}
cJSON_AddStringToObject(pWebHandler->pData, WEBCOMM_TOKEN_ACCESS, pPermitUser->cookieId);
return WebErrReason(pWebHandler, WEBERR_RSN_OK);
}
WebcommResult_t WebcommGetSession(WEBHANDLE webHandle, Webs *wp, const char *cname)
{
const char *lasttime = NULL;
WebHandler_t *pWebHandler = NULL;
assert(webHandle);
assert(wp);
wfree(wp->username);
wp->username = sclone(cname);
pWebHandler = (WebHandler_t *)webHandle;
CHECK_WEBHANDLE_DATA_OBJECT(pWebHandler);
lasttime = websGetTokenSessionVar(wp, WEBCOMM_LOGIN_LAST, "");
cJSON_AddStringToObject(pWebHandler->pData, WEBCOMM_LOGIN_USER, cname);
cJSON_AddStringToObject(pWebHandler->pData, WEBCOMM_LOGIN_LAST, lasttime);
return WebErrReason(pWebHandler, WEBERR_RSN_OK);
}
WebcommResult_t WebcommDeleteSession(WEBHANDLE webHandle, Webs *wp, const char *cname)
{
assert(webHandle);
assert(wp);
wfree(wp->username);
wp->username = sclone(cname);
OPLOGS_OPTION_PREFIX(webHandle, wp->username, NULL, "logout");
OPLOGS_OPTION_STRSAVE("", NULL, "", 1);
websRemoveSessionVar(wp, WEBCOMM_LOGIN_USER);
websRemoveSessionVar(wp, WEBCOMM_LOGIN_PASS);
websRemoveSessionVar(wp, WEBCOMM_LOGIN_LAST);
websDestroySession(wp);
return WebErrReason((WebHandler_t *)webHandle, WEBERR_RSN_OK);
}
WebcommResult_t WebcommExecuteHandler(WEBHANDLE webHandle, Webs *wp, const char *cname)
{
void *callback = NULL;
const char *method = NULL;
char option[MAX_LEN_64] = {0};
char uriPath[MAX_LEN_2048] = {0};
WebHandler_t *pWebHandler = NULL;
WebPermitUser_t *pPermitUser = NULL;
WebcommFrame_t *pAssemble = NULL;
assert(webHandle);
assert(wp);
wfree(wp->username);
wp->username = sclone(cname);
pWebHandler = (WebHandler_t *)webHandle;
CHECK_WEBHANDLE_DATA_OBJECT(pWebHandler);
#if (1 == WEBCOMM_ACCOUNT_PERMISSION_CHECK)
/* 获取当前用户的权限mask */
if (NULL != (pPermitUser = WebsGetPermitUser(wp->username))) {
// ....
}
#endif
sscanf(wp->url, "/web/app/%[^/]%*c%[^?]", option, uriPath);
for (pAssemble = sg_WebAssemble; pAssemble->options; pAssemble++) {
// 校验option的是否匹配
if (0 != strcmp1(option, pAssemble->options)) {
continue;
}
// 校验请求路径的是否匹配
if (0 != strncmp(uriPath, pAssemble->uriLabel, strlen(pAssemble->uriLabel))) {
continue;
}
#if (1 == WEBCOMM_ACCOUNT_PERMISSION_CHECK)
// 检查当前用户是否具体该 suboptions 权限
if (NULL == pPermitUser || !(pPermitUser->permitMask & pAssemble->suboptions)) {
return WebErrReason(pWebHandler, WEBERR_RSN_ACCOUNT_NOT_PERISSION);
}
#endif
// 获取BODY中method的值
method = websGetVar(wp, WEBCOMM_METHOD, "");
if (NULL != (callback = GetCallback(pAssemble->callbackSet, wp->method, method))) {
return ((WebcommResult_t (*)(WEBHANDLE, cchar *, Webs *))callback)(webHandle, uriPath, wp);
} else {
return WebErrReason(pWebHandler, WEBERR_RSN_REQUEST_NOT_METHOD);
}
}
return WebErrReason(pWebHandler, WEBERR_RSN_URL_NOT_SUPPORT);
}