From 13b0ec9d5332f8e00c01c2778a47c6fe235c6e1b Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 7 Jan 2022 10:55:51 +0800 Subject: [PATCH 01/34] delete:mysql XStorage_MySql_FileQueryForTable and XStorage_MySql_FileQueryForHash function delete:sqlite XStorage_SQLite_FileQueryForTable function modify:sqlite XStorage_SQLite_FileDelete and XStorage_SQLite_FileQuery functions support buckkey parament modify:mysql XStorage_MySql_FileDelete and XStorage_MySql_FileQuery functions support buckkey parament --- .../XStorage_SQLPacket/SQLPacket_Define.h | 216 +++++--- .../XStorage_SQLPacket/SQLPacket_Error.h | 6 +- .../XStorage_MySql/XStorage_MySql.cpp | 510 +++++------------- .../XStorage_MySql/XStorage_MySql.h | 6 +- .../XStorage_SQLPacket/XStorage_SQLPacket.def | 5 +- .../XStorage_SQLite/XStorage_SQLite.cpp | 286 ++++------ .../XStorage_SQLite/XStorage_SQLite.h | 5 +- .../XStorage_SQLPacket/pch.cpp | 41 +- 8 files changed, 422 insertions(+), 653 deletions(-) diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Define.h b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Define.h index eb49bf7..09e1271 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Define.h +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Define.h @@ -53,12 +53,17 @@ extern "C" BOOL XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBManage); /******************************************************************** 函数名称:XStorage_MySql_FileDelete 函数功能:删除一个数据库文件信息 - 参数.一:lpszFile + 参数.一:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:所属BUCK名称 + 参数.二:lpszFile In/Out:In 类型:常量字符指针 可空:Y 意思:要删除的文件全路径 - 参数.二:lpszHash + 参数.三:lpszHash In/Out:In 类型:常量字符指针 可空:Y @@ -68,7 +73,7 @@ extern "C" BOOL XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBManage); 意思:是否成功 备注:参数不能全为空,不会删除文件 *********************************************************************/ -extern "C" BOOL XStorage_MySql_FileDelete(LPCSTR lpszFile = NULL, LPCSTR lpszHash = NULL); +extern "C" BOOL XStorage_MySql_FileDelete(LPCTSTR lpszBuckKey = NULL, LPCSTR lpszFile = NULL, LPCSTR lpszHash = NULL); /******************************************************************** 函数名称:XStorage_MySql_FileQuery 函数功能:查询文件信息 @@ -92,80 +97,32 @@ extern "C" BOOL XStorage_MySql_FileDelete(LPCSTR lpszFile = NULL, LPCSTR lpszHas 类型:常量字符指针 可空:Y 意思:查找结束时间,20190730 - 参数.五:lpszFile + 参数.五:lpszBuckKey In/Out:In 类型:常量字符指针 可空:Y - 意思:要查询的名称 - 参数.六:lpszHash + 意思:查询的BUCK名 + 参数.六:lpszFile In/Out:In 类型:常量字符指针 可空:Y - 意思:要查询的文件MD5 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:返回假可能没有查找到,这条记录不存在.参数lpszFile和lpszMD5不能全为空 -*********************************************************************/ -extern "C" BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCSTR lpszTimeStart = NULL, LPCSTR lpszTimeEnd = NULL, LPCSTR lpszFile = NULL, LPCSTR lpszHash = NULL); -/******************************************************************** -函数名称:XStorage_MySql_FileQueryForTable -函数功能:通过指定表名称查询所有文件 - 参数.一:pppSt_ListFile - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出查询到的文件信息 - 参数.二:pInt_ListCount - In/Out:Out - 类型:三级指针 - 可空:N - 意思:导出获取到的列表个数 - 参数.三:lpszTableName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要查询的表名称 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:参数一需要调用基础库的内存释放函数进行释放内存 -*********************************************************************/ -extern "C" BOOL XStorage_MySql_FileQueryForTable(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCSTR lpszTableName); -/******************************************************************** -函数名称:XStorage_MySql_FileQueryForHash -函数功能:通过HASH查询文件信息 - 参数.一:pSt_FileInfo - In/Out:Out - 类型:数据结构指针 - 可空:N - 意思:输出查询到的文件信息 - 参数.二:lpszFileMD5 - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要查询的文件MD5 - 参数.三:lpszUser - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入文件所属用户 - 参数.四:lpszTimeStart + 意思:要查询的名称 + 参数.七:lpszHash In/Out:In 类型:常量字符指针 可空:Y - 意思:输入开始时间 - 参数.五:lpszTimeEnd + 意思:要查询的文件HASH + 参数.八:lpszTableName In/Out:In 类型:常量字符指针 可空:Y - 意思:输入结束时间 + 意思:输入要查询的表明,为NULL所有 返回值 类型:逻辑型 意思:是否成功 -备注: +备注:返回假可能没有查找到,这条记录不存在.参数lpszFile和lpszMD5不能全为空 *********************************************************************/ -extern "C" BOOL XStorage_MySql_FileQueryForHash(XSTORAGECORE_DBFILE* pSt_FileInfo, LPCSTR lpszFileMD5, LPCSTR lpszUser = NULL, LPCSTR lpszTimeStart = NULL, LPCSTR lpszTimeEnd = NULL); +extern "C" BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCSTR lpszTimeStart = NULL, LPCSTR lpszTimeEnd = NULL, LPCTSTR lpszBuckKey = NULL, LPCSTR lpszFile = NULL, LPCSTR lpszHash = NULL, LPCTSTR lpszTableName = NULL); /************************************************************************/ /* SQLITE数据库函数 */ /************************************************************************/ @@ -214,12 +171,17 @@ extern "C" BOOL XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBManage); /******************************************************************** 函数名称:XStorage_SQLite_FileDelete 函数功能:删除一个数据库文件信息 - 参数.一:lpszFile + 参数.一:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:所属BUCK名称 + 参数.二:lpszFile In/Out:In 类型:常量字符指针 可空:Y 意思:要删除的文件全路径 - 参数.二:lpszHash + 参数.三:lpszHash In/Out:In 类型:常量字符指针 可空:Y @@ -229,7 +191,7 @@ extern "C" BOOL XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBManage); 意思:是否成功 备注:参数不能全为空,不会删除文件 *********************************************************************/ -extern "C" BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); +extern "C" BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); /******************************************************************** 函数名称:XStorage_SQLite_FileQuery 函数功能:查询文件信息 @@ -253,43 +215,139 @@ extern "C" BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszFile = NULL, LPCTSTR lpsz 类型:常量字符指针 可空:Y 意思:查找结束时间,20190730 - 参数.五:lpszFile + 参数.五:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:查询的BUCK名 + 参数.六:lpszFile In/Out:In 类型:常量字符指针 可空:Y 意思:要查询的名称 - 参数.六:lpszHash + 参数.七:lpszHash In/Out:In 类型:常量字符指针 可空:Y 意思:要查询的文件HASH + 参数.八:lpszTableName + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入要查询的表明,为NULL所有 返回值 类型:逻辑型 意思:是否成功 备注:返回假可能没有查找到,这条记录不存在.参数lpszFile和lpszHash不能全为空 *********************************************************************/ -extern "C" BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); +extern "C" BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL, LPCTSTR lpszTableName = NULL); +/************************************************************************/ +/* SQL帮助函数集 */ +/************************************************************************/ /******************************************************************** -函数名称:XStorage_SQLite_FileQueryForTable -函数功能:通过指定表名称查询所有文件 - 参数.一:pppSt_ListFile +函数名称:XStorage_SQLHelp_Insert +函数功能:数据插入函数 + 参数.一:ptszSQLBuffer In/Out:Out - 类型:三级指针 + 类型:字符指针 可空:N - 意思:输出查询到的文件信息 - 参数.二:pInt_ListCount - In/Out:Out - 类型:三级指针 + 意思:输出打好包的插入语句 + 参数.二:pSt_DBFile + In/Out:In + 类型:数据结构指针 + 可空:N + 意思:输入要插入的数据 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL XStorage_SQLHelp_Insert(TCHAR* ptszSQLBuffer, XSTORAGECORE_DBFILE* pSt_DBFile); +/******************************************************************** +函数名称:XStorage_SQLHelp_Delete +函数功能:删除语句 + 参数.一:ptszSQLBuffer + In/Out:In + 类型:字符指针 可空:N - 意思:导出获取到的列表个数 - 参数.三:lpszTableName + 意思:输出打好包的查询语句 + 参数.二:lpszTableName + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入要查询的表名称 + 参数.三:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入BUCKET名 + 参数.四:lpszFileName + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件名称 + 参数.五:lpszFileHash In/Out:In 类型:常量字符指针 + 可空:Y + 意思:输入文件HASH值 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL XStorage_SQLHelp_Delete(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFileName = NULL, LPCTSTR lpszFileHash = NULL); +/******************************************************************** +函数名称:XStorage_SQLHelp_Query +函数功能:数据库查询打包函数 + 参数.一:ptszSQLBuffer + In/Out:In + 类型:字符指针 可空:N + 意思:输出打好包的查询语句 + 参数.二:lpszTableName + In/Out:In + 类型:常量字符指针 + 可空:Y 意思:输入要查询的表名称 + 参数.三:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入BUCKET名 + 参数.四:lpszFilePath + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件路径 + 参数.五:lpszFileName + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件名称 + 参数.六:lpszFileHash + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件HASH值 + 参数.七:lpszFileUser + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件所属用户 + 参数.八:lpszTimeStart + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件开始时间范围 + 参数.九:lpszTimeEnd + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入文件结束时间范围 返回值 类型:逻辑型 意思:是否成功 -备注:参数一需要调用基础库的内存释放函数进行释放内存 +备注: *********************************************************************/ -extern "C" BOOL XStorage_SQLite_FileQueryForTable(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName); \ No newline at end of file +extern "C" BOOL XStorage_SQLHelp_Query(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFilePath = NULL, LPCTSTR lpszFileName = NULL, LPCTSTR lpszFileHash = NULL, LPCTSTR lpszFileUser = NULL, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL); \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Error.h b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Error.h index ad04d44..822132d 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Error.h +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Error.h @@ -18,8 +18,4 @@ #define ERROR_XENGINE_XSTROGE_CORE_DB_INSERTFILE_PARAMENT 0x130B0010 //参数错误 #define ERROR_XENGINE_XSTROGE_CORE_DB_DELETEFILE_PARAMENT 0x130B0020 //参数错误 #define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILE_PARAMENT 0x130B0030 //参数错误 -#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILE_EMPTY 0x130B0031 //查找数据为空 -#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_PARAMENT 0x130B00B1//参数错误 -#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_EMPTY 0x130B00B2 //空的表 -#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYMD5_PARAMENT 0x130B00D0 //参数错误 -#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYMD5_NOTFOUND 0x130B00D1 //没有找到 \ No newline at end of file +#define ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILE_EMPTY 0x130B0031 //查找数据为空 \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp index 080e038..3ac422e 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp @@ -137,24 +137,9 @@ BOOL CXStorage_MySql::XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBFile) } BaseLib_OperatorMemory_Free((void***)&ppSt_ListFile, nListCount); TCHAR tszSQLStatement[2048]; - TCHAR tszTableName[64]; - XENGINE_LIBTIMER st_LibTimer; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - memset(tszTableName, '\0', sizeof(tszTableName)); - memset(&st_LibTimer, '\0', sizeof(XENGINE_LIBTIMER)); - //òڱ - BaseLib_OperatorTime_GetSysTime(&st_LibTimer); - if (_tcslen(pSt_DBFile->tszTableName) > 0) - { - _tcscpy(tszTableName, pSt_DBFile->tszTableName); - } - else - { - _stprintf_s(tszTableName, _T("%04d%02d"), st_LibTimer.wYear, st_LibTimer.wMonth); - } - // - _stprintf_s(tszSQLStatement, _T("INSERT INTO `%s` (BuckKey,FilePath,FileName,FileHash,FileUser,FileSize,FileTime) VALUES('%s','%s','%s','%s','%s',%lld,now())"), tszTableName, pSt_DBFile->tszBuckKey, pSt_DBFile->st_ProtocolFile.tszFilePath, pSt_DBFile->st_ProtocolFile.tszFileName, pSt_DBFile->st_ProtocolFile.tszFileHash, pSt_DBFile->st_ProtocolFile.tszFileUser, pSt_DBFile->st_ProtocolFile.nFileSize); + + XStorage_SQLHelp_Insert(tszSQLStatement, pSt_DBFile); if (!DataBase_MySQL_Execute(xhDBSQL, tszSQLStatement)) { XStorage_IsErrorOccur = TRUE; @@ -166,12 +151,17 @@ BOOL CXStorage_MySql::XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBFile) /******************************************************************** ƣXStorage_MySql_FileDelete ܣɾһݿļϢ - .һlpszFile + .һlpszBuckKey + In/OutIn + ַָͣ + ɿգY + ˼BUCK + .lpszFile In/OutIn ַָͣ ɿգY ˼Ҫɾļȫ· - .lpszHash + .lpszHash In/OutIn ַָͣ ɿգY @@ -181,7 +171,7 @@ BOOL CXStorage_MySql::XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBFile) ˼Ƿɹ עȫΪ,ɾļ *********************************************************************/ -BOOL CXStorage_MySql::XStorage_MySql_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHash) +BOOL CXStorage_MySql::XStorage_MySql_FileDelete(LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */) { XStorage_IsErrorOccur = FALSE; @@ -191,7 +181,6 @@ BOOL CXStorage_MySql::XStorage_MySql_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHa XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_DELETEFILE_PARAMENT; return FALSE; } - TCHAR tszSQLStatement[1024]; int nListCount = 0; XSTORAGECORE_DBFILE **ppSt_ListFile; if (!XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, NULL, NULL, lpszFile, lpszHash)) @@ -201,15 +190,10 @@ BOOL CXStorage_MySql::XStorage_MySql_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHa //ѵɾ for (int i = 0; i < nListCount; i++) { - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - if (NULL == lpszHash) - { - _stprintf_s(tszSQLStatement, _T("DELETE FROM `%s` WHERE FileName = '%s'"), ppSt_ListFile[i]->tszTableName, ppSt_ListFile[i]->st_ProtocolFile.tszFileName); - } - else - { - _stprintf_s(tszSQLStatement, _T("DELETE FROM `%s` WHERE FileHash = '%s'"), ppSt_ListFile[i]->tszTableName, ppSt_ListFile[i]->st_ProtocolFile.tszFileHash); - } + TCHAR tszSQLStatement[1024]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + XStorage_SQLHelp_Delete(tszSQLStatement, ppSt_ListFile[i]->tszTableName, lpszBuckKey, lpszFile, lpszHash); + if (!DataBase_MySQL_Execute(xhDBSQL, tszSQLStatement)) { XStorage_IsErrorOccur = TRUE; @@ -243,22 +227,32 @@ BOOL CXStorage_MySql::XStorage_MySql_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHa ַָͣ ɿգY ˼ҽʱ,20190730 - .壺lpszFile + .壺lpszBuckKey + In/OutIn + ַָͣ + ɿգY + ˼ѯBUCK + .lpszFile In/OutIn ַָͣ ɿգY ˼Ҫѯ - .lpszHash + .ߣlpszHash In/OutIn ַָͣ ɿգY ˼ҪѯļHASH + .ˣlpszTableName + In/OutIn + ַָͣ + ɿգY + ˼Ҫѯı,ΪNULL ֵ ͣ߼ ˼Ƿɹ עؼٿûвҵ,¼.lpszFilelpszHashȫΪ *********************************************************************/ -BOOL CXStorage_MySql::XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */) +BOOL CXStorage_MySql::XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */, LPCTSTR lpszTableName /* = NULL */) { XStorage_IsErrorOccur = FALSE; @@ -272,121 +266,147 @@ BOOL CXStorage_MySql::XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_List XHDATA xhTable = 0; __int64u nllLine = 0; __int64u nllRow = 0; + list stl_ListFile; + TCHAR tszSQLStatement[1024]; memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //Ƿʱ䷶Χ - if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) - { - if (_tcslen(lpszTimeStart) > 0 && _tcslen(lpszTimeEnd) > 0) - { - _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage' AND TABLE_NAME BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage'")); - } - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage'")); - } - if (!DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhTable, tszSQLStatement, &nllLine, &nllRow)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = DataBase_GetLastError(); - return FALSE; - } - list stl_ListFile; - //ѵ - for (__int64u i = 0; i < nllLine; i++) - { - TCHAR **pptszResult = DataBase_MySQL_GetResult(xhDBSQL, xhTable); - if (NULL == pptszResult[0]) - { - continue; - } - __int64u dwLineResult = 0; - __int64u dwFieldResult = 0; - XNETHANDLE xhResult; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //жϲѯʽ - if (NULL != lpszFile) - { - if (_tcslen(lpszFile) > 0) - { - TCHAR tszFilePath[MAX_PATH]; - TCHAR tszFileName[MAX_PATH]; - - memset(tszFilePath, '\0', MAX_PATH); - memset(tszFileName, '\0', MAX_PATH); - BaseLib_OperatorString_GetFileAndPath(lpszFile, tszFilePath, tszFileName); - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FilePath = '%s' AND FileName = '%s'"), pptszResult[0], tszFilePath, tszFileName); - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), pptszResult[0]); - } - } - if (NULL != lpszHash) - { - if (_tcslen(lpszHash) > 0) + if (NULL == lpszTableName) + { + //Ƿʱ䷶Χ + if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) + { + if (_tcslen(lpszTimeStart) > 0 && _tcslen(lpszTimeEnd) > 0) { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FileHash = '%s'"), pptszResult[0], lpszHash); + _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage' AND TABLE_NAME BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); } else { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), pptszResult[0]); + _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage'")); } - } - //ѯļ - if (DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhResult, tszSQLStatement, &dwLineResult, &dwFieldResult)) - { - //ѭȡвҵļ - for (__int64u j = 0; j < dwLineResult; j++) - { - TCHAR **pptszFileResult = DataBase_MySQL_GetResult(xhDBSQL, xhResult); + } + else + { + _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XEngine_Storage'")); + } + if (!DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhTable, tszSQLStatement, &nllLine, &nllRow)) + { + XStorage_IsErrorOccur = TRUE; + XStorage_dwErrorCode = DataBase_GetLastError(); + return FALSE; + } + //ѵ + for (__int64u i = 0; i < nllLine; i++) + { + TCHAR** pptszResult = DataBase_MySQL_GetResult(xhDBSQL, xhTable); + if (NULL == pptszResult[0]) + { + continue; + } + __int64u dwLineResult = 0; + __int64u dwFieldResult = 0; + XNETHANDLE xhResult; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + + XStorage_SQLHelp_Query(tszSQLStatement, pptszResult[0], lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); + //ѯļ + if (DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhResult, tszSQLStatement, &dwLineResult, &dwFieldResult)) + { + //ѭȡвҵļ + for (__int64u j = 0; j < dwLineResult; j++) + { + TCHAR** pptszFileResult = DataBase_MySQL_GetResult(xhDBSQL, xhResult); + + XSTORAGECORE_DBFILE st_DBFile; + memset(&st_DBFile, '\0', sizeof(XSTORAGECORE_DBFILE)); + + _tcscpy(st_DBFile.tszTableName, pptszResult[0]); + + if (NULL != pptszFileResult[1]) + { + _tcscpy(st_DBFile.tszBuckKey, pptszFileResult[1]); + } + if (NULL != pptszFileResult[2]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[2]); + } + if (NULL != pptszFileResult[3]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileName, pptszFileResult[3]); + } + if (NULL != pptszFileResult[4]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileHash, pptszFileResult[4]); + } + if (NULL != pptszFileResult[5]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileUser, pptszFileResult[5]); + } + if (NULL != pptszFileResult[6]) + { + st_DBFile.st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[6]); + } + if (NULL != pptszFileResult[7]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileTime, pptszFileResult[7]); + } + stl_ListFile.push_back(st_DBFile); + } + DataBase_MySQL_FreeResult(xhDBSQL, xhResult); + } + } + DataBase_MySQL_FreeResult(xhDBSQL, xhTable); + } + else + { + XStorage_SQLHelp_Query(tszSQLStatement, lpszTableName, lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); + //ѯļ + if (DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhTable, tszSQLStatement, &nllLine, &nllRow)) + { + //ѭȡвҵļ + for (__int64u i = 0; i < nllLine; i++) + { + TCHAR** pptszFileResult = DataBase_MySQL_GetResult(xhDBSQL, xhTable); - XSTORAGECORE_DBFILE st_DBFile; - memset(&st_DBFile, '\0', sizeof(XSTORAGECORE_DBFILE)); + XSTORAGECORE_DBFILE st_DBFile; + memset(&st_DBFile, '\0', sizeof(XSTORAGECORE_DBFILE)); - _tcscpy(st_DBFile.tszTableName, pptszResult[0]); + _tcscpy(st_DBFile.tszTableName, lpszTableName); if (NULL != pptszFileResult[1]) { _tcscpy(st_DBFile.tszBuckKey, pptszFileResult[1]); } - if (NULL != pptszFileResult[2]) - { - _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[2]); - } - if (NULL != pptszFileResult[3]) - { - _tcscpy(st_DBFile.st_ProtocolFile.tszFileName, pptszFileResult[3]); - } + if (NULL != pptszFileResult[2]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[2]); + } + if (NULL != pptszFileResult[3]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileName, pptszFileResult[3]); + } if (NULL != pptszFileResult[4]) { _tcscpy(st_DBFile.st_ProtocolFile.tszFileHash, pptszFileResult[4]); } - if (NULL != pptszFileResult[5]) - { - _tcscpy(st_DBFile.st_ProtocolFile.tszFileUser, pptszFileResult[5]); - } - if (NULL != pptszFileResult[6]) - { - st_DBFile.st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[6]); - } - if (NULL != pptszFileResult[7]) - { - _tcscpy(st_DBFile.st_ProtocolFile.tszFileTime, pptszFileResult[7]); - } - stl_ListFile.push_back(st_DBFile); - } - DataBase_MySQL_FreeResult(xhDBSQL, xhResult); - } + if (NULL != pptszFileResult[5]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileUser, pptszFileResult[5]); + } + if (NULL != pptszFileResult[6]) + { + st_DBFile.st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[6]); + } + if (NULL != pptszFileResult[7]) + { + _tcscpy(st_DBFile.st_ProtocolFile.tszFileTime, pptszFileResult[7]); + } + stl_ListFile.push_back(st_DBFile); + } + DataBase_MySQL_FreeResult(xhDBSQL, xhTable); + } } - DataBase_MySQL_FreeResult(xhDBSQL, xhTable); - + //ǷΪ if (stl_ListFile.empty()) { XStorage_IsErrorOccur = TRUE; @@ -404,237 +424,6 @@ BOOL CXStorage_MySql::XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_List stl_ListFile.clear(); return TRUE; } -/******************************************************************** -ƣXStorage_MySql_FileQueryForTable -ܣָͨƲѯļ - .һpppSt_ListFile - In/OutOut - ָͣ - ɿգN - ˼ѯļϢ - .pInt_ListCount - In/OutOut - ָͣ - ɿգN - ˼ȡб - .lpszTableName - In/OutIn - ַָͣ - ɿգN - ˼Ҫѯı -ֵ - ͣ߼ - ˼Ƿɹ -עһҪûڴͷźͷڴ -*********************************************************************/ -BOOL CXStorage_MySql::XStorage_MySql_FileQueryForTable(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName) -{ - XStorage_IsErrorOccur = FALSE; - - if ((NULL == pppSt_ListFile) || (NULL == pInt_ListCount) || (NULL == lpszTableName)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_PARAMENT; - return FALSE; - } - //ѯ - XHDATA xhTable = 0; - __int64u nllLine = 0; - __int64u nllRow = 0; - - TCHAR tszSQLStatement[1024]; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //Ƿʱ䷶Χ - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), lpszTableName); - DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhTable, tszSQLStatement, &nllLine, &nllRow); - if (nllLine <= 0) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_EMPTY; - return FALSE; - } - BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_ListFile, (int)nllLine, sizeof(XSTORAGECORE_DBFILE)); - //ѭȡвҵļ - for (__int64u i = 0; i < nllLine; i++) - { - TCHAR** pptszFileResult = DataBase_MySQL_GetResult(xhDBSQL, xhTable); - - _tcscpy((*pppSt_ListFile)[i]->tszTableName, lpszTableName); - - if (NULL != pptszFileResult[1]) - { - _tcscpy((*pppSt_ListFile)[i]->tszBuckKey, pptszFileResult[1]); - } - if (NULL != pptszFileResult[2]) - { - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFilePath, pptszFileResult[2]); - } - if (NULL != pptszFileResult[3]) - { - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileName, pptszFileResult[3]); - } - if (NULL != pptszFileResult[4]) - { - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileHash, pptszFileResult[4]); - } - if (NULL != pptszFileResult[5]) - { - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileUser, pptszFileResult[5]); - } - if (NULL != pptszFileResult[6]) - { - (*pppSt_ListFile)[i]->st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[6]); - } - if (NULL != pptszFileResult[7]) - { - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileTime, pptszFileResult[7]); - } - } - DataBase_MySQL_FreeResult(xhDBSQL, xhTable); - *pInt_ListCount = (int)nllLine; - return TRUE; -} -/******************************************************************** -ƣXStorage_MySql_FileQueryForHash -ܣͨMD5ѯļϢ - .һpSt_FileInfo - In/OutOut - ͣݽṹָ - ɿգN - ˼ѯļϢ - .lpszFileHash - In/OutIn - ַָͣ - ɿգN - ˼ҪѯļMD5 - .lpszUser - In/OutIn - ַָͣ - ɿգN - ˼ļû - .ģlpszTimeStart - In/OutIn - ַָͣ - ɿգY - ˼뿪ʼʱ - .壺lpszTimeEnd - In/OutIn - ַָͣ - ɿգY - ˼ʱ -ֵ - ͣ߼ - ˼Ƿɹ -ע -*********************************************************************/ -BOOL CXStorage_MySql::XStorage_MySql_FileQueryForHash(XSTORAGECORE_DBFILE* pSt_FileInfo, LPCTSTR lpszFileHash, LPCTSTR lpszUser, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd) -{ - XStorage_IsErrorOccur = FALSE; - - if ((NULL == pSt_FileInfo) || (NULL == lpszFileHash)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYMD5_PARAMENT; - return FALSE; - } - //ѯ - XHDATA xhTable = 0; - __int64u nllLine = 0; - __int64u nllRow = 0; - BOOL bFound = FALSE; - TCHAR tszSQLStatement[1024]; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //Ƿʱ䷶Χ - if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) - { - _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XStorage_Storage' AND TABLE_NAME BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'XStorage_Storage'")); - } - if (!DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhTable, tszSQLStatement, &nllLine, &nllRow)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = DataBase_GetLastError(); - return FALSE; - } - //ѵ - for (__int64u i = 0; i < nllLine; i++) - { - TCHAR** pptszResult = DataBase_MySQL_GetResult(xhDBSQL, xhTable); - if (NULL == pptszResult[0]) - { - continue; - } - __int64u dwLineResult = 0; - __int64u dwFieldResult = 0; - XNETHANDLE xhResult; - - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //жϲѯʽ - if (NULL == lpszUser) - { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FileHash = '%s'"), pptszResult[0], lpszFileHash); - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FileHash = '%s' AND FileUser = '%s'"), pptszResult[0], lpszFileHash, lpszUser); - } - //ѯļ - if (DataBase_MySQL_ExecuteQuery(xhDBSQL, &xhResult, tszSQLStatement, &dwLineResult, &dwFieldResult)) - { - //ѭȡвҵļ - for (__int64u j = 0; j < dwLineResult; j++) - { - TCHAR** pptszFileResult = DataBase_MySQL_GetResult(xhDBSQL, xhResult); - - _tcscpy(pSt_FileInfo->tszTableName, pptszResult[0]); - - if (NULL != pptszFileResult[1]) - { - _tcscpy(pSt_FileInfo->tszBuckKey, pptszFileResult[1]); - } - if (NULL != pptszFileResult[2]) - { - _tcscpy(pSt_FileInfo->st_ProtocolFile.tszFilePath, pptszFileResult[2]); - } - if (NULL != pptszFileResult[3]) - { - _tcscpy(pSt_FileInfo->st_ProtocolFile.tszFileName, pptszFileResult[3]); - } - if (NULL != pptszFileResult[4]) - { - _tcscpy(pSt_FileInfo->st_ProtocolFile.tszFileUser, pptszFileResult[4]); - } - if (NULL != pptszFileResult[5]) - { - pSt_FileInfo->st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[5]); - } - if (NULL != pptszFileResult[6]) - { - _tcscpy(pSt_FileInfo->st_ProtocolFile.tszFileHash, pptszFileResult[6]); - } - if (NULL != pptszFileResult[7]) - { - _tcscpy(pSt_FileInfo->st_ProtocolFile.tszFileTime, pptszFileResult[7]); - } - bFound = TRUE; - break; - } - DataBase_MySQL_FreeResult(xhDBSQL, xhResult); - } - } - DataBase_MySQL_FreeResult(xhDBSQL, xhTable); - - if (!bFound) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYMD5_NOTFOUND; - return FALSE; - } - return TRUE; -} ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// @@ -771,8 +560,7 @@ BOOL CXStorage_MySql::XStorage_MySql_TimeDel() //ɾļ int nListCount = 0; XSTORAGECORE_DBFILE **ppSt_ListFile; - XStorage_MySql_FileQueryForTable(&ppSt_ListFile, &nListCount, pptszResult[0]); - + XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, NULL, NULL, NULL, NULL, NULL, pptszResult[0]); for (int i = 0; i < nListCount; i++) { //ɾļ diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.h b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.h index 40e5ee1..d98ade3 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.h +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.h @@ -20,10 +20,8 @@ public: BOOL XStorage_MySql_Init(DATABASE_MYSQL_CONNECTINFO* pSt_DBConnector, int nTimeMonth = 1); BOOL XStorage_MySql_Destory(); BOOL XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE *pSt_DBManage); - BOOL XStorage_MySql_FileDelete(LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); - BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); - BOOL XStorage_MySql_FileQueryForTable(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName); - BOOL XStorage_MySql_FileQueryForHash(XSTORAGECORE_DBFILE* pSt_FileInfo, LPCTSTR lpszFileHash, LPCTSTR lpszUser = NULL, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL); + BOOL XStorage_MySql_FileDelete(LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); + BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL, LPCTSTR lpszTableName = NULL); protected: BOOL XStorage_MySql_CreateTable(); BOOL XStorage_MySql_TimeMonth(LPCTSTR lpszStartTime, int* pInt_Month); diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLPacket.def b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLPacket.def index 71311ab..d1c6734 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLPacket.def +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLPacket.def @@ -8,12 +8,9 @@ EXPORTS XStorage_MySql_FileInsert XStorage_MySql_FileDelete XStorage_MySql_FileQuery - XStorage_MySql_FileQueryForTable - XStorage_MySql_FileQueryForHash XStorage_SQLite_Init XStorage_SQLite_Destory XStorage_SQLite_FileInsert XStorage_SQLite_FileDelete - XStorage_SQLite_FileQuery - XStorage_SQLite_FileQueryForTable \ No newline at end of file + XStorage_SQLite_FileQuery \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp index 8e647d5..1f81bf8 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp @@ -136,25 +136,10 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBFil return TRUE; } BaseLib_OperatorMemory_Free((void***)&ppSt_ListFile, nListCount); - TCHAR tszSQLStatement[2048]; - TCHAR tszTableName[64]; - XENGINE_LIBTIMER st_LibTimer; + TCHAR tszSQLStatement[2048]; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - memset(tszTableName, '\0', sizeof(tszTableName)); - memset(&st_LibTimer, '\0', sizeof(XENGINE_LIBTIMER)); - //获得插入日期表 - BaseLib_OperatorTime_GetSysTime(&st_LibTimer); - if (_tcslen(pSt_DBFile->tszTableName) > 0) - { - _tcscpy(tszTableName, pSt_DBFile->tszTableName); - } - else - { - _stprintf_s(tszTableName, _T("%04d%02d"), st_LibTimer.wYear, st_LibTimer.wMonth); - } - //插入语句 - _stprintf_s(tszSQLStatement, _T("INSERT INTO `%s` (BuckKey,FilePath,FileName,FileHash,FileUser,FileSize,FileTime) VALUES('%s','%s','%s','%s','%s',%lld,DATETIME('now', 'localtime'))"), tszTableName, pSt_DBFile->tszBuckKey, pSt_DBFile->st_ProtocolFile.tszFilePath, pSt_DBFile->st_ProtocolFile.tszFileName, pSt_DBFile->st_ProtocolFile.tszFileHash, pSt_DBFile->st_ProtocolFile.tszFileUser, pSt_DBFile->st_ProtocolFile.nFileSize); + XStorage_SQLHelp_Insert(tszSQLStatement, pSt_DBFile); if (!DataBase_SQLite_Exec(xhSQL, tszSQLStatement)) { XStorage_IsErrorOccur = TRUE; @@ -166,12 +151,17 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBFil /******************************************************************** 函数名称:XStorage_SQLite_FileDelete 函数功能:删除一个数据库文件信息 - 参数.一:lpszFile + 参数.一:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:所属BUCK名称 + 参数.二:lpszFile In/Out:In 类型:常量字符指针 可空:Y 意思:要删除的文件全路径 - 参数.二:lpszHash + 参数.三:lpszHash In/Out:In 类型:常量字符指针 可空:Y @@ -181,7 +171,7 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBFil 意思:是否成功 备注:参数不能全为空,不会删除文件 *********************************************************************/ -BOOL CXStorage_SQLite::XStorage_SQLite_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHash) +BOOL CXStorage_SQLite::XStorage_SQLite_FileDelete(LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */) { XStorage_IsErrorOccur = FALSE; @@ -191,25 +181,19 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileDelete(LPCTSTR lpszFile, LPCTSTR lpsz XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_DELETEFILE_PARAMENT; return FALSE; } - TCHAR tszSQLStatement[1024]; int nListCount = 0; XSTORAGECORE_DBFILE** ppSt_ListFile; - if (!XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, NULL, NULL, lpszFile, lpszHash)) + if (!XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, NULL, NULL, lpszBuckKey, lpszFile, lpszHash)) { return FALSE; } //轮训查找删除 for (int i = 0; i < nListCount; i++) { + TCHAR tszSQLStatement[1024]; memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - if (NULL == lpszHash) - { - _stprintf_s(tszSQLStatement, _T("DELETE FROM `%s` WHERE FileName = '%s'"), ppSt_ListFile[i]->tszTableName, ppSt_ListFile[i]->st_ProtocolFile.tszFileName); - } - else - { - _stprintf_s(tszSQLStatement, _T("DELETE FROM `%s` WHERE FileHash = '%s'"), ppSt_ListFile[i]->tszTableName, ppSt_ListFile[i]->st_ProtocolFile.tszFileHash); - } + XStorage_SQLHelp_Delete(tszSQLStatement, ppSt_ListFile[i]->tszTableName, lpszBuckKey, lpszFile, lpszHash); + if (!DataBase_SQLite_Exec(xhSQL, tszSQLStatement)) { XStorage_IsErrorOccur = TRUE; @@ -243,22 +227,32 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileDelete(LPCTSTR lpszFile, LPCTSTR lpsz 类型:常量字符指针 可空:Y 意思:查找结束时间,20190730 - 参数.五:lpszFile + 参数.五:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:查询的BUCK名 + 参数.六:lpszFile In/Out:In 类型:常量字符指针 可空:Y 意思:要查询的名称 - 参数.六:lpszHash + 参数.七:lpszHash In/Out:In 类型:常量字符指针 可空:Y 意思:要查询的文件HASH + 参数.八:lpszTableName + In/Out:In + 类型:常量字符指针 + 可空:Y + 意思:输入要查询的表明,为NULL所有 返回值 类型:逻辑型 意思:是否成功 备注:返回假可能没有查找到,这条记录不存在.参数lpszFile和lpszHash不能全为空 *********************************************************************/ -BOOL CXStorage_SQLite::XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */) +BOOL CXStorage_SQLite::XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFile /* = NULL */, LPCTSTR lpszHash /* = NULL */, LPCTSTR lpszTableName /* = NULL */) { XStorage_IsErrorOccur = FALSE; @@ -273,110 +267,126 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_Li int nRow = 0; TCHAR** pptszResult; TCHAR tszSQLStatement[1024]; + list stl_ListFile; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //检查是否时间范围检索 - if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) + if (NULL == lpszTableName) { - if (_tcslen(lpszTimeStart) > 0 && _tcslen(lpszTimeEnd) > 0) - { - _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table' AND NAME BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table'")); - } - } - else - { - _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table'")); - } - if (!DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszResult, &nLine, &nRow)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = DataBase_GetLastError(); - return FALSE; - } - list stl_ListFile; - //轮训 - for (int i = 0; i < nLine; i++) - { - if (!XStorage_SQLite_IsNumber(pptszResult[i])) - { - continue; - } - int nLineResult = 0; - int nFieldResult = 0; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //判断查询方式 - if (NULL != lpszFile) + //检查是否时间范围检索 + if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) { - if (_tcslen(lpszFile) > 0) + if (_tcslen(lpszTimeStart) > 0 && _tcslen(lpszTimeEnd) > 0) { - TCHAR tszFilePath[MAX_PATH]; - TCHAR tszFileName[MAX_PATH]; - - memset(tszFilePath, '\0', MAX_PATH); - memset(tszFileName, '\0', MAX_PATH); - - BaseLib_OperatorString_GetFileAndPath(lpszFile, tszFilePath, tszFileName); - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FilePath = '%s' AND FileName = '%s'"), pptszResult[i], tszFilePath, tszFileName); + _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table' AND NAME BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); } else { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), pptszResult[i]); + _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table'")); } } - if (NULL != lpszHash) + else + { + _stprintf_s(tszSQLStatement, _T("SELECT NAME FROM SQLITE_MASTER WHERE TYPE = 'table'")); + } + if (!DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszResult, &nLine, &nRow)) { - if (_tcslen(lpszHash) > 0) + XStorage_IsErrorOccur = TRUE; + XStorage_dwErrorCode = DataBase_GetLastError(); + return FALSE; + } + //轮训 + for (int i = 0; i < nLine; i++) + { + if (!XStorage_SQLite_IsNumber(pptszResult[i])) { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s` WHERE FileHash = '%s'"), pptszResult[i], lpszHash); + continue; } - else + int nLineResult = 0; + int nFieldResult = 0; + memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); + XStorage_SQLHelp_Query(tszSQLStatement, pptszResult[0], lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); + //查询文件 + TCHAR** pptszFileResult; + if (DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszFileResult, &nLineResult, &nFieldResult)) { - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), pptszResult[i]); + int nFiled = nFieldResult; + //循环获取所有查找到的文件 + for (int j = 0; j < nLineResult; j++) + { + XSTORAGECORE_DBFILE st_DBFile; + memset(&st_DBFile, '\0', sizeof(XSTORAGECORE_DBFILE)); + + _tcscpy(st_DBFile.tszTableName, pptszResult[i]); + nFiled++; + + _tcscpy(st_DBFile.tszBuckKey, pptszFileResult[nFiled]); + nFiled++; + + _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[nFiled]); + nFiled++; + + _tcscpy(st_DBFile.st_ProtocolFile.tszFileName, pptszFileResult[nFiled]); + nFiled++; + + _tcscpy(st_DBFile.st_ProtocolFile.tszFileHash, pptszFileResult[nFiled]); + nFiled++; + + _tcscpy(st_DBFile.st_ProtocolFile.tszFileUser, pptszFileResult[nFiled]); + nFiled++; + + st_DBFile.st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[nFiled]); + nFiled++; + + _tcscpy(st_DBFile.st_ProtocolFile.tszFileTime, pptszFileResult[nFiled]); + nFiled++; + stl_ListFile.push_back(st_DBFile); + } + DataBase_SQLite_FreeTable(pptszFileResult); } } - //查询文件 - TCHAR** pptszFileResult; - if (DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszFileResult, &nLineResult, &nFieldResult)) + DataBase_SQLite_FreeTable(pptszResult); + } + else + { + XStorage_SQLHelp_Query(tszSQLStatement, lpszTableName, lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); + TCHAR** pptszFileResult; + if (DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszFileResult, &nLine, &nRow)) { - int nFiled = nFieldResult; + int nFiled = nRow; //循环获取所有查找到的文件 - for (int j = 0; j < nLineResult; j++) + for (int i = 0; i < nLine; i++) { XSTORAGECORE_DBFILE st_DBFile; memset(&st_DBFile, '\0', sizeof(XSTORAGECORE_DBFILE)); - _tcscpy(st_DBFile.tszTableName, pptszResult[i]); - nFiled++; + _tcscpy(st_DBFile.tszTableName, lpszTableName); + nFiled++; _tcscpy(st_DBFile.tszBuckKey, pptszFileResult[nFiled]); nFiled++; - _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[nFiled]); - nFiled++; + _tcscpy(st_DBFile.st_ProtocolFile.tszFilePath, pptszFileResult[nFiled]); + nFiled++; _tcscpy(st_DBFile.st_ProtocolFile.tszFileName, pptszFileResult[nFiled]); nFiled++; _tcscpy(st_DBFile.st_ProtocolFile.tszFileHash, pptszFileResult[nFiled]); nFiled++; - + _tcscpy(st_DBFile.st_ProtocolFile.tszFileUser, pptszFileResult[nFiled]); nFiled++; st_DBFile.st_ProtocolFile.nFileSize = _ttoi64(pptszFileResult[nFiled]); nFiled++; - + _tcscpy(st_DBFile.st_ProtocolFile.tszFileTime, pptszFileResult[nFiled]); nFiled++; stl_ListFile.push_back(st_DBFile); } DataBase_SQLite_FreeTable(pptszFileResult); } - } - DataBase_SQLite_FreeTable(pptszResult); + } if (stl_ListFile.empty()) { XStorage_IsErrorOccur = TRUE; @@ -394,88 +404,6 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_Li stl_ListFile.clear(); return TRUE; } -/******************************************************************** -函数名称:XStorage_SQLite_FileQueryForTable -函数功能:通过指定表名称查询所有文件 - 参数.一:pppSt_ListFile - In/Out:Out - 类型:三级指针 - 可空:N - 意思:输出查询到的文件信息 - 参数.二:pInt_ListCount - In/Out:Out - 类型:三级指针 - 可空:N - 意思:导出获取到的列表个数 - 参数.三:lpszTableName - In/Out:In - 类型:常量字符指针 - 可空:N - 意思:输入要查询的表名称 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注:参数一需要调用基础库的内存释放函数进行释放内存 -*********************************************************************/ -BOOL CXStorage_SQLite::XStorage_SQLite_FileQueryForTable(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName) -{ - XStorage_IsErrorOccur = FALSE; - - if ((NULL == pppSt_ListFile) || (NULL == pInt_ListCount) || (NULL == lpszTableName)) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_PARAMENT; - return FALSE; - } - //查询 - XHDATA xhTable = 0; - int nLine = 0; - int nRow = 0; - TCHAR** pptszResulte; - TCHAR tszSQLStatement[1024]; - memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - //检查是否时间范围检索 - _stprintf_s(tszSQLStatement, _T("SELECT * FROM `%s`"), lpszTableName); - DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszResulte, &nLine, &nRow); - if (nLine <= 0) - { - XStorage_IsErrorOccur = TRUE; - XStorage_dwErrorCode = ERROR_XENGINE_XSTROGE_CORE_DB_QUERYFILETABLE_EMPTY; - return FALSE; - } - *pInt_ListCount = nLine; - BaseLib_OperatorMemory_Malloc((XPPPMEM)pppSt_ListFile, nLine, sizeof(XSTORAGECORE_DBFILE)); - //循环获取所有查找到的文件 - int nFiled = nRow; - for (int i = 0; i < nLine; i++) - { - nFiled++; - _tcscpy((*pppSt_ListFile)[i]->tszTableName, lpszTableName); - - _tcscpy((*pppSt_ListFile)[i]->tszBuckKey, pptszResulte[nFiled]); - nFiled++; - - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFilePath, pptszResulte[nFiled]); - nFiled++; - - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileName, pptszResulte[nFiled]); - nFiled++; - - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileHash, pptszResulte[nFiled]); - nFiled++; - - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileUser, pptszResulte[nFiled]); - nFiled++; - - (*pppSt_ListFile)[i]->st_ProtocolFile.nFileSize = _ttoi64(pptszResulte[nFiled]); - nFiled++; - - _tcscpy((*pppSt_ListFile)[i]->st_ProtocolFile.tszFileTime, pptszResulte[nFiled]); - nFiled++; - } - DataBase_MySQL_FreeResult(xhSQL, xhTable); - return TRUE; -} ////////////////////////////////////////////////////////////////////////// // 保护函数 ////////////////////////////////////////////////////////////////////////// @@ -612,7 +540,7 @@ BOOL CXStorage_SQLite::XStorage_SQLite_TimeDel() //删除文件 int nListCount = 0; XSTORAGECORE_DBFILE** ppSt_ListFile; - XStorage_SQLite_FileQueryForTable(&ppSt_ListFile, &nListCount, pptszResult[i]); + XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, NULL, NULL, NULL, NULL, NULL, pptszResult[i]); for (int i = 0; i < nListCount; i++) { //删除文件 diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.h b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.h index 5472654..bbf2e20 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.h +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.h @@ -21,9 +21,8 @@ public: BOOL XStorage_SQLite_Init(LPCTSTR lpszSQLFile, int nTimeMonth = 1); BOOL XStorage_SQLite_Destory(); BOOL XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE* pSt_DBManage); - BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); - BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); - BOOL XStorage_SQLite_FileQueryForTable(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName); + BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL); + BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFile = NULL, LPCTSTR lpszHash = NULL, LPCTSTR lpszTableName = NULL); protected: BOOL XStorage_SQLite_CreateTable(); BOOL XStorage_SQLite_TimeMonth(LPCTSTR lpszStartTime, int* pInt_Month); diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/pch.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/pch.cpp index 8df24de..1b9118a 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/pch.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/pch.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "XStorage_MySql/XStorage_MySql.h" #include "XStorage_SQLite/XStorage_SQLite.h" +#include "XStorage_SQLHelp/XStorage_SQLHelp.h" /******************************************************************** // Created: 2021/06/10 11:10:16 // File Name: D:\XEngine_Storage\XEngine_Source\XEngine_StorageComponents\XStorage_SQLPacket\pch.cpp @@ -17,6 +18,7 @@ DWORD XStorage_dwErrorCode = 0; ////////////////////////////////////////////////////////////////////////// CXStorage_MySql m_MySql; CXStorage_SQLite m_SQLite; +CXStorage_SQLHelp m_SQLHelp; ////////////////////////////////////////////////////////////////////////// /// 导出的函数 ////////////////////////////////////////////////////////////////////////// @@ -43,21 +45,13 @@ extern "C" BOOL XStorage_MySql_FileInsert(XSTORAGECORE_DBFILE * pSt_DBManage) { return m_MySql.XStorage_MySql_FileInsert(pSt_DBManage); } -extern "C" BOOL XStorage_MySql_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHash) +extern "C" BOOL XStorage_MySql_FileDelete(LPCTSTR lpszBuckKey, LPCTSTR lpszFile, LPCTSTR lpszHash) { - return m_MySql.XStorage_MySql_FileDelete(lpszFile, lpszHash); + return m_MySql.XStorage_MySql_FileDelete(lpszBuckKey, lpszFile, lpszHash); } -extern "C" BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd, LPCTSTR lpszFile, LPCTSTR lpszHash) +extern "C" BOOL XStorage_MySql_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd, LPCTSTR lpszBuckKey, LPCTSTR lpszFile, LPCTSTR lpszHash, LPCTSTR lpszTableName) { - return m_MySql.XStorage_MySql_FileQuery(pppSt_ListFile, pInt_ListCount, lpszTimeStart, lpszTimeEnd, lpszFile, lpszHash); -} -extern "C" BOOL XStorage_MySql_FileQueryForTable(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName) -{ - return m_MySql.XStorage_MySql_FileQueryForTable(pppSt_ListFile, pInt_ListCount, lpszTableName); -} -extern "C" BOOL XStorage_MySql_FileQueryForHash(XSTORAGECORE_DBFILE * pSt_FileInfo, LPCTSTR lpszFileMD5, LPCTSTR lpszUser, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd) -{ - return m_MySql.XStorage_MySql_FileQueryForHash(pSt_FileInfo, lpszFileMD5, lpszUser, lpszTimeStart, lpszTimeEnd); + return m_MySql.XStorage_MySql_FileQuery(pppSt_ListFile, pInt_ListCount, lpszTimeStart, lpszTimeEnd, lpszBuckKey, lpszFile, lpszHash, lpszTableName); } /************************************************************************/ /* SQLITE数据库函数 */ @@ -74,15 +68,26 @@ extern "C" BOOL XStorage_SQLite_FileInsert(XSTORAGECORE_DBFILE * pSt_DBManage) { return m_SQLite.XStorage_SQLite_FileInsert(pSt_DBManage); } -extern "C" BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszFile, LPCTSTR lpszHash) +extern "C" BOOL XStorage_SQLite_FileDelete(LPCTSTR lpszBuckKey, LPCTSTR lpszFile, LPCTSTR lpszHash) +{ + return m_SQLite.XStorage_SQLite_FileDelete(lpszBuckKey, lpszFile, lpszHash); +} +extern "C" BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd, LPCTSTR lpszBuckKey, LPCTSTR lpszFile, LPCTSTR lpszHash, LPCTSTR lpszTableName) +{ + return m_SQLite.XStorage_SQLite_FileQuery(pppSt_ListFile, pInt_ListCount, lpszTimeStart, lpszTimeEnd, lpszBuckKey, lpszFile, lpszHash, lpszTableName); +} +/************************************************************************/ +/* SQL帮助函数集 */ +/************************************************************************/ +extern "C" BOOL XStorage_SQLHelp_Insert(TCHAR * ptszSQLBuffer, XSTORAGECORE_DBFILE * pSt_DBFile) { - return m_SQLite.XStorage_SQLite_FileDelete(lpszFile, lpszHash); + return m_SQLHelp.XStorage_SQLHelp_Insert(ptszSQLBuffer, pSt_DBFile); } -extern "C" BOOL XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd, LPCTSTR lpszFile, LPCTSTR lpszHash) +extern "C" BOOL XStorage_SQLHelp_Delete(TCHAR * ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszFileHash) { - return m_SQLite.XStorage_SQLite_FileQuery(pppSt_ListFile, pInt_ListCount, lpszTimeStart, lpszTimeEnd, lpszFile, lpszHash); + return m_SQLHelp.XStorage_SQLHelp_Delete(ptszSQLBuffer, lpszTableName, lpszBuckKey, lpszFileName, lpszFileHash); } -extern "C" BOOL XStorage_SQLite_FileQueryForTable(XSTORAGECORE_DBFILE * **pppSt_ListFile, int* pInt_ListCount, LPCTSTR lpszTableName) +extern "C" BOOL XStorage_SQLHelp_Query(TCHAR * ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey, LPCTSTR lpszFilePath, LPCTSTR lpszFileName, LPCTSTR lpszFileHash, LPCTSTR lpszFileUser, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd) { - return m_SQLite.XStorage_SQLite_FileQueryForTable(pppSt_ListFile, pInt_ListCount, lpszTableName); + return m_SQLHelp.XStorage_SQLHelp_Query(ptszSQLBuffer, lpszTableName, lpszBuckKey, lpszFilePath, lpszFileName, lpszFileHash, lpszFileUser, lpszTimeStart, lpszTimeEnd); } \ No newline at end of file -- Gitee From 7c43139e4848f6136b598e811b5573bf5d5ce31d Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 7 Jan 2022 10:57:16 +0800 Subject: [PATCH 02/34] added:sql Statement packet code for sql module --- .../XStorage_SQLPacket/Makefile | 4 +- .../XStorage_SQLHelp/XStorage_SQLHelp.cpp | 301 ++++++++++++++++++ .../XStorage_SQLHelp/XStorage_SQLHelp.h | 25 ++ 3 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp create mode 100644 XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.h diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/Makefile b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/Makefile index 6964aab..0841a17 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/Makefile +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/Makefile @@ -7,7 +7,7 @@ LOADBIN = -L /usr/local/lib/XEngine_Release/XEngine_BaseLib -L /usr/local/lib/XE LIB = -lXEngine_BaseLib -lHelpComponents_DataBase LIBEX = -static-libgcc -lrt -ldl LOADSO = -Wl,-rpath=./,--disable-new-dtags -LIBINCLUDE = XStorage_MySql.o XStorage_SQLite.o pch.o +LIBINCLUDE = XStorage_SQLHelp.o XStorage_MySql.o XStorage_SQLite.o pch.o ifeq ($(RELEASE),1) FLAGS = -c -O2 @@ -26,6 +26,8 @@ endif all:$(LIBINCLUDE) $(CC) $(DEBUG) $(LIBINCLUDE) -o libXStorage_SQLPacket.so -shared $(LOADBIN) $(LIB) $(LIBEX) $(LOADSO) +XStorage_SQLHelp.o:./XStorage_SQLHelp/XStorage_SQLHelp.cpp + $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(INCLUDE) ./XStorage_SQLHelp/XStorage_SQLHelp.cpp XStorage_MySql.o:./XStorage_MySql/XStorage_MySql.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(INCLUDE) ./XStorage_MySql/XStorage_MySql.cpp XStorage_SQLite.o:./XStorage_SQLite/XStorage_SQLite.cpp diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp new file mode 100644 index 0000000..88e2b4e --- /dev/null +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp @@ -0,0 +1,301 @@ +#include "pch.h" +#include "XStorage_SQLHelp.h" +/******************************************************************** +// Created: 2022/01/06 10:24:07 +// File Name: D:\XEngine_Storage\XEngine_Source\XEngine_StorageComponents\XStorage_SQLPacket\XStorage_SQLHelp\XStorage_SQLHelp.cpp +// File Path: D:\XEngine_Storage\XEngine_Source\XEngine_StorageComponents\XStorage_SQLPacket\XStorage_SQLHelp +// File Base: XStorage_SQLHelp +// File Ext: cpp +// Project: XEngine(ͨ) +// Author: qyt +// Purpose: SQLݿ﷨ +// History: +*********************************************************************/ +CXStorage_SQLHelp::CXStorage_SQLHelp() +{ +} +CXStorage_SQLHelp::~CXStorage_SQLHelp() +{ +} +////////////////////////////////////////////////////////////////////////// +// к +////////////////////////////////////////////////////////////////////////// +/******************************************************************** +ƣXStorage_SQLHelp_Insert +ܣݲ뺯 + .һptszSQLBuffer + In/OutOut + ַָͣ + ɿգN + ˼ðIJ + .pSt_DBFile + In/OutIn + ͣݽṹָ + ɿգN + ˼Ҫ +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Insert(TCHAR* ptszSQLBuffer, XSTORAGECORE_DBFILE* pSt_DBFile) +{ + XStorage_IsErrorOccur = FALSE; + + TCHAR tszTableName[64]; + XENGINE_LIBTIMER st_LibTimer; + + memset(tszTableName, '\0', sizeof(tszTableName)); + memset(&st_LibTimer, '\0', sizeof(XENGINE_LIBTIMER)); + //òڱ + BaseLib_OperatorTime_GetSysTime(&st_LibTimer); + + if (_tcslen(pSt_DBFile->tszTableName) > 0) + { + _tcscpy(tszTableName, pSt_DBFile->tszTableName); + } + else + { + _stprintf(tszTableName, _T("%04d%02d"), st_LibTimer.wYear, st_LibTimer.wMonth); + } + + _stprintf(ptszSQLBuffer, _T("INSERT INTO `%s` (BuckKey,FilePath,FileName,FileHash,FileUser,FileSize,FileTime) VALUES('%s','%s','%s','%s','%s',%lld,%04d-%02d-%02d %02d:%02d:%02d)"), tszTableName, pSt_DBFile->tszBuckKey, pSt_DBFile->st_ProtocolFile.tszFilePath, pSt_DBFile->st_ProtocolFile.tszFileName, pSt_DBFile->st_ProtocolFile.tszFileHash, pSt_DBFile->st_ProtocolFile.tszFileUser, pSt_DBFile->st_ProtocolFile.nFileSize, st_LibTimer.wYear, st_LibTimer.wMonth, st_LibTimer.wDay, st_LibTimer.wHour, st_LibTimer.wMinute, st_LibTimer.wSecond); + return TRUE; +} +/******************************************************************** +ƣXStorage_SQLHelp_Delete +ܣɾ + .һptszSQLBuffer + In/OutIn + ַָͣ + ɿգN + ˼ðIJѯ + .lpszTableName + In/OutIn + ַָͣ + ɿգY + ˼Ҫѯı + .lpszBuckKey + In/OutIn + ַָͣ + ɿգY + ˼BUCKET + .ģlpszFileName + In/OutIn + ַָͣ + ɿգY + ˼ļ + .壺lpszFileHash + In/OutIn + ַָͣ + ɿգY + ˼ļHASHֵ +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Delete(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFileName /* = NULL */, LPCTSTR lpszFileHash /* = NULL */) +{ + XStorage_IsErrorOccur = FALSE; + + TCHAR tszSQLQuery[1024]; + memset(tszSQLQuery, '\0', sizeof(tszSQLQuery)); + + XStorage_SQLHelp_Packet(tszSQLQuery, lpszBuckKey, NULL, lpszFileName, lpszFileHash); + _stprintf(ptszSQLBuffer, _T("DELETE FROM `%s` %s"), lpszTableName, tszSQLQuery); + return TRUE; +} +/******************************************************************** +ƣXStorage_SQLHelp_Query +ܣݿѯ + .һptszSQLBuffer + In/OutIn + ַָͣ + ɿգN + ˼ðIJѯ + .lpszTableName + In/OutIn + ַָͣ + ɿգY + ˼Ҫѯı + .lpszBuckKey + In/OutIn + ַָͣ + ɿգY + ˼BUCKET + .ģlpszFilePath + In/OutIn + ַָͣ + ɿգY + ˼ļ· + .壺lpszFileName + In/OutIn + ַָͣ + ɿգY + ˼ļ + .lpszFileHash + In/OutIn + ַָͣ + ɿգY + ˼ļHASHֵ + .ߣlpszFileUser + In/OutIn + ַָͣ + ɿգY + ˼ļû + .ˣlpszTimeStart + In/OutIn + ַָͣ + ɿգY + ˼ļʼʱ䷶Χ + .ţlpszTimeEnd + In/OutIn + ַָͣ + ɿգY + ˼ļʱ䷶Χ +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Query(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFilePath /* = NULL */, LPCTSTR lpszFileName /* = NULL */, LPCTSTR lpszFileHash /* = NULL */, LPCTSTR lpszFileUser /* = NULL */, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */) +{ + XStorage_IsErrorOccur = FALSE; + + BOOL bInit = FALSE; + TCHAR tszSQLQuery[1024]; + memset(tszSQLQuery, '\0', sizeof(tszSQLQuery)); + + _stprintf(ptszSQLBuffer, _T("SELECT * FROM `%s`"), lpszTableName); + XStorage_SQLHelp_Packet(tszSQLQuery, lpszBuckKey, lpszFilePath, lpszFileName, lpszFileHash, lpszFileUser, lpszTimeStart, lpszTimeEnd); + _tcscat(ptszSQLBuffer, tszSQLQuery); + return TRUE; +} +////////////////////////////////////////////////////////////////////////// +// +////////////////////////////////////////////////////////////////////////// +BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Packet(TCHAR* ptszSQLBuffer, LPCTSTR lpszBuckKey /* = NULL */, LPCTSTR lpszFilePath /* = NULL */, LPCTSTR lpszFileName /* = NULL */, LPCTSTR lpszFileHash /* = NULL */, LPCTSTR lpszFileUser /* = NULL */, LPCTSTR lpszTimeStart /* = NULL */, LPCTSTR lpszTimeEnd /* = NULL */) +{ + XStorage_IsErrorOccur = FALSE; + + BOOL bInit = FALSE; + TCHAR tszSQLQuery[MAX_PATH]; + memset(tszSQLQuery, '\0', MAX_PATH); + //ļBUCKET + if (NULL != lpszBuckKey) + { + if (_tcslen(lpszBuckKey) > 0) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("BuckKey = '%s'"), lpszBuckKey); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + //ļ· + if (NULL != lpszFilePath) + { + if (_tcslen(lpszFilePath) > 0) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("FilePath = '%s'"), lpszFilePath); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + //ļ + if (NULL != lpszFileName) + { + if (_tcslen(lpszFileName) > 0) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("FileName = '%s'"), lpszFileName); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + //ļHASH + if (NULL != lpszFileHash) + { + if (_tcslen(lpszFileHash) > 0) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("FileHash = '%s'"), lpszFileHash); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + //ļû + if (NULL != lpszFileUser) + { + if (_tcslen(lpszFileUser) > 0) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("FileUser = '%s'"), lpszFileUser); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + //ʱ䷶Χ + if ((NULL != lpszTimeStart) && (NULL != lpszTimeEnd)) + { + if ((_tcslen(lpszTimeStart) > 0) && (_tcslen(lpszTimeEnd) > 0)) + { + if (bInit) + { + _tcscat(ptszSQLBuffer, _T(" AND ")); + } + else + { + _tcscat(ptszSQLBuffer, _T("WHERE ")); + } + memset(tszSQLQuery, '\0', MAX_PATH); + _stprintf(tszSQLQuery, _T("BETWEEN '%s' AND '%s'"), lpszTimeStart, lpszTimeEnd); + _tcscat(ptszSQLBuffer, tszSQLQuery); + bInit = TRUE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.h b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.h new file mode 100644 index 0000000..3be2512 --- /dev/null +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.h @@ -0,0 +1,25 @@ +#pragma once +/******************************************************************** +// Created: 2022/01/06 10:23:13 +// File Name: D:\XEngine_Storage\XEngine_Source\XEngine_StorageComponents\XStorage_SQLPacket\XStorage_SQLHelp\XStorage_SQLHelp.h +// File Path: D:\XEngine_Storage\XEngine_Source\XEngine_StorageComponents\XStorage_SQLPacket\XStorage_SQLHelp +// File Base: XStorage_SQLHelp +// File Ext: h +// Project: XEngine(网络通信引擎) +// Author: qyt +// Purpose: SQL数据库语法帮助类 +// History: +*********************************************************************/ + +class CXStorage_SQLHelp +{ +public: + CXStorage_SQLHelp(); + ~CXStorage_SQLHelp(); +public: + BOOL XStorage_SQLHelp_Insert(TCHAR* ptszSQLBuffer, XSTORAGECORE_DBFILE* pSt_DBFile); + BOOL XStorage_SQLHelp_Delete(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFileName = NULL, LPCTSTR lpszFileHash = NULL); + BOOL XStorage_SQLHelp_Query(TCHAR* ptszSQLBuffer, LPCTSTR lpszTableName, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFilePath = NULL, LPCTSTR lpszFileName = NULL, LPCTSTR lpszFileHash = NULL, LPCTSTR lpszFileUser = NULL, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL); +protected: + BOOL XStorage_SQLHelp_Packet(TCHAR* ptszSQLBuffer, LPCTSTR lpszBuckKey = NULL, LPCTSTR lpszFilePath = NULL, LPCTSTR lpszFileName = NULL, LPCTSTR lpszFileHash = NULL, LPCTSTR lpszFileUser = NULL, LPCTSTR lpszTimeStart = NULL, LPCTSTR lpszTimeEnd = NULL); +}; -- Gitee From 05c5b404d8dc9d784550b78ee1607b5f6217d292 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 7 Jan 2022 13:17:43 +0800 Subject: [PATCH 03/34] modify:Protocol_StoragePacket_UPDown funciton support bucket parament modify:Protocol_StorageParse_QueryFile and Protocol_StorageParse_ProxyNotify function support bucket parament --- .../Protocol_StoragePacket.cpp | 36 +++++++++------- .../Protocol_Packet/Protocol_StoragePacket.h | 2 +- .../Protocol_Parse/Protocol_StorageParse.cpp | 18 ++++---- .../Protocol_Parse/Protocol_StorageParse.h | 4 +- .../StorageProtocol_Define.h | 41 +++++++++++-------- XEngine_Source/StorageModule_Protocol/pch.cpp | 12 +++--- 6 files changed, 64 insertions(+), 49 deletions(-) diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp index c8e4915..6ed5806 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp @@ -323,32 +323,37 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMetho /******************************************************************** 函数名称:Protocol_StoragePacket_UPDown 函数功能:上传下载完成代理通知协议 - 参数.一:lpszFileName + 参数.一:ptszMsgBuffer + In/Out:Out + 类型:字符指针 + 可空:N + 意思:数据包 + 参数.二:pInt_MsgLen + In/Out:Out + 类型:整数型 + 可空:N + 意思:导出数据包大小 + 参数.三:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入文件所属BUCKET + 参数.四:lpszFileName In/Out:In 类型:常量字符指针 可空:N 意思:文件的地址 - 参数.二:lpszClientAddr + 参数.五:lpszClientAddr In/Out:In 类型:常量字符指针 可空:N 意思:用户客户端地址 - 参数.三:nFileSize + 参数.六:nFileSize In/Out:In 类型:整数型 可空:N 意思:文件大小 - 参数.四:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:数据包 - 参数.五:pInt_MsgLen - In/Out:Out - 类型:整数型 - 可空:N - 意思:导出数据包大小 - 参数.六:lpszFileHash + 参数.七:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -358,7 +363,7 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMetho 意思:是否成功 备注: *********************************************************************/ -BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszFileHash) +BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash /* = NULL */) { Protocol_IsErrorOccur = FALSE; @@ -370,6 +375,7 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(LPCTSTR lpszFileName } Json::Value st_JsonRoot; + st_JsonRoot["lpszBuckKey"] = lpszBuckKey; st_JsonRoot["lpszFileName"] = lpszFileName; st_JsonRoot["lpszClientAddr"] = lpszClientAddr; st_JsonRoot["nFileSize"] = nFileSize; diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h index 99e54fc..c5bfa48 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h @@ -21,5 +21,5 @@ public: BOOL Protocol_StoragePacket_Info(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, SESSION_STORAGEINFO*** pppSt_DLInfo, SESSION_STORAGEINFO*** pppSt_UPInfo, int nDLCount, int nUPCount); BOOL Protocol_StoragePacket_DirOperator(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, TCHAR*** pppszListEnum, int nListCount); BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lpszPostUrl, LPCTSTR lpszClientAddr, LPCTSTR lpszUser, LPCTSTR lpszPass, TCHAR* ptszMsgBuffer, int* pInt_MsgLen); - BOOL Protocol_StoragePacket_UPDown(LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszFileHash = NULL); + BOOL Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash = NULL); }; diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp index 91e70f9..133cc47 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp @@ -40,7 +40,7 @@ CProtocol_StorageParse::~CProtocol_StorageParse() 类型:字符指针 可空:N 意思:查询结束时间 - 参数.四:ptszPathKey + 参数.四:ptszBuckKey In/Out:Out 类型:字符指针 可空:Y @@ -60,7 +60,7 @@ CProtocol_StorageParse::~CProtocol_StorageParse() 意思:是否成功 备注: *********************************************************************/ -BOOL CProtocol_StorageParse::Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR* ptszTimeStart, TCHAR* ptszTimeEnd, TCHAR* ptszPathKey /* = NULL */, TCHAR* ptszFileName /* = NULL */, TCHAR* ptszFileHash /* = NULL */) +BOOL CProtocol_StorageParse::Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR* ptszTimeStart, TCHAR* ptszTimeEnd, TCHAR* ptszBuckKey /* = NULL */, TCHAR* ptszFileName /* = NULL */, TCHAR* ptszFileHash /* = NULL */) { Protocol_IsErrorOccur = FALSE; @@ -113,11 +113,11 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuff _tcscpy(ptszFileHash, st_JsonRoot["lpszFileHash"].asCString()); } } - if (NULL != ptszPathKey) + if (NULL != ptszBuckKey) { if (!st_JsonRoot["lpszBuckKey"].isNull()) { - _tcscpy(ptszPathKey, st_JsonRoot["lpszBuckKey"].asCString()); + _tcscpy(ptszBuckKey, st_JsonRoot["lpszBuckKey"].asCString()); } } return TRUE; @@ -184,6 +184,10 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_ReportFile(LPCTSTR lpszMsgBuf (*pppSt_DBFile)[i]->st_ProtocolFile.nFileSize = st_JsonArray[i]["nFileSize"].asInt64(); } + if (!st_JsonArray[i]["tszBuckKey"].isNull()) + { + _tcscpy((*pppSt_DBFile)[i]->tszBuckKey, st_JsonArray[i]["tszBuckKey"].asCString()); + } if (!st_JsonArray[i]["tszFileName"].isNull()) { _tcscpy((*pppSt_DBFile)[i]->st_ProtocolFile.tszFileName, st_JsonArray[i]["tszFileName"].asCString()); @@ -284,7 +288,7 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_DirOperator(LPCTSTR lpszMsgBu 类型:字符指针 可空:N 意思:输出文件客户端地址 - 参数.四:ptszPathKey + 参数.四:ptszBuckKey In/Out:Out 类型:字符指针 可空:N @@ -309,7 +313,7 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_DirOperator(LPCTSTR lpszMsgBu 意思:是否成功 备注: *********************************************************************/ -BOOL CProtocol_StorageParse::Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR* ptszClientAddr, TCHAR* ptszPathKey, TCHAR* ptszFileName, TCHAR* ptszFileHash, __int64x* pInt_FileSize) +BOOL CProtocol_StorageParse::Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR* ptszClientAddr, TCHAR* ptszBuckKey, TCHAR* ptszFileName, TCHAR* ptszFileHash, __int64x* pInt_FileSize) { Protocol_IsErrorOccur = FALSE; @@ -337,7 +341,7 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBu _tcscpy(ptszClientAddr, st_JsonRoot["lpszClientAddr"].asCString()); _tcscpy(ptszFileName, st_JsonRoot["lpszFileName"].asCString()); _tcscpy(ptszFileHash, st_JsonRoot["lpszFileHash"].asCString()); - _tcscpy(ptszPathKey, st_JsonRoot["lpszPathKey"].asCString()); + _tcscpy(ptszBuckKey, st_JsonRoot["lpszBuckKey"].asCString()); *pInt_FileSize = st_JsonRoot["nFileSize"].asInt64(); return TRUE; diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.h b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.h index bea9049..95d5683 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.h +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.h @@ -17,8 +17,8 @@ public: CProtocol_StorageParse(); ~CProtocol_StorageParse(); public: - BOOL Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR* ptszTimeStart, TCHAR* ptszTimeEnd, TCHAR* ptszPathKey = NULL, TCHAR* ptszFileName = NULL, TCHAR* ptszFileHash = NULL); + BOOL Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR* ptszTimeStart, TCHAR* ptszTimeEnd, TCHAR* ptszBuckKey = NULL, TCHAR* ptszFileName = NULL, TCHAR* ptszFileHash = NULL); BOOL Protocol_StorageParse_ReportFile(LPCTSTR lpszMsgBuffer, int nMsgLen, XSTORAGECORE_DBFILE*** pppSt_DBFile, int* pInt_ListCount); BOOL Protocol_StorageParse_DirOperator(LPCTSTR lpszMsgBuffer, TCHAR* ptszUserDir, TCHAR* ptszBuckKey, int* pInt_Operator); - BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR* ptszClientAddr, TCHAR* ptszPathKey, TCHAR* ptszFileName, TCHAR* ptszFileHash, __int64x* pInt_FileSize); + BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR* ptszClientAddr, TCHAR* ptszBuckKey, TCHAR* ptszFileName, TCHAR* ptszFileHash, __int64x* pInt_FileSize); }; diff --git a/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h b/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h index fc3e08f..de32538 100644 --- a/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h +++ b/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h @@ -136,7 +136,7 @@ extern "C" BOOL Protocol_P2XPParse_Connect(LPCTSTR lpszMsgBuffer, int nMsgLen, X 类型:字符指针 可空:N 意思:输出文件客户端地址 - 参数.四:ptszPathKey + 参数.四:ptszBuckKey In/Out:Out 类型:字符指针 可空:N @@ -161,7 +161,7 @@ extern "C" BOOL Protocol_P2XPParse_Connect(LPCTSTR lpszMsgBuffer, int nMsgLen, X 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR * ptszClientAddr, TCHAR * ptszPathKey, TCHAR * ptszFileName, TCHAR * ptszFileHash, __int64x * pInt_FileSize); +extern "C" BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR * ptszClientAddr, TCHAR * ptszBuckKey, TCHAR * ptszFileName, TCHAR * ptszFileHash, __int64x * pInt_FileSize); /******************************************************************** 函数名称:Protocol_StorageParse_QueryFile 函数功能:文件查询请求解析函数 @@ -195,7 +195,7 @@ extern "C" BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMs 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Protocol_StorageParse_QueryFile(LPCSTR lpszMsgBuffer, CHAR * ptszTimeStart, CHAR * ptszTimeEnd, CHAR * ptszPathKey = NULL, CHAR * ptszFileName = NULL, CHAR * ptszFileHash = NULL); +extern "C" BOOL Protocol_StorageParse_QueryFile(LPCSTR lpszMsgBuffer, CHAR * ptszTimeStart, CHAR * ptszTimeEnd, CHAR * ptszBuckKey = NULL, CHAR * ptszFileName = NULL, CHAR * ptszFileHash = NULL); /******************************************************************** 函数名称:Protocol_StorageParse_ReportFile 函数功能:解析文件报告协议 @@ -488,32 +488,37 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps /******************************************************************** 函数名称:Protocol_StoragePacket_UPDown 函数功能:上传下载完成代理通知协议 - 参数.一:lpszFileName + 参数.一:ptszMsgBuffer + In/Out:Out + 类型:字符指针 + 可空:N + 意思:数据包 + 参数.二:pInt_MsgLen + In/Out:Out + 类型:整数型 + 可空:N + 意思:导出数据包大小 + 参数.三:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入文件所属BUCKET + 参数.四:lpszFileName In/Out:In 类型:常量字符指针 可空:N 意思:文件的地址 - 参数.二:lpszClientAddr + 参数.五:lpszClientAddr In/Out:In 类型:常量字符指针 可空:N 意思:用户客户端地址 - 参数.三:nFileSize + 参数.六:nFileSize In/Out:In 类型:整数型 可空:N 意思:文件大小 - 参数.四:ptszMsgBuffer - In/Out:Out - 类型:字符指针 - 可空:N - 意思:数据包 - 参数.五:pInt_MsgLen - In/Out:Out - 类型:整数型 - 可空:N - 意思:导出数据包大小 - 参数.六:lpszFileHash + 参数.七:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -523,7 +528,7 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Protocol_StoragePacket_UPDown(LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszFileHash = NULL); +extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash = NULL); /******************************************************************** 函数名称:Protocol_StorageParse_QueryFile 函数功能:查询回复打包协议 diff --git a/XEngine_Source/StorageModule_Protocol/pch.cpp b/XEngine_Source/StorageModule_Protocol/pch.cpp index 7215104..ce4f401 100644 --- a/XEngine_Source/StorageModule_Protocol/pch.cpp +++ b/XEngine_Source/StorageModule_Protocol/pch.cpp @@ -50,13 +50,13 @@ extern "C" BOOL Protocol_P2XPParse_Connect(LPCTSTR lpszMsgBuffer, int nMsgLen, X return m_P2XPParse.Protocol_P2XPParse_Connect(lpszMsgBuffer, nMsgLen, pSt_IOProtocol); } ////////////////////////////////////////////////////////////////////////// -extern "C" BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR * ptszClientAddr, TCHAR * ptszPathKey, TCHAR * ptszFileName, TCHAR * ptszFileHash, __int64x * pInt_FileSize) +extern "C" BOOL Protocol_StorageParse_ProxyNotify(LPCTSTR lpszMsgBuffer, int nMsgLen, TCHAR * ptszClientAddr, TCHAR * ptszBuckKey, TCHAR * ptszFileName, TCHAR * ptszFileHash, __int64x * pInt_FileSize) { - return m_StorageParse.Protocol_StorageParse_ProxyNotify(lpszMsgBuffer, nMsgLen, ptszClientAddr, ptszPathKey, ptszFileName, ptszFileHash, pInt_FileSize); + return m_StorageParse.Protocol_StorageParse_ProxyNotify(lpszMsgBuffer, nMsgLen, ptszClientAddr, ptszBuckKey, ptszFileName, ptszFileHash, pInt_FileSize); } -extern "C" BOOL Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR * ptszTimeStart, TCHAR * ptszTimeEnd, CHAR * ptszPathKey, TCHAR * ptszFileName, TCHAR * ptszFileHash) +extern "C" BOOL Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuffer, TCHAR * ptszTimeStart, TCHAR * ptszTimeEnd, CHAR * ptszBuckKey, TCHAR * ptszFileName, TCHAR * ptszFileHash) { - return m_StorageParse.Protocol_StorageParse_QueryFile(lpszMsgBuffer, ptszTimeStart, ptszTimeEnd, ptszPathKey, ptszFileName, ptszFileHash); + return m_StorageParse.Protocol_StorageParse_QueryFile(lpszMsgBuffer, ptszTimeStart, ptszTimeEnd, ptszBuckKey, ptszFileName, ptszFileHash); } extern "C" BOOL Protocol_StorageParse_ReportFile(LPCTSTR lpszMsgBuffer, int nMsgLen, XSTORAGECORE_DBFILE * **pppSt_DBFile, int* pInt_ListCount) { @@ -98,9 +98,9 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps { return m_StoragePacket.Protocol_StoragePacket_BasicAuth(lpszMethod, lpszPostUrl, lpszClientAddr, lpszUser, lpszPass, ptszMsgBuffer, pInt_MsgLen); } -extern "C" BOOL Protocol_StoragePacket_UPDown(LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszFileHash) +extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash) { - return m_StoragePacket.Protocol_StoragePacket_UPDown(lpszFileName, lpszClientAddr, nFileSize, ptszMsgBuffer, pInt_MsgLen, lpszFileHash); + return m_StoragePacket.Protocol_StoragePacket_UPDown(ptszMsgBuffer, pInt_MsgLen, lpszBuckKey, lpszFileName, lpszClientAddr, nFileSize, lpszFileHash); } extern "C" BOOL Protocol_StoragePacket_QueryFile(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, XSTORAGECORE_DBFILE * **pppSt_DBFile, int nListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd) { -- Gitee From 67c900b4a680c08a768b9969ae700946e9d0d7eb Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 7 Jan 2022 13:18:23 +0800 Subject: [PATCH 04/34] modify:upload and download session support bucket parament --- .../StorageModule_Session/Session_Define.h | 37 ++++++++++++------- .../Session_Stroage/Session_DLStroage.cpp | 20 ++++++---- .../Session_Stroage/Session_DLStroage.h | 2 +- .../Session_Stroage/Session_UPStroage.cpp | 18 ++++++--- .../Session_Stroage/Session_UPStroage.h | 2 +- XEngine_Source/StorageModule_Session/pch.cpp | 8 ++-- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/XEngine_Source/StorageModule_Session/Session_Define.h b/XEngine_Source/StorageModule_Session/Session_Define.h index 6445346..323f7c3 100644 --- a/XEngine_Source/StorageModule_Session/Session_Define.h +++ b/XEngine_Source/StorageModule_Session/Session_Define.h @@ -18,6 +18,7 @@ typedef struct TCHAR tszFileDir[MAX_PATH]; //文件地址 TCHAR tszClientAddr[128]; //操作的用户地址 TCHAR tszFileHash[128]; //文件HASH值 + TCHAR tszBuckKey[128]; //BUCKKey __int64x ullCount; //总大小 __int64x ullRWCount; //读取(写入)总大小 __int64x ullRWLen; //已经读取(写入)的大小 @@ -110,32 +111,37 @@ extern "C" BOOL Session_DLStroage_Destory(); 类型:常量字符指针 可空:N 意思:输入要操作的客户端 - 参数.二:lpszFileDir + 参数.二:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入BUCKET名称 + 参数.三:lpszFileDir In/Out:In 类型:常量字符指针 可空:N 意思:输入文件地址 - 参数.三:pInt_Count + 参数.四:pInt_Count In/Out:Out 类型:整数型指针 可空:N 意思:输出文件大小 - 参数.四:pInt_LeftCount + 参数.五:pInt_LeftCount In/Out:Out 类型:整数型指针 可空:N 意思:输出需要读取大小 - 参数.五:nPosStart + 参数.六:nPosStart In/Out:In 类型:整数型 可空:Y 意思:输入开始位置 - 参数.六:nPostEnd + 参数.七:nPostEnd In/Out:In 类型:整数型 可空:Y 意思:输入结束位置 - 参数.七:lpszFileHash + 参数.八:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -145,7 +151,7 @@ extern "C" BOOL Session_DLStroage_Destory(); 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x * pInt_Count, __int64x * pInt_LeftCount, int nPosStart = 0, int nPostEnd = 0, LPCTSTR lpszFileHash = NULL); +extern "C" BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x * pInt_Count, __int64x * pInt_LeftCount, int nPosStart = 0, int nPostEnd = 0, LPCTSTR lpszFileHash = NULL); /******************************************************************** 函数名称:Session_DLStroage_GetBuffer 函数功能:获得下载器中指定缓冲区 @@ -290,27 +296,32 @@ extern "C" BOOL Session_UPStroage_Destory(); 类型:常量字符指针 可空:N 意思:输入要操作的客户端 - 参数.二:lpszFileDir + 参数.二:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入BUCKET名称 + 参数.三:lpszFileDir In/Out:In 类型:常量字符指针 可空:N 意思:输入文件地址 - 参数.三:nFileSize + 参数.四:nFileSize In/Out:Out 类型:整数型 可空:N 意思:输入文件大小 - 参数.四:nLeftCount + 参数.五:nLeftCount In/Out:In 类型:整数型 可空:N 意思:输入需要写入的大小 - 参数.五:nPosStart + 参数.六:nPosStart In/Out:In 类型:整数型 可空:Y 意思:输入起始位置 - 参数.六:nPostEnd + 参数.七:nPostEnd In/Out:In 类型:整数型 可空:Y @@ -320,7 +331,7 @@ extern "C" BOOL Session_UPStroage_Destory(); 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart = 0, int nPostEnd = 0); +extern "C" BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart = 0, int nPostEnd = 0); /******************************************************************** 函数名称:Session_UPStroage_GetInfo 函数功能:获取上传客户端信息 diff --git a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.cpp b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.cpp index dfea2b5..372a34b 100644 --- a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.cpp +++ b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.cpp @@ -66,32 +66,37 @@ BOOL CSession_DLStroage::Session_DLStroage_Destory() 类型:常量字符指针 可空:N 意思:输入要操作的客户端 - 参数.二:lpszFileDir + 参数.二:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入BUCKET名称 + 参数.三:lpszFileDir In/Out:In 类型:常量字符指针 可空:N 意思:输入文件地址 - 参数.三:pInt_Count + 参数.四:pInt_Count In/Out:Out 类型:整数型指针 可空:N 意思:输出文件大小 - 参数.四:pInt_LeftCount + 参数.五:pInt_LeftCount In/Out:Out 类型:整数型指针 可空:N 意思:输出需要读取大小 - 参数.五:nPosStart + 参数.六:nPosStart In/Out:In 类型:整数型 可空:Y 意思:输入开始位置 - 参数.六:nPostEnd + 参数.七:nPostEnd In/Out:In 类型:整数型 可空:Y 意思:输入结束位置 - 参数.七:lpszFileHash + 参数.八:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -101,7 +106,7 @@ BOOL CSession_DLStroage::Session_DLStroage_Destory() 意思:是否成功 备注: *********************************************************************/ -BOOL CSession_DLStroage::Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x* pInt_Count, __int64x* pInt_LeftCount, int nPosStart /* = 0 */, int nPostEnd /* = 0 */, LPCTSTR lpszFileHash /* = NULL */) +BOOL CSession_DLStroage::Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x* pInt_Count, __int64x* pInt_LeftCount, int nPosStart /* = 0 */, int nPostEnd /* = 0 */, LPCTSTR lpszFileHash /* = NULL */) { Session_IsErrorOccur = FALSE; @@ -139,6 +144,7 @@ BOOL CSession_DLStroage::Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTST st_Client.ullCount = st_FStat.st_size; _tcscpy(st_Client.tszFileDir, lpszFileDir); _tcscpy(st_Client.tszClientAddr, lpszClientAddr); + _tcscpy(st_Client.tszBuckKey, lpszBuckKey); if (NULL != lpszFileHash) { _tcscpy(st_Client.tszFileHash, lpszFileHash); diff --git a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.h b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.h index 6b9e859..8df77b2 100644 --- a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.h +++ b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_DLStroage.h @@ -19,7 +19,7 @@ public: public: BOOL Session_DLStroage_Init(int nTryTime); BOOL Session_DLStroage_Destory(); - BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x* pInt_Count, __int64x* pInt_LeftCount, int nPosStart = 0, int nPostEnd = 0, LPCTSTR lpszFileHash = NULL); + BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x* pInt_Count, __int64x* pInt_LeftCount, int nPosStart = 0, int nPostEnd = 0, LPCTSTR lpszFileHash = NULL); BOOL Session_DLStroage_GetBuffer(LPCTSTR lpszClientAddr, TCHAR* ptszMsgBuffer, int* pInt_MsgLen); BOOL Session_DLStroage_GetInfo(LPCTSTR lpszClientAddr, SESSION_STORAGEINFO* pSt_StorageInfo); BOOL Session_DLStroage_GetCount(int* pInt_ListCount); diff --git a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp index 60f246c..fb909d8 100644 --- a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp +++ b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp @@ -66,27 +66,32 @@ BOOL CSession_UPStroage::Session_UPStroage_Destory() 类型:常量字符指针 可空:N 意思:输入要操作的客户端 - 参数.二:lpszFileDir + 参数.二:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入BUCKET名称 + 参数.三:lpszFileDir In/Out:In 类型:常量字符指针 可空:N 意思:输入文件地址 - 参数.三:nFileSize + 参数.四:nFileSize In/Out:Out 类型:整数型 可空:N 意思:输入文件大小 - 参数.四:nLeftCount + 参数.五:nLeftCount In/Out:In 类型:整数型 可空:N 意思:输入需要写入的大小 - 参数.五:nPosStart + 参数.六:nPosStart In/Out:In 类型:整数型 可空:Y 意思:输入起始位置 - 参数.六:nPostEnd + 参数.七:nPostEnd In/Out:In 类型:整数型 可空:Y @@ -96,7 +101,7 @@ BOOL CSession_UPStroage::Session_UPStroage_Destory() 意思:是否成功 备注: *********************************************************************/ -BOOL CSession_UPStroage::Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart /* = 0 */, int nPostEnd /* = 0 */) +BOOL CSession_UPStroage::Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart /* = 0 */, int nPostEnd /* = 0 */) { Session_IsErrorOccur = FALSE; @@ -125,6 +130,7 @@ BOOL CSession_UPStroage::Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTST st_Client.st_StorageInfo.ullPosEnd = nPostEnd; st_Client.st_StorageInfo.ullRWCount = nLeftCount; st_Client.st_StorageInfo.ullCount = nFileSize; + _tcscpy(st_Client.st_StorageInfo.tszBuckKey, lpszBuckKey); _tcscpy(st_Client.st_StorageInfo.tszFileDir, lpszFileDir); _tcscpy(st_Client.st_StorageInfo.tszClientAddr, lpszClientAddr); //填充下载信息 diff --git a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.h b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.h index ed112e0..c92937e 100644 --- a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.h +++ b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.h @@ -24,7 +24,7 @@ public: public: BOOL Session_UPStroage_Init(BOOL bUPResume = FALSE); BOOL Session_UPStroage_Destory(); - BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart = 0, int nPostEnd = 0); + BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart = 0, int nPostEnd = 0); BOOL Session_UPStroage_GetInfo(LPCTSTR lpszClientAddr, SESSION_STORAGEINFO* pSt_StorageInfo); BOOL Session_UPStroage_Write(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int nMsgLen); BOOL Session_UPStroage_Exist(LPCTSTR lpszClientAddr); diff --git a/XEngine_Source/StorageModule_Session/pch.cpp b/XEngine_Source/StorageModule_Session/pch.cpp index 0393f9d..3f718cd 100644 --- a/XEngine_Source/StorageModule_Session/pch.cpp +++ b/XEngine_Source/StorageModule_Session/pch.cpp @@ -56,9 +56,9 @@ extern "C" BOOL Session_DLStroage_Destory() { return m_DLStorage.Session_DLStroage_Destory(); } -extern "C" BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x * pInt_Count, __int64x * pInt_LeftCount, int nPosStart, int nPostEnd, LPCTSTR lpszFileHash) +extern "C" BOOL Session_DLStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x * pInt_Count, __int64x * pInt_LeftCount, int nPosStart, int nPostEnd, LPCTSTR lpszFileHash) { - return m_DLStorage.Session_DLStroage_Insert(lpszClientAddr, lpszFileDir, pInt_Count, pInt_LeftCount, nPosStart, nPostEnd, lpszFileHash); + return m_DLStorage.Session_DLStroage_Insert(lpszClientAddr, lpszBuckKey, lpszFileDir, pInt_Count, pInt_LeftCount, nPosStart, nPostEnd, lpszFileHash); } extern "C" BOOL Session_DLStroage_GetBuffer(LPCTSTR lpszClientAddr, TCHAR * ptszMsgBuffer, int* pInt_MsgLen) { @@ -92,9 +92,9 @@ extern "C" BOOL Session_UPStroage_Destory() { return m_UPStorage.Session_UPStroage_Destory(); } -extern "C" BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart, int nPostEnd) +extern "C" BOOL Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTSTR lpszBuckKey, LPCTSTR lpszFileDir, __int64x nFileSize, __int64x nLeftCount, int nPosStart, int nPostEnd) { - return m_UPStorage.Session_UPStroage_Insert(lpszClientAddr, lpszFileDir, nFileSize, nLeftCount, nPosStart, nPostEnd); + return m_UPStorage.Session_UPStroage_Insert(lpszClientAddr, lpszBuckKey, lpszFileDir, nFileSize, nLeftCount, nPosStart, nPostEnd); } extern "C" BOOL Session_UPStroage_GetInfo(LPCTSTR lpszClientAddr, SESSION_STORAGEINFO * pSt_StorageInfo) { -- Gitee From 64cdd9b11f44962d4489e0a1a8e4fb97cc5f64e4 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 7 Jan 2022 13:18:54 +0800 Subject: [PATCH 05/34] fixed:p2p client count incorrent --- .../XStorage_P2XPPeer/P2XPPeer_Manage/P2XPPeer_Manage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_P2XPPeer/P2XPPeer_Manage/P2XPPeer_Manage.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_P2XPPeer/P2XPPeer_Manage/P2XPPeer_Manage.cpp index fd5f9eb..70da765 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_P2XPPeer/P2XPPeer_Manage/P2XPPeer_Manage.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_P2XPPeer/P2XPPeer_Manage/P2XPPeer_Manage.cpp @@ -429,7 +429,7 @@ BOOL CP2XPPeer_Manage::P2XPPeer_Manage_GetAllList(TCHAR*** pppszP2XPClient, int* { _tcscpy((*pppszP2XPClient)[i], stl_MapIterator->first.c_str()); } - *pInt_ListCount = stl_MapClients.size(); + *pInt_ListCount = stl_MapPeerAddr.size(); st_rwLocker.unlock_shared(); return TRUE; } -- Gitee From 5b13ad20a1ba618b17b59f6717952c9fd8eb6c90 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 10 Jan 2022 09:34:08 +0800 Subject: [PATCH 06/34] added:apihelp function for storage module from app program --- .../APIHelp_Api/APIHelp_Api.cpp | 223 ++++++++++++++++++ .../APIHelp_Api/APIHelp_Api.h | 26 ++ .../StorageModule_APIHelp/APIHelp_Define.h | 94 +++++++- .../StorageModule_APIHelp/APIHelp_Error.h | 12 +- XEngine_Source/StorageModule_APIHelp/Makefile | 6 +- .../StorageModule_APIHelp.def | 6 +- .../StorageModule_APIHelp.vcxproj | 2 + .../StorageModule_APIHelp.vcxproj.filters | 12 + XEngine_Source/StorageModule_APIHelp/pch.cpp | 17 ++ XEngine_Source/StorageModule_APIHelp/pch.h | 7 + 10 files changed, 397 insertions(+), 8 deletions(-) create mode 100644 XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp create mode 100644 XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.h diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp new file mode 100644 index 0000000..34261dd --- /dev/null +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp @@ -0,0 +1,223 @@ +#include "pch.h" +#include "APIHelp_Api.h" +/******************************************************************** +// Created: 2022/01/07 14:36:59 +// File Name: D:\XEngine_Storage\XEngine_Source\StorageModule_APIHelp\APIHelp_Api\APIHelp_Api.cpp +// File Path: D:\XEngine_Storage\XEngine_Source\StorageModule_APIHelp\APIHelp_Api +// File Base: APIHelp_Api +// File Ext: cpp +// Project: XEngine(ͨ) +// Author: qyt +// Purpose: +// History: +*********************************************************************/ +CAPIHelp_Api::CAPIHelp_Api() +{ + +} +CAPIHelp_Api::~CAPIHelp_Api() +{ + +} +////////////////////////////////////////////////////////////////////////// +// к +////////////////////////////////////////////////////////////////////////// +/******************************************************************** +ƣAPIHelp_Api_ProxyAuth +ܣ֤ + .һptszUser + In/OutOut + ַָͣ + ɿգN + ˼û + .ptszPass + In/OutOut + ַָͣ + ɿգN + ˼ + .pptszListHdr + In/OutIn + ָָָͣ + ɿգN + ˼ҪHTTPͷ + .ģnHdrCount + In/OutIn + ͣ + ɿգN + ˼ҪHTTPͷб +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CAPIHelp_Api::APIHelp_Api_ProxyAuth(TCHAR* ptszUser, TCHAR* ptszPass, TCHAR** pptszListHdr, int nHdrCount) +{ + APIHelp_IsErrorOccur = FALSE; + + int nSDLen = 1024; + int nAuthType = 0; + int nAuthLen = MAX_PATH; + + TCHAR tszAuthStr[MAX_PATH]; + TCHAR tszSDBuffer[1024]; + + memset(tszAuthStr, '\0', MAX_PATH); + memset(tszSDBuffer, '\0', sizeof(tszSDBuffer)); + //Ƿ֤Ϣ + if (!RfcComponents_HttpHelp_GetAuthInfo(&pptszListHdr, nHdrCount, tszAuthStr, &nAuthLen, &nAuthType)) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTAUTH; + return FALSE; + } + //ǷBASIC + if (1 != nAuthType) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTSUPPORT; + return FALSE; + } + OPenSsl_Help_BasicDecoder(tszAuthStr, ptszUser, ptszPass); + return TRUE; +} +/******************************************************************** +ƣAPIHelp_Api_RangeFile +ܣȡHTTPķΧ + .һpInt_SPos + In/OutOut + ָͣ + ɿգN + ˼ʼΧ + .pInt_EPos + In/OutOut + ָͣ + ɿգN + ˼Χ + .pInt_Count + In/OutOut + ָͣ + ɿգN + ˼ܴС + .ģpptszListHdr + In/OutIn + ָָָͣ + ɿգN + ˼HTTPЭͷб + .壺nHdrCount + In/OutIn + ָָָͣ + ɿգN + ˼б +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CAPIHelp_Api::APIHelp_Api_RangeFile(int* pInt_SPos, int* pInt_EPos, __int64x* pInt_Count, TCHAR** pptszListHdr, int nHdrCount) +{ + APIHelp_IsErrorOccur = FALSE; + + BOOL bFound = FALSE; + LPCTSTR lpszRangeStr = _T("Range"); + LPCTSTR lpszLengthStr = _T("Content-Length"); + TCHAR tszKeyStr[128]; + TCHAR tszValueStr[128]; + TCHAR tszFieldStr[128]; + + memset(tszKeyStr, '\0', sizeof(tszKeyStr)); + memset(tszValueStr, '\0', sizeof(tszValueStr)); + memset(tszFieldStr, '\0', sizeof(tszFieldStr)); + //ǷзΧ + if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszRangeStr, tszFieldStr)) + { + //Ƿûҵ + int nBPos = 0; //ijЩʱиBYTE + if (NULL != _tcsstr(tszFieldStr, _T("bytes="))) + { + nBPos = 6; + } + if (!BaseLib_OperatorString_GetKeyValue(tszFieldStr + nBPos, "-", tszKeyStr, tszValueStr)) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_PARSELEN; + return FALSE; + } + //õ 1/2 еĻ + TCHAR tszRangeEnd[128]; + TCHAR tszRangeCount[128]; + + memset(tszRangeEnd, '\0', sizeof(tszRangeEnd)); + memset(tszRangeCount, '\0', sizeof(tszRangeCount)); + if (BaseLib_OperatorString_GetKeyValue(tszValueStr, "/", tszRangeEnd, tszRangeCount)) + { + *pInt_SPos = _ttoi(tszKeyStr); + *pInt_EPos = _ttoi(tszRangeEnd); + *pInt_Count = _ttoi64(tszRangeCount); + } + else + { + *pInt_SPos = _ttoi(tszKeyStr); + *pInt_EPos = _ttoi(tszValueStr); + } + bFound = TRUE; + } + if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszLengthStr, tszFieldStr)) + { + *pInt_Count = _ttoi64(tszFieldStr); + bFound = TRUE; + } + + if (!bFound) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTLENGTH; + return FALSE; + } + + return TRUE; +} +/******************************************************************** +ƣAPIHelp_Api_VerHash +ܣ֤HASHֵ + .һlpszFileHash + In/OutIn + ַָͣ + ɿգN + ˼ҪȶԵHASHֵ + .pptszListHdr + In/OutIn + ָָָͣ + ɿգN + ˼HTTPЭͷб + .nHdrCount + In/OutIn + ָָָͣ + ɿգN + ˼б +ֵ + ͣ߼ + ˼Ƿɹ +ע +*********************************************************************/ +BOOL CAPIHelp_Api::APIHelp_Api_VerHash(LPCTSTR lpszFileHash, TCHAR** pptszListHdr, int nHdrCount) +{ + APIHelp_IsErrorOccur = FALSE; + + LPCTSTR lpszKeyStr = _T("FileHash"); + TCHAR tszValueStr[MAX_PATH]; + memset(tszValueStr, '\0', MAX_PATH); + + if (!RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszKeyStr, tszValueStr)) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTHASH; + return FALSE; + } + if (0 != _tcsnicmp(lpszFileHash, tszValueStr, _tcslen(lpszFileHash))) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTMATCH; + return FALSE; + } + return TRUE; +} \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.h new file mode 100644 index 0000000..3950c35 --- /dev/null +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.h @@ -0,0 +1,26 @@ +#pragma once +/******************************************************************** +// Created: 2022/01/07 14:36:50 +// File Name: D:\XEngine_Storage\XEngine_Source\StorageModule_APIHelp\APIHelp_Api\APIHelp_Api.h +// File Path: D:\XEngine_Storage\XEngine_Source\StorageModule_APIHelp\APIHelp_Api +// File Base: APIHelp_Api +// File Ext: h +// Project: XEngine(ͨ) +// Author: qyt +// Purpose: +// History: +*********************************************************************/ + + +class CAPIHelp_Api +{ +public: + CAPIHelp_Api(); + ~CAPIHelp_Api(); +public: + BOOL APIHelp_Api_ProxyAuth(TCHAR* ptszUser, TCHAR* ptszPass, TCHAR** pptszListHdr, int nHdrCount); + BOOL APIHelp_Api_RangeFile(int* pInt_SPos, int* pInt_EPos, __int64x* pInt_Count, TCHAR** pptszListHdr, int nHdrCount); + BOOL APIHelp_Api_VerHash(LPCTSTR lpszFileHash, TCHAR** pptszListHdr, int nHdrCount); +protected: +private: +}; \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h index b986316..d737d9f 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h @@ -20,7 +20,7 @@ typedef struct ////////////////////////////////////////////////////////////////////////// extern "C" DWORD StorageHelp_GetLastError(int* pInt_SysError = NULL); /************************************************************************/ -/* */ +/* 分布式函数 */ /************************************************************************/ /******************************************************************** 函数名称:APIHelp_Distributed_IsMode @@ -126,4 +126,94 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); \ No newline at end of file +extern "C" BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); +/************************************************************************/ +/* 帮助函数 */ +/************************************************************************/ +/******************************************************************** +函数名称:APIHelp_Api_ProxyAuth +函数功能:代理验证 + 参数.一:ptszUser + In/Out:Out + 类型:字符指针 + 可空:N + 意思:输出用户名 + 参数.二:ptszPass + In/Out:Out + 类型:字符指针 + 可空:N + 意思:输出密码 + 参数.三:pptszListHdr + In/Out:In + 类型:指向指针的指针 + 可空:N + 意思:输入要解析的HTTP头 + 参数.四:nHdrCount + In/Out:In + 类型:整数型 + 可空:N + 意思:输入要解析的HTTP头列表个数 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL APIHelp_Api_ProxyAuth(TCHAR* ptszUser, TCHAR* ptszPass, TCHAR** pptszListHdr, int nHdrCount); +/******************************************************************** +函数名称:APIHelp_Api_RangeFile +函数功能:获取HTTP的范围 + 参数.一:pInt_SPos + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出起始范围 + 参数.二:pInt_EPos + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出结束范围 + 参数.三:pInt_Count + In/Out:Out + 类型:整数型指针 + 可空:N + 意思:输出总大小 + 参数.四:pptszListHdr + In/Out:In + 类型:指向指针的指针 + 可空:N + 意思:输入HTTP协议头列表 + 参数.五:nHdrCount + In/Out:In + 类型:指向指针的指针 + 可空:N + 意思:输入列表个数 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL APIHelp_Api_RangeFile(int* pInt_SPos, int* pInt_EPos, __int64x* pInt_Count, TCHAR** pptszListHdr, int nHdrCount); +/******************************************************************** +函数名称:APIHelp_Api_VerHash +函数功能:验证HASH值 + 参数.一:lpszFileHash + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要比对的HASH值 + 参数.二:pptszListHdr + In/Out:In + 类型:指向指针的指针 + 可空:N + 意思:输入HTTP协议头列表 + 参数.三:nHdrCount + In/Out:In + 类型:指向指针的指针 + 可空:N + 意思:输入列表个数 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL APIHelp_Api_VerHash(LPCTSTR lpszFileHash, TCHAR** pptszListHdr, int nHdrCount); \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Error.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Error.h index d9481ce..aa66fd1 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Error.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Error.h @@ -10,6 +10,12 @@ // Purpose: 导出错误 // History: *********************************************************************/ -#define ERROR_STORAGE_MODULE_APIHELP_PARAMENT 0x0030001 -#define ERROR_STORAGE_MODULE_APIHELP_PARSE 0x0030002 -#define ERROR_STORAGE_MODULE_APIHELP_NOTFOUND 0x0030003 \ No newline at end of file +#define ERROR_STORAGE_MODULE_APIHELP_PARAMENT 0x0030001 //参数错误 +#define ERROR_STORAGE_MODULE_APIHELP_PARSE 0x0030002 //解析失败 +#define ERROR_STORAGE_MODULE_APIHELP_NOTFOUND 0x0030003 //没有找到 +#define ERROR_STORAGE_MODULE_APIHELP_NOTAUTH 0x0030010 //没有验证信息 +#define ERROR_STORAGE_MODULE_APIHELP_NOTSUPPORT 0x0030011 //不支持 +#define ERROR_STORAGE_MODULE_APIHELP_NOTLENGTH 0x0030012 //没有长度信息 +#define ERROR_STORAGE_MODULE_APIHELP_PARSELEN 0x0030013 //解析长度失败 +#define ERROR_STORAGE_MODULE_APIHELP_NOTHASH 0x0030014 //没有HASH值 +#define ERROR_STORAGE_MODULE_APIHELP_NOTMATCH 0x0030015 //HASH不匹配 \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/Makefile b/XEngine_Source/StorageModule_APIHelp/Makefile index 58b5213..ca21933 100644 --- a/XEngine_Source/StorageModule_APIHelp/Makefile +++ b/XEngine_Source/StorageModule_APIHelp/Makefile @@ -6,7 +6,7 @@ LOADBIN = LIB = LIBEX = -static-libgcc -lrt -ldl -lpthread LOADSO = -Wl,-rpath= -LIBINCLUDE = APIHelp_Distributed.o pch.o +LIBINCLUDE = APIHelp_Distributed.o APIHelp_Api.o pch.o ifeq ($(RELEASE),1) FLAGS = -c -O2 @@ -28,7 +28,9 @@ all:$(LIBINCLUDE) APIHelp_Distributed.o:./APIHelp_Distributed/APIHelp_Distributed.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(INCLUDE) ./APIHelp_Distributed/APIHelp_Distributed.cpp - +APIHelp_Api.o:./APIHelp_Api/APIHelp_Api.cpp + $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(INCLUDE) ./APIHelp_Api/APIHelp_Api.cpp + pch.o:./pch.cpp $(CC) $(DEBUG) $(FLAGS) $(UNICODE) $(INCLUDE) ./pch.cpp diff --git a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def index 1f0e8e6..1602d00 100644 --- a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def +++ b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def @@ -7,4 +7,8 @@ EXPORTS APIHelp_Distributed_RandomAddr APIHelp_Distributed_FileList APIHelp_Distributed_DLStorage - APIHelp_Distributed_UPStorage \ No newline at end of file + APIHelp_Distributed_UPStorage + + APIHelp_Api_ProxyAuth + APIHelp_Api_RangeFile + APIHelp_Api_VerHash \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj index b480b95..95b37e6 100644 --- a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj +++ b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj @@ -166,6 +166,7 @@ + @@ -173,6 +174,7 @@ + diff --git a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj.filters b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj.filters index 38ae2d5..14ad6f8 100644 --- a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj.filters +++ b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.vcxproj.filters @@ -19,6 +19,12 @@ {5b2628b8-77c6-475d-b982-4b4b8815b907} + + {91f72057-f0a5-49ff-88f2-fb003f358183} + + + {70c91174-907f-422b-8db6-f8ee8298447c} + @@ -36,6 +42,9 @@ 头文件 + + 头文件\APIHelp_Api + @@ -47,6 +56,9 @@ 源文件\APIHelp_Distributed + + 源文件\APIHelp_Api + diff --git a/XEngine_Source/StorageModule_APIHelp/pch.cpp b/XEngine_Source/StorageModule_APIHelp/pch.cpp index c792feb..e41699e 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.cpp +++ b/XEngine_Source/StorageModule_APIHelp/pch.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "APIHelp_Distributed/APIHelp_Distributed.h" +#include "APIHelp_Api/APIHelp_Api.h" /******************************************************************** // Created: 2021/07/08 16:40:04 // File Name: D:\XEngine_Storage\XEngine_Source\StorageModule_APIHelp\pch.cpp @@ -15,6 +16,7 @@ BOOL APIHelp_IsErrorOccur = FALSE; DWORD APIHelp_dwErrorCode = 0; ////////////////////////////////////////////////////////////////////////// CAPIHelp_Distributed m_APIDistributed; +CAPIHelp_Api m_APIHelp; ////////////////////////////////////////////////////////////////////////// // 导出函数 ////////////////////////////////////////////////////////////////////////// @@ -48,4 +50,19 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list*pStl_ListBucket, XENGINE_STORAGEBUCKET * pSt_StorageBucket) { return m_APIDistributed.APIHelp_Distributed_UPStorage(pStl_ListBucket, pSt_StorageBucket); +} +/************************************************************************/ +/* 帮助函数 */ +/************************************************************************/ +extern "C" BOOL APIHelp_Api_ProxyAuth(TCHAR * ptszUser, TCHAR * ptszPass, TCHAR * *pptszListHdr, int nHdrCount) +{ + return m_APIHelp.APIHelp_Api_ProxyAuth(ptszUser, ptszPass, pptszListHdr, nHdrCount); +} +extern "C" BOOL APIHelp_Api_RangeFile(int* pInt_SPos, int* pInt_EPos, __int64x * pInt_Count, TCHAR * *pptszListHdr, int nHdrCount) +{ + return m_APIHelp.APIHelp_Api_RangeFile(pInt_SPos, pInt_EPos, pInt_Count, pptszListHdr, nHdrCount); +} +extern "C" BOOL APIHelp_Api_VerHash(LPCTSTR lpszFileHash, TCHAR * *pptszListHdr, int nHdrCount) +{ + return m_APIHelp.APIHelp_Api_VerHash(lpszFileHash, pptszListHdr, nHdrCount); } \ No newline at end of file diff --git a/XEngine_Source/StorageModule_APIHelp/pch.h b/XEngine_Source/StorageModule_APIHelp/pch.h index 88adabb..62f0686 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.h +++ b/XEngine_Source/StorageModule_APIHelp/pch.h @@ -12,6 +12,7 @@ #include "framework.h" #include #include +#include #else #ifdef _CENTOS #include @@ -33,11 +34,15 @@ using namespace std; #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include "../XStorage_Protocol.h" #include "../StorageModule_Config/Config_Define.h" #include "../XEngine_StorageComponents/XStorage_SQLPacket/SQLPacket_Define.h" @@ -59,5 +64,7 @@ extern DWORD APIHelp_dwErrorCode; #ifdef _WINDOWS #pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib") +#pragma comment(lib,"XEngine_Core/XEngine_OPenSsl") +#pragma comment(lib,"XEngine_RfcComponents/RfcComponents_HttpServer") #pragma comment(lib,"XEngine_SystemSdk/XEngine_SystemApi") #endif \ No newline at end of file -- Gitee From 0d761eb92ba3752d2bf267a270599f39920b0bc5 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 10 Jan 2022 09:35:48 +0800 Subject: [PATCH 07/34] delete:apihelp file for storage app --- .../Storage_APPHelp/Storage_APPHelp.cpp | 211 ------------------ .../Storage_APPHelp/Storage_APPHelp.h | 5 - 2 files changed, 216 deletions(-) delete mode 100644 XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.cpp delete mode 100644 XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.h diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.cpp deleted file mode 100644 index 55bab52..0000000 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "../StorageApp_Hdr.h" - -BOOL XEngine_APPHelp_ProxyAuth(LPCTSTR lpszClientAddr, LPCTSTR lpszMethod, LPCTSTR lpszPostUrl, TCHAR** pptszListHdr, int nHdrCount, int nSDType) -{ - int nSDLen = 1024; - int nAuthType = 0; - int nAuthLen = MAX_PATH; - LPCTSTR lpszClientType; - TCHAR tszAuthStr[MAX_PATH]; - TCHAR tszSDBuffer[1024]; - RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam; - - memset(tszAuthStr, '\0', MAX_PATH); - memset(tszSDBuffer, '\0', sizeof(tszSDBuffer)); - memset(&st_HDRParam, '\0', sizeof(RFCCOMPONENTS_HTTP_HDRPARAM)); - - if (!st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) - { - return TRUE; - } - - if (STORAGE_NETTYPE_HTTPDOWNLOAD == nSDType) - { - lpszClientType = _T("下载客户端"); - } - else if (STORAGE_NETTYPE_HTTPUPLOADER == nSDType) - { - lpszClientType = _T("上传客户端"); - } - else - { - lpszClientType = _T("业务客户端"); - } - - if (!RfcComponents_HttpHelp_GetAuthInfo(&pptszListHdr, nHdrCount, tszAuthStr, &nAuthLen, &nAuthType)) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.bAuth = TRUE; - st_HDRParam.nHttpCode = 402; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, nSDType); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("%s:%s,没有验证信息,无法继续"), lpszClientType, lpszClientAddr); - return FALSE; - } - - if (1 == nAuthType) - { - TCHAR tszUserName[64]; - TCHAR tszUserPass[64]; - - memset(tszUserName, '\0', sizeof(tszUserName)); - memset(tszUserPass, '\0', sizeof(tszUserPass)); - - OPenSsl_Help_BasicDecoder(tszAuthStr, tszUserName, tszUserPass); - if (_tcslen(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy) > 0) - { - int nBLen = 0; - int nResponseCode = 0; - TCHAR* ptszBody = NULL; - - Protocol_StoragePacket_BasicAuth(lpszMethod, lpszPostUrl, lpszClientAddr, tszUserName, tszUserPass, tszSDBuffer, &nSDLen); - APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszSDBuffer, &nResponseCode, &ptszBody, &nBLen); - if (200 == nResponseCode) - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("%s:%s,代理服务:%s 验证通过,用户名:%s,密码:%s"), lpszClientType, lpszClientAddr, st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszUserName, tszUserPass); - } - else - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.bAuth = TRUE; - st_HDRParam.nHttpCode = nResponseCode; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, nSDType); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("%s:%s,用户验证失败,用户名:%s,密码:%s,错误码:%d,错误内容:%s"), lpszClientType, lpszClientAddr, tszUserPass, tszUserPass, nResponseCode, ptszBody); - } - BaseLib_OperatorMemory_FreeCStyle((VOID**)&ptszBody); - } - else - { - if (!Session_User_Exist(tszUserName, tszUserPass)) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.bAuth = TRUE; - st_HDRParam.nHttpCode = 402; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, nSDType); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("%s:%s,验证用户失败,无法继续"), lpszClientType, lpszClientAddr); - return FALSE; - } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("%s:%s,本地验证用户验证通过,用户名:%s,密码:%s"), lpszClientType, lpszClientAddr, tszUserName, tszUserPass); - } - } - else - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.bAuth = TRUE; - st_HDRParam.nHttpCode = 402; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, nSDType); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("%s:%s,没有验证信息,无法继续"), lpszClientType, lpszClientAddr); - return FALSE; - } - return TRUE; -} -BOOL XEngine_APPHelp_RangeFile(LPCTSTR lpszClientAddr, int* pInt_SPos, int* pInt_EPos, __int64x* pInt_Count, TCHAR** pptszListHdr, int nHdrCount, int nSDType) -{ - LPCTSTR lpszRangeStr = _T("Range"); - LPCTSTR lpszLengthStr = _T("Content-Length"); - LPCTSTR lpszClientType; - TCHAR tszKeyStr[128]; - TCHAR tszValueStr[128]; - TCHAR tszFieldStr[128]; - - memset(tszKeyStr, '\0', sizeof(tszKeyStr)); - memset(tszValueStr, '\0', sizeof(tszValueStr)); - memset(tszFieldStr, '\0', sizeof(tszFieldStr)); - - if (STORAGE_NETTYPE_HTTPDOWNLOAD == nSDType) - { - lpszClientType = _T("下载客户端"); - } - else if (STORAGE_NETTYPE_HTTPUPLOADER == nSDType) - { - lpszClientType = _T("上传客户端"); - } - else - { - lpszClientType = _T("业务客户端"); - } - //是否有范围 - if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszRangeStr, tszFieldStr)) - { - //是否没有找到 - int nBPos = 0; //某些时候有个BYTE - if (NULL != _tcsstr(tszFieldStr, _T("bytes="))) - { - nBPos = 6; - } - if (!BaseLib_OperatorString_GetKeyValue(tszFieldStr + nBPos, "-", tszKeyStr, tszValueStr)) - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("%s:%s,请求内容有范围信息,但是解析失败,内容:%s"), lpszClientType, lpszClientAddr, tszFieldStr); - return FALSE; - } - //得到 1/2 如果有的话 - TCHAR tszRangeEnd[128]; - TCHAR tszRangeCount[128]; - - memset(tszRangeEnd, '\0', sizeof(tszRangeEnd)); - memset(tszRangeCount, '\0', sizeof(tszRangeCount)); - if (BaseLib_OperatorString_GetKeyValue(tszValueStr, "/", tszRangeEnd, tszRangeCount)) - { - *pInt_SPos = _ttoi(tszKeyStr); - *pInt_EPos = _ttoi(tszRangeEnd); - *pInt_Count = _ttoi64(tszRangeCount); - } - else - { - *pInt_SPos = _ttoi(tszKeyStr); - *pInt_EPos = _ttoi(tszValueStr); - } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("%s:%s,客户端的请求设置了数据范围:%d - %d/%lld"), lpszClientType, lpszClientAddr, *pInt_SPos, *pInt_EPos, *pInt_Count); - } - else - { - if (STORAGE_NETTYPE_HTTPDOWNLOAD == nSDType) - { - return FALSE; - } - if (!RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszLengthStr, tszFieldStr)) - { - return FALSE; - } - *pInt_Count = _ttoi64(tszFieldStr); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("%s:%s,请求内容是新的数据,大小:%lld"), lpszClientType, lpszClientAddr, *pInt_Count); - } - return TRUE; -} -BOOL XEngine_APPHelp_VerHash(LPCTSTR lpszClientAddr, LPCTSTR lpszFileName, LPCTSTR lpszFileHash, TCHAR** pptszListHdr, int nHdrCount) -{ - if (st_ServiceCfg.st_XStorage.bUPHash) - { - LPCTSTR lpszKeyStr = _T("FileHash"); - TCHAR tszValueStr[MAX_PATH]; - memset(tszValueStr, '\0', MAX_PATH); - - if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszKeyStr, tszValueStr)) - { - if (0 == _tcsnicmp(lpszFileHash, tszValueStr, _tcslen(lpszFileHash))) - { - _tremove(lpszFileName); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,上传的文件信息HASH效验成功,文件:%s 原始HASH:%s,计算HASH:%s"), lpszClientAddr, lpszFileName, tszValueStr, lpszFileHash); - } - else - { - _tremove(lpszFileName); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,上传的文件信息HASH校验失败,无法继续,文件:%s 已被删除,原始HASH:%s,计算HASH:%s"), lpszClientAddr, lpszFileName, tszValueStr, lpszFileHash); - return FALSE; - } - } - else - { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,上传的信息没有附带HASH值,无法验证文件的正确性"), lpszClientAddr); - return FALSE; - } - } - return TRUE; -} \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.h b/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.h deleted file mode 100644 index 68475e3..0000000 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPHelp/Storage_APPHelp.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -BOOL XEngine_APPHelp_ProxyAuth(LPCTSTR lpszClientAddr, LPCTSTR lpszMethod, LPCTSTR lpszPostUrl, TCHAR** pptszListHdr, int nHdrCount, int nSDType = STORAGE_NETTYPE_HTTPDOWNLOAD); -BOOL XEngine_APPHelp_RangeFile(LPCTSTR lpszClientAddr, int* pInt_SPos, int* pInt_EPos, __int64x* pInt_Count, TCHAR** pptszListHdr, int nHdrCount, int nSDType = STORAGE_NETTYPE_HTTPDOWNLOAD); -BOOL XEngine_APPHelp_VerHash(LPCTSTR lpszClientAddr, LPCTSTR lpszFileName, LPCTSTR lpszFileHash, TCHAR** pptszListHdr, int nHdrCount); \ No newline at end of file -- Gitee From 0348533c9f74706b0e2b2c35739ff75f06932c3a Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 10 Jan 2022 09:37:18 +0800 Subject: [PATCH 08/34] modify:protocol function support bucket key for app --- XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h | 1 - XEngine_Source/XEngine_StorageApp/StorageApp_P2XPNet.cpp | 6 ++++-- .../Storage_APPTask/Storage_TaskManage.cpp | 5 ++--- .../Storage_APPTask/Storage_TaskP2p.cpp | 8 +++++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h b/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h index 51aafc2..7d63440 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h @@ -112,7 +112,6 @@ extern XENGINE_LBCONFIG st_LoadbalanceCfg; #include "Storage_APPTask/Storage_TaskPass.h" #include "Storage_APPTask/Storage_TaskP2p.h" #include "Storage_APPTask/Storage_TaskManage.h" -#include "Storage_APPHelp/Storage_APPHelp.h" #ifdef _WINDOWS #pragma comment(lib,"Ws2_32.lib") diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_P2XPNet.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_P2XPNet.cpp index 76ee217..1f2d6b5 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_P2XPNet.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_P2XPNet.cpp @@ -220,15 +220,17 @@ BOOL XEngine_Task_TCPP2xp(XENGINE_PROTOCOLHDR* pSt_ProtocolHdr, LPCTSTR lpszClie { TCHAR tszTimeStart[MAX_PATH]; TCHAR tszTimeEnd[MAX_PATH]; + TCHAR tszBuckKey[MAX_PATH]; TCHAR tszFileName[MAX_PATH]; TCHAR tszFileHash[MAX_PATH]; memset(tszTimeStart, '\0', MAX_PATH); memset(tszTimeEnd, '\0', MAX_PATH); + memset(tszBuckKey, '\0', MAX_PATH); memset(tszFileName, '\0', MAX_PATH); memset(tszFileHash, '\0', MAX_PATH); //用于验证协议是否正确 - if (!Protocol_StorageParse_QueryFile(lpszMsgBuffer, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash)) + if (!Protocol_StorageParse_QueryFile(lpszMsgBuffer, tszTimeStart, tszTimeEnd, tszBuckKey, tszFileName, tszFileHash)) { Protocol_P2XPPacket_Common(pSt_ProtocolHdr, tszSDBuffer, &nSDLen, 400, "协议错误"); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_TCPP2XP); @@ -254,7 +256,7 @@ BOOL XEngine_Task_TCPP2xp(XENGINE_PROTOCOLHDR* pSt_ProtocolHdr, LPCTSTR lpszClie XEngine_Net_SendMsg(pppszP2XPClient[i], (LPCTSTR)pSt_ProtocolHdr, sizeof(XENGINE_PROTOCOLHDR), STORAGE_NETTYPE_TCPP2XP); XEngine_Net_SendMsg(pppszP2XPClient[i], lpszMsgBuffer, nMsgLen, STORAGE_NETTYPE_TCPP2XP); } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("客户端:%s,请求查询文件:%s,用户个数:%d"), lpszClientAddr, tszFileName, tszFileHash, nListCount--); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("客户端:%s,请求查询Buck:%s 中的文件名:%s,HASH:%s,用户个数:%d"), lpszClientAddr, tszBuckKey, tszFileName, tszFileHash, nListCount); BaseLib_OperatorMemory_Free((XPPPMEM)&pppszP2XPClient, nListCount); } else diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp index c215133..4e9195f 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp @@ -190,7 +190,6 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp int nListCount = 0; XSTORAGECORE_DBFILE** ppSt_ListFile; Protocol_StorageParse_QueryFile(lpszMsgBuffer, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); - if (0 == st_ServiceCfg.st_XSql.nSQLType) { st_HDRParam.bIsClose = TRUE; @@ -204,11 +203,11 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp { if (1 == st_ServiceCfg.st_XSql.nSQLType) { - XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash); + XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); } else { - XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash); + XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); } Protocol_StoragePacket_QueryFile(tszMsgBuffer, &nMsgLen, &ppSt_ListFile, nListCount, tszTimeStart, tszTimeEnd); diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp index 69fdcda..330167e 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp @@ -6,6 +6,7 @@ XHTHREAD XEngine_Task_P2PThread() TCHAR tszIPAddr[128]; TCHAR tszTimeStart[64]; TCHAR tszTimeEnd[64]; + TCHAR tszBuckKey[MAX_PATH]; TCHAR tszFileName[MAX_PATH]; TCHAR tszFileHash[MAX_PATH]; @@ -16,13 +17,14 @@ XHTHREAD XEngine_Task_P2PThread() memset(tszIPAddr, '\0', sizeof(tszIPAddr)); memset(tszTimeStart, '\0', sizeof(tszTimeStart)); memset(tszTimeEnd, '\0', sizeof(tszTimeEnd)); + memset(tszBuckKey, '\0', MAX_PATH); memset(tszFileName, '\0', MAX_PATH); memset(tszFileHash, '\0', MAX_PATH); if (NetCore_BroadCast_Recv(hBroadSocket, tszMsgBuffer, &nMsgLen, tszIPAddr)) { //收到文件查询请求 - if (Protocol_StorageParse_QueryFile(tszMsgBuffer, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash)) + if (Protocol_StorageParse_QueryFile(tszMsgBuffer, tszTimeStart, tszTimeEnd, tszBuckKey, tszFileName, tszFileHash)) { //查询文件是否存在数据库,不存在不关心 if (0 != st_ServiceCfg.st_XSql.nSQLType) @@ -31,11 +33,11 @@ XHTHREAD XEngine_Task_P2PThread() XSTORAGECORE_DBFILE** pppSt_ListFile; if (1 == st_ServiceCfg.st_XSql.nSQLType) { - XStorage_MySql_FileQuery(&pppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash); + XStorage_MySql_FileQuery(&pppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBuckKey, tszFileName, tszFileHash); } else { - XStorage_SQLite_FileQuery(&pppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszFileName, tszFileHash); + XStorage_SQLite_FileQuery(&pppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBuckKey, tszFileName, tszFileHash); } if (nListCount > 0) { -- Gitee From 6f6e64c5a587df490f6a7c55bf65fc479b4f84ae Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 10 Jan 2022 13:39:55 +0800 Subject: [PATCH 09/34] modify:authorize verification code for upload and download and center modify:rangefile parse code for upload and download modify:insert bucket key for download and upload modify:hash verificaiton for upload --- .../XEngine_StorageApp/StorageApp_Center.cpp | 65 +++++++-- .../StorageApp_Download.cpp | 64 ++++++++- .../StorageApp_UPLoader.cpp | 135 ++++++++++++------ .../XEngine_StorageApp.vcxproj | 2 - .../XEngine_StorageApp.vcxproj.filters | 12 -- 5 files changed, 201 insertions(+), 77 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp index 9555ad2..4a5a0ba 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp @@ -59,16 +59,65 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int LPCTSTR lpszMethodGet = _T("GET"); LPCTSTR lpszMethodOption = _T("OPTIONS"); - if (0 == _tcsnicmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPost))) + if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) { - if (!XEngine_APPHelp_ProxyAuth(lpszClientAddr, lpszMethodPost, pSt_HTTPParam->tszHttpUri, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPCENTER)) + TCHAR tszUserName[64]; + TCHAR tszUserPass[64]; + + memset(tszUserName, '\0', sizeof(tszUserName)); + memset(tszUserPass, '\0', sizeof(tszUserPass)); + if (!APIHelp_Api_ProxyAuth(tszUserName, tszUserPass, pptszListHdr, nHdrCount)) { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,用户验证失败,错误:%lX"), lpszClientAddr, APIHelp_GetLastError()); return FALSE; } - if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) + if (_tcslen(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy) > 0) { - st_HDRParam.bAuth = TRUE; + int nBLen = 0; + int nResponseCode = 0; + TCHAR* ptszBody = NULL; + + Protocol_StoragePacket_BasicAuth(pSt_HTTPParam->tszHttpMethod, pSt_HTTPParam->tszHttpUri, lpszClientAddr, tszUserName, tszUserPass, tszSDBuffer, &nSDLen); + APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszSDBuffer, &nResponseCode, &ptszBody, &nBLen); + if (200 != nResponseCode) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = nResponseCode; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,用户验证失败,用户名:%s,密码:%s,错误码:%d,错误内容:%s"), tszUserName, tszUserPass, tszUserPass, nResponseCode, ptszBody); + } + BaseLib_OperatorMemory_FreeCStyle((VOID**)&ptszBody); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,代理服务:%s 验证通过,用户名:%s,密码:%s"), lpszClientAddr, st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszUserName, tszUserPass); } + else + { + if (!Session_User_Exist(tszUserName, tszUserPass)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,验证用户失败,无法继续"), lpszClientAddr); + return FALSE; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,本地验证用户验证通过,用户名:%s,密码:%s"), lpszClientAddr, tszUserName, tszUserPass); + } + st_HDRParam.bAuth = TRUE; + } + + if (0 == _tcsnicmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPost))) + { //使用重定向? if (APIHelp_Distributed_IsMode(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUseMode, STORAGE_NETTYPE_HTTPCENTER)) { @@ -112,14 +161,6 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int } else if (0 == _tcsnicmp(lpszMethodGet, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodGet))) { - if (!XEngine_APPHelp_ProxyAuth(lpszClientAddr, lpszMethodGet, pSt_HTTPParam->tszHttpUri, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPCENTER)) - { - return FALSE; - } - if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) - { - st_HDRParam.bAuth = TRUE; - } XEngine_Task_P2PGet(pSt_HTTPParam->tszHttpUri + 1, lpszClientAddr, pSt_HTTPParam); } else if (0 == _tcsnicmp(lpszMethodOption, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodOption))) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp index 102b81f..be0ea73 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp @@ -65,7 +65,7 @@ void CALLBACK XEngine_Download_CBSend(LPCSTR lpszClientAddr, SOCKET hSocket, LPV Session_DLStroage_GetInfo(lpszClientAddr, &st_StorageInfo); - Protocol_StoragePacket_UPDown(st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, tszProxyStr, &nPLen, st_StorageInfo.tszFileHash); + Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszFileDir, st_StorageInfo.tszBuckKey, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, st_StorageInfo.tszFileHash); if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszDLPass, tszProxyStr, &nHttpCode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("下载客户端:%s,请求完成通知返回值:%d,文件:%s,地址:%s"), lpszClientAddr, nHttpCode, st_StorageInfo.tszFileDir, st_ServiceCfg.st_XProxy.st_XProxyPass.tszDLPass); @@ -119,12 +119,61 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,发送的方法不支持"), lpszClientAddr); return FALSE; } - if (!XEngine_APPHelp_ProxyAuth(lpszClientAddr, lpszMethodGet, pSt_HTTPParam->tszHttpUri, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPDOWNLOAD)) - { - return FALSE; - } + if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) { + TCHAR tszUserName[64]; + TCHAR tszUserPass[64]; + + memset(tszUserName, '\0', sizeof(tszUserName)); + memset(tszUserPass, '\0', sizeof(tszUserPass)); + if (!APIHelp_Api_ProxyAuth(tszUserName, tszUserPass, pptszListHdr, nHdrCount)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPDOWNLOAD); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,用户验证失败,错误:%lX"), lpszClientAddr, APIHelp_GetLastError()); + return FALSE; + } + if (_tcslen(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy) > 0) + { + int nBLen = 0; + int nResponseCode = 0; + TCHAR* ptszBody = NULL; + + Protocol_StoragePacket_BasicAuth(pSt_HTTPParam->tszHttpMethod, pSt_HTTPParam->tszHttpUri, lpszClientAddr, tszUserName, tszUserPass, tszSDBuffer, &nSDLen); + APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszSDBuffer, &nResponseCode, &ptszBody, &nBLen); + if (200 != nResponseCode) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = nResponseCode; + + RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPDOWNLOAD); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,用户验证失败,用户名:%s,密码:%s,错误码:%d,错误内容:%s"), tszUserName, tszUserPass, tszUserPass, nResponseCode, ptszBody); + } + BaseLib_OperatorMemory_FreeCStyle((VOID**)&ptszBody); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("下载客户端:%s,代理服务:%s 验证通过,用户名:%s,密码:%s"), lpszClientAddr, st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszUserName, tszUserPass); + } + else + { + if (!Session_User_Exist(tszUserName, tszUserPass)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPDOWNLOAD); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,验证用户失败,无法继续"), lpszClientAddr); + return FALSE; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("下载客户端:%s,本地验证用户验证通过,用户名:%s,密码:%s"), lpszClientAddr, tszUserName, tszUserPass); + } st_HDRParam.bAuth = TRUE; } //使用重定向,这是分布式重定向实现 @@ -152,7 +201,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in int nPosStart = 0; int nPosEnd = 0; __int64x nPosCount = 0; - if (XEngine_APPHelp_RangeFile(lpszClientAddr, &nPosStart, &nPosEnd, &nPosCount, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPDOWNLOAD)) + if (APIHelp_Api_RangeFile(&nPosStart, &nPosEnd, &nPosCount, pptszListHdr, nHdrCount)) { //是否启用了断点续传 if (st_ServiceCfg.st_XStorage.bResumable) @@ -165,6 +214,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in nPosStart = 0; nPosEnd = 0; } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("下载客户端:%s,客户端的请求设置了数据范围:%d - %d/%lld"), lpszClientAddr, nPosStart, nPosEnd, nPosCount); } XENGINE_STORAGEBUCKET st_StorageBucket; memset(&st_StorageBucket, '\0', sizeof(XENGINE_STORAGEBUCKET)); @@ -188,7 +238,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in BaseLib_OperatorString_StrToHex((char*)tszHashKey, nHashLen, tszHashStr); BaseLib_OperatorString_GetFileAndPath(tszFileDir, NULL, NULL, NULL, st_HDRParam.tszMimeType); //插入数据 - if (!Session_DLStroage_Insert(lpszClientAddr, tszFileDir, &ullCount, &ullSize, nPosStart, nPosEnd, tszHashStr)) + if (!Session_DLStroage_Insert(lpszClientAddr, st_StorageBucket.tszBuckKey, tszFileDir, &ullCount, &ullSize, nPosStart, nPosEnd, tszHashStr)) { st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 404; diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index aafd197..8d5c380 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -62,12 +62,61 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,发送的方法:%s 不支持"), lpszClientAddr, pSt_HTTPParam->tszHttpMethod); return FALSE; } - if (!XEngine_APPHelp_ProxyAuth(lpszClientAddr, lpszMethodGet, pSt_HTTPParam->tszHttpUri, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPUPLOADER)) - { - return FALSE; - } + //用户验证 if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) { + TCHAR tszUserName[64]; + TCHAR tszUserPass[64]; + + memset(tszUserName, '\0', sizeof(tszUserName)); + memset(tszUserPass, '\0', sizeof(tszUserPass)); + if (!APIHelp_Api_ProxyAuth(tszUserName, tszUserPass, pptszListHdr, nHdrCount)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,用户验证失败,错误:%lX"), lpszClientAddr, APIHelp_GetLastError()); + return FALSE; + } + if (_tcslen(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy) > 0) + { + int nBLen = 0; + int nResponseCode = 0; + TCHAR* ptszBody = NULL; + + Protocol_StoragePacket_BasicAuth(pSt_HTTPParam->tszHttpMethod, pSt_HTTPParam->tszHttpUri, lpszClientAddr, tszUserName, tszUserPass, tszSDBuffer, &nSDLen); + APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszSDBuffer, &nResponseCode, &ptszBody, &nBLen); + if (200 != nResponseCode) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = nResponseCode; + + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,用户验证失败,用户名:%s,密码:%s,错误码:%d,错误内容:%s"), tszUserName, tszUserPass, tszUserPass, nResponseCode, ptszBody); + } + BaseLib_OperatorMemory_FreeCStyle((VOID**)&ptszBody); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,代理服务:%s 验证通过,用户名:%s,密码:%s"), lpszClientAddr, st_ServiceCfg.st_XProxy.st_XProxyAuth.tszAuthProxy, tszUserName, tszUserPass); + } + else + { + if (!Session_User_Exist(tszUserName, tszUserPass)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.bAuth = TRUE; + st_HDRParam.nHttpCode = 401; + + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,验证用户失败,无法继续"), lpszClientAddr); + return FALSE; + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,本地验证用户验证通过,用户名:%s,密码:%s"), lpszClientAddr, tszUserName, tszUserPass); + } st_HDRParam.bAuth = TRUE; } //使用重定向? @@ -109,45 +158,32 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in int nPosStart = 0; int nPosEnd = 0; __int64x nPosCount = 0; - //得到长度大小 - if (XEngine_APPHelp_RangeFile(lpszClientAddr, &nPosStart, &nPosEnd, &nPosCount, pptszListHdr, nHdrCount, STORAGE_NETTYPE_HTTPUPLOADER)) - { - //是新的还是断点续传的 - if ((0 != nPosStart) || (0 != nPosEnd)) - { - //是否启用了断点续传 - if (!st_ServiceCfg.st_XStorage.bResumable) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 416; - - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,请求断点续传上传文件失败,服务端关闭了此功能,文件:%s,错误:%lX"), lpszClientAddr, tszFileDir, Session_GetLastError()); - return FALSE; - } - } - } - RfcComponents_HttpServer_GetRecvModeEx(xhUPHttp, lpszClientAddr, &nRVMode, &nRVCount, &nHDSize); - if (!Session_UPStroage_Insert(lpszClientAddr, tszFileDir, nPosCount, nRVCount, nPosStart, nPosEnd)) + //得到断点续传大小 + if (!APIHelp_Api_RangeFile(&nPosStart, &nPosEnd, &nPosCount, pptszListHdr, nHdrCount)) { st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 404; - + st_HDRParam.nHttpCode = 411; RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,插入用户请求失败,文件:%s,错误:%lX"), lpszClientAddr, tszFileDir, Session_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,没有用户数据大小字段,无法继续"), lpszClientAddr); return FALSE; } - } - if (nMsgLen <= 0) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 411; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,用户数据大小为0?"), lpszClientAddr); - return FALSE; + //是新的还是断点续传的 + if ((0 != nPosStart) || (0 != nPosEnd)) + { + //是否启用了断点续传 + if (!st_ServiceCfg.st_XStorage.bResumable) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 416; + + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,请求断点续传上传文件失败,服务端关闭了此功能,文件:%s,错误:%lX"), lpszClientAddr, tszFileDir, Session_GetLastError()); + return FALSE; + } + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求设置了数据范围:%d - %d/%lld"), lpszClientAddr, nPosStart, nPosEnd, nPosCount); } Session_UPStroage_Write(lpszClientAddr, lpszMsgBuffer, nMsgLen); RfcComponents_HttpServer_GetRecvModeEx(xhUPHttp, lpszClientAddr, &nRVMode, &nRVCount, &nHDSize); @@ -182,14 +218,25 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in OPenSsl_Api_Digest(tszFileDir, tszHashStr, &nHashLen, TRUE, st_ServiceCfg.st_XStorage.nHashMode); BaseLib_OperatorString_StrToHex((char*)tszHashStr, nHashLen, st_ProtocolFile.st_ProtocolFile.tszFileHash); //处理结果 - if (!XEngine_APPHelp_VerHash(lpszClientAddr, tszFileDir, st_ProtocolFile.st_ProtocolFile.tszFileHash, pptszListHdr, nHdrCount)) + if (st_ServiceCfg.st_XStorage.bUPHash) { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 403; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); - return FALSE; + if (APIHelp_Api_VerHash(st_ProtocolFile.st_ProtocolFile.tszFileHash, pptszListHdr, nHdrCount)) + { + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,上传的文件信息HASH效验成功,文件:%s HASH:%s"), lpszClientAddr, tszFileDir, st_ProtocolFile.st_ProtocolFile.tszFileHash); + } + else + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 403; + _tremove(tszFileDir); + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,上传的文件信息HASH校验失败,无法继续,文件:%s 已被删除,HASH:%s,错误:%lX"), lpszClientAddr, tszFileDir, st_ProtocolFile.st_ProtocolFile.tszFileHash, APIHelp_GetLastError()); + return FALSE; + } } + BOOL bRet = TRUE; if (0 != st_ServiceCfg.st_XSql.nSQLType) { @@ -239,7 +286,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in memset(&st_StorageInfo, '\0', sizeof(SESSION_STORAGEINFO)); Session_UPStroage_GetInfo(lpszClientAddr, &st_StorageInfo); - Protocol_StoragePacket_UPDown(st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, tszProxyStr, &nPLen, st_ProtocolFile.st_ProtocolFile.tszFileHash); + Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszBuckKey, st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, st_ProtocolFile.st_ProtocolFile.tszFileHash); if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass, tszProxyStr, &nHttpCode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求完成通知返回值:%d,文件:%s,地址:%s"), lpszClientAddr, nHttpCode, st_StorageInfo.tszFileDir, st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass); diff --git a/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj b/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj index 3f2dc98..3386144 100644 --- a/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj +++ b/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj @@ -155,7 +155,6 @@ - @@ -170,7 +169,6 @@ - diff --git a/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj.filters b/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj.filters index f6efca7..39a8cbb 100644 --- a/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj.filters +++ b/XEngine_Source/XEngine_StorageApp/XEngine_StorageApp.vcxproj.filters @@ -19,12 +19,6 @@ {40f770d9-b733-4850-8351-c1ab77d56900} - - {a417f386-25d6-47ac-a994-5ffcf8b453ea} - - - {5625d0f7-4a2d-4a18-86b6-adaaa214ad88} - @@ -48,9 +42,6 @@ 源文件\Storage_APPTask - - 源文件\Storage_APPHelp - 源文件 @@ -83,9 +74,6 @@ 头文件\Storage_APPTask - - 头文件\Storage_APPHelp - 头文件 -- Gitee From 4323ca4a249ca467d3fff03e76749ac7bd915a1e Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 10 Jan 2022 15:52:06 +0800 Subject: [PATCH 10/34] fixed:Get length overwritten problem --- .../APIHelp_Api/APIHelp_Api.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp index 34261dd..5d73f92 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Api/APIHelp_Api.cpp @@ -161,12 +161,16 @@ BOOL CAPIHelp_Api::APIHelp_Api_RangeFile(int* pInt_SPos, int* pInt_EPos, __int64 } bFound = TRUE; } - if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszLengthStr, tszFieldStr)) + + if (0 == *pInt_Count) { - *pInt_Count = _ttoi64(tszFieldStr); - bFound = TRUE; + if (RfcComponents_HttpHelp_GetField(&pptszListHdr, nHdrCount, lpszLengthStr, tszFieldStr)) + { + *pInt_Count = _ttoi64(tszFieldStr); + bFound = TRUE; + } } - + if (!bFound) { APIHelp_IsErrorOccur = TRUE; -- Gitee From d810721a71a7aa239923d644ecd48028abac1ed7 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 11 Jan 2022 09:06:59 +0800 Subject: [PATCH 11/34] fixed:upload storage module create file error --- .../Session_Stroage/Session_UPStroage.cpp | 10 +++++----- XEngine_Source/StorageModule_Session/pch.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp index fb909d8..669bc0f 100644 --- a/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp +++ b/XEngine_Source/StorageModule_Session/Session_Stroage/Session_UPStroage.cpp @@ -125,7 +125,7 @@ BOOL CSession_UPStroage::Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTST SESSION_STORAGEUPLOADER st_Client; memset(&st_Client, '\0', sizeof(SESSION_STORAGEUPLOADER)); - + //填充下载信息 st_Client.st_StorageInfo.ullPosStart = nPosStart; st_Client.st_StorageInfo.ullPosEnd = nPostEnd; st_Client.st_StorageInfo.ullRWCount = nLeftCount; @@ -133,10 +133,10 @@ BOOL CSession_UPStroage::Session_UPStroage_Insert(LPCTSTR lpszClientAddr, LPCTST _tcscpy(st_Client.st_StorageInfo.tszBuckKey, lpszBuckKey); _tcscpy(st_Client.st_StorageInfo.tszFileDir, lpszFileDir); _tcscpy(st_Client.st_StorageInfo.tszClientAddr, lpszClientAddr); - //填充下载信息 - if ((m_bResume) && ((0 != nPosStart) || (0 != nPostEnd))) + //文件是否存在 + if ((m_bResume) && ((0 != nPosStart) || (0 != nPostEnd)) && (0 == _taccess(lpszFileDir, 0))) { - st_Client.st_StorageInfo.pSt_File = _tfopen(lpszFileDir, _T("ab+")); + st_Client.st_StorageInfo.pSt_File = _tfopen(lpszFileDir, _T("rb+")); if (NULL == st_Client.st_StorageInfo.pSt_File) { Session_IsErrorOccur = TRUE; @@ -257,7 +257,7 @@ BOOL CSession_UPStroage::Session_UPStroage_Write(LPCTSTR lpszClientAddr, LPCTSTR break; } } - stl_MapIterator->second.st_StorageInfo.ullRWLen += nMsgLen; + stl_MapIterator->second.st_StorageInfo.ullRWLen += nWLen; st_Locker.unlock_shared(); return TRUE; } diff --git a/XEngine_Source/StorageModule_Session/pch.h b/XEngine_Source/StorageModule_Session/pch.h index 218bbcb..05b469c 100644 --- a/XEngine_Source/StorageModule_Session/pch.h +++ b/XEngine_Source/StorageModule_Session/pch.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include -- Gitee From df25677e349e78a6942f93dec568d899e773ccb8 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 11 Jan 2022 09:07:58 +0800 Subject: [PATCH 12/34] added:upload support post method. fixed:not insert session module when upload file --- .../XEngine_StorageApp/StorageApp_UPLoader.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 8d5c380..2375bb0 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -50,9 +50,9 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in memset(tszFileDir, '\0', sizeof(tszFileDir)); memset(&st_HDRParam, '\0', sizeof(RFCCOMPONENTS_HTTP_HDRPARAM)); - LPCTSTR lpszMethodGet = _T("PUT"); - - if (0 != _tcsncmp(lpszMethodGet, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodGet))) + LPCTSTR lpszMethodPut = _T("PUT"); + LPCTSTR lpszMethodPost = _T("POST"); + if ((0 != _tcsncmp(lpszMethodPut, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPut))) && (0 != _tcsncmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPost)))) { st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 405; @@ -183,6 +183,16 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in return FALSE; } } + if (!Session_UPStroage_Insert(lpszClientAddr, st_StorageBucket.tszBuckKey, tszFileDir, nPosCount, nRVCount, nPosStart, nPosEnd)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 404; + + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,插入用户请求失败,文件:%s,错误:%lX"), lpszClientAddr, tszFileDir, Session_GetLastError()); + return FALSE; + } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求设置了数据范围:%d - %d/%lld"), lpszClientAddr, nPosStart, nPosEnd, nPosCount); } Session_UPStroage_Write(lpszClientAddr, lpszMsgBuffer, nMsgLen); -- Gitee From 7ab3391c67c10f7eacf3d669e9c7c738360c9635 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 11 Jan 2022 11:14:27 +0800 Subject: [PATCH 13/34] fixed:init dose not create sql table fixed:query sql time not incorrent --- .../XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp | 3 +++ .../XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp | 4 ++-- .../XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp index 3ac422e..1a8ce7c 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_MySql/XStorage_MySql.cpp @@ -592,6 +592,9 @@ XHTHREAD CXStorage_MySql::XStorage_MySql_Thread(LPVOID lParam) time_t nTimeEnd = 0; int nTime = 60 * 60 * 12; + pClass_This->XStorage_MySql_TimeDel(); + pClass_This->XStorage_MySql_CreateTable(); + while (pClass_This->bIsRun) { if ((nTimeEnd - nTimeStart) > nTime) diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp index 88e2b4e..4085548 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLHelp/XStorage_SQLHelp.cpp @@ -59,7 +59,7 @@ BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Insert(TCHAR* ptszSQLBuffer, XSTORAGECO _stprintf(tszTableName, _T("%04d%02d"), st_LibTimer.wYear, st_LibTimer.wMonth); } - _stprintf(ptszSQLBuffer, _T("INSERT INTO `%s` (BuckKey,FilePath,FileName,FileHash,FileUser,FileSize,FileTime) VALUES('%s','%s','%s','%s','%s',%lld,%04d-%02d-%02d %02d:%02d:%02d)"), tszTableName, pSt_DBFile->tszBuckKey, pSt_DBFile->st_ProtocolFile.tszFilePath, pSt_DBFile->st_ProtocolFile.tszFileName, pSt_DBFile->st_ProtocolFile.tszFileHash, pSt_DBFile->st_ProtocolFile.tszFileUser, pSt_DBFile->st_ProtocolFile.nFileSize, st_LibTimer.wYear, st_LibTimer.wMonth, st_LibTimer.wDay, st_LibTimer.wHour, st_LibTimer.wMinute, st_LibTimer.wSecond); + _stprintf(ptszSQLBuffer, _T("INSERT INTO `%s` (BuckKey,FilePath,FileName,FileHash,FileUser,FileSize,FileTime) VALUES('%s','%s','%s','%s','%s',%lld,'%04d-%02d-%02d %02d:%02d:%02d')"), tszTableName, pSt_DBFile->tszBuckKey, pSt_DBFile->st_ProtocolFile.tszFilePath, pSt_DBFile->st_ProtocolFile.tszFileName, pSt_DBFile->st_ProtocolFile.tszFileHash, pSt_DBFile->st_ProtocolFile.tszFileUser, pSt_DBFile->st_ProtocolFile.nFileSize, st_LibTimer.wYear, st_LibTimer.wMonth, st_LibTimer.wDay, st_LibTimer.wHour, st_LibTimer.wMinute, st_LibTimer.wSecond); return TRUE; } /******************************************************************** @@ -193,7 +193,7 @@ BOOL CXStorage_SQLHelp::XStorage_SQLHelp_Packet(TCHAR* ptszSQLBuffer, LPCTSTR lp } else { - _tcscat(ptszSQLBuffer, _T("WHERE ")); + _tcscat(ptszSQLBuffer, _T(" WHERE ")); } memset(tszSQLQuery, '\0', MAX_PATH); _stprintf(tszSQLQuery, _T("BuckKey = '%s'"), lpszBuckKey); diff --git a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp index 1f81bf8..891ab4e 100644 --- a/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp +++ b/XEngine_Source/XEngine_StorageComponents/XStorage_SQLPacket/XStorage_SQLite/XStorage_SQLite.cpp @@ -304,7 +304,7 @@ BOOL CXStorage_SQLite::XStorage_SQLite_FileQuery(XSTORAGECORE_DBFILE*** pppSt_Li int nLineResult = 0; int nFieldResult = 0; memset(tszSQLStatement, '\0', sizeof(tszSQLStatement)); - XStorage_SQLHelp_Query(tszSQLStatement, pptszResult[0], lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); + XStorage_SQLHelp_Query(tszSQLStatement, pptszResult[i], lpszBuckKey, NULL, lpszFile, lpszHash, NULL, lpszTimeStart, lpszTimeEnd); //查询文件 TCHAR** pptszFileResult; if (DataBase_SQLite_GetTable(xhSQL, tszSQLStatement, &pptszFileResult, &nLineResult, &nFieldResult)) @@ -584,6 +584,9 @@ XHTHREAD CXStorage_SQLite::XStorage_SQLite_Thread(LPVOID lParam) time_t nTimeEnd = 0; int nTime = 60 * 60 * 12; + pClass_This->XStorage_SQLite_TimeDel(); + pClass_This->XStorage_SQLite_CreateTable(); + while (pClass_This->bIsRun) { if ((nTimeEnd - nTimeStart) > nTime) -- Gitee From 1d1580f7b4bc3515fc4b479719eb7163be87f124 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 11 Jan 2022 11:24:01 +0800 Subject: [PATCH 14/34] modify:task manage method name delete:p2p lan and user api function --- .../Storage_APPTask/Storage_TaskManage.cpp | 259 ++++++------------ .../Storage_APPTask/Storage_TaskManage.h | 8 +- 2 files changed, 83 insertions(+), 184 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp index 4e9195f..930fe5b 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp @@ -21,7 +21,55 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,处理用户重载配置文件成功"), lpszClientAddr); } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_ADD, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_ADD))) + else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_QUERY, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_QUERY))) + { + //查询文件列表 + int nMsgLen = 10240; + TCHAR tszFileName[MAX_PATH]; + TCHAR tszFileHash[MAX_PATH]; + TCHAR tszBucketKey[128]; + TCHAR tszTimeStart[128]; + TCHAR tszTimeEnd[128]; + TCHAR tszMsgBuffer[10240]; + + memset(tszFileName, '\0', MAX_PATH); + memset(tszFileHash, '\0', MAX_PATH); + memset(tszBucketKey, '\0', sizeof(tszBucketKey)); + memset(tszTimeStart, '\0', sizeof(tszTimeStart)); + memset(tszTimeEnd, '\0', sizeof(tszTimeEnd)); + memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); + + int nListCount = 0; + XSTORAGECORE_DBFILE** ppSt_ListFile; + Protocol_StorageParse_QueryFile(lpszMsgBuffer, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); + if (0 == st_ServiceCfg.st_XSql.nSQLType) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 406; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _T("业务客户端:%s,请求查询文件列表失败,服务器没有启用这个功能"), lpszClientAddr); + } + else + { + if (1 == st_ServiceCfg.st_XSql.nSQLType) + { + XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); + } + else + { + XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); + } + + Protocol_StoragePacket_QueryFile(tszMsgBuffer, &nMsgLen, &ppSt_ListFile, nListCount, tszTimeStart, tszTimeEnd); + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszMsgBuffer, nMsgLen); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListFile, nListCount); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求查询文件列表成功,列表个数:%d"), lpszClientAddr, nListCount); + } + } + else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_INSERT, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_INSERT))) { int nListCount = 0; XSTORAGECORE_DBFILE** ppSt_DBFile; @@ -29,44 +77,39 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp Protocol_StorageParse_ReportFile(lpszMsgBuffer, nMsgLen, &ppSt_DBFile, &nListCount); for (int i = 0; i < nListCount; i++) { - if (0 == ppSt_DBFile[i]->st_ProtocolFile.nFileSize) + TCHAR tszFileDir[1024]; + memset(tszFileDir, '\0', sizeof(tszFileDir)); + //判断下文件是否存在就行了 + if (_tcslen(ppSt_DBFile[i]->tszBuckKey) > 0) { - int nHashLen = 0; - UCHAR tszHashStr[MAX_PATH]; - TCHAR tszFileDir[1024]; - struct __stat64 st_FStat; - - memset(tszHashStr, '\0', MAX_PATH); - memset(tszFileDir, '\0', sizeof(tszFileDir)); - - _stprintf(tszFileDir, _T("%s/%s"), ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); - - int nRet = _stat64(tszFileDir, &st_FStat); - if (0 != nRet) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 404; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,请求添加文件到数据库失败,文件不存在,文件;%s"), lpszClientAddr, tszFileDir); - return FALSE; - } - //获取大小 - ppSt_DBFile[i]->st_ProtocolFile.nFileSize = st_FStat.st_size; - //计算HASH - OPenSsl_Api_Digest(tszFileDir, tszHashStr, &nHashLen, TRUE, st_ServiceCfg.st_XStorage.nHashMode); - BaseLib_OperatorString_StrToHex((char*)tszHashStr, nHashLen, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); + APIHelp_Distributed_GetPathKey(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, ppSt_DBFile[i]->tszBuckKey, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath); } - if (0 != st_ServiceCfg.st_XSql.nSQLType) + _stprintf(tszFileDir, _T("%s/%s"), ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); + if (0 != _taccess(tszFileDir, 0)) { - if (1 == st_ServiceCfg.st_XSql.nSQLType) - { - XStorage_MySql_FileInsert(ppSt_DBFile[i]); - } - else - { - XStorage_SQLite_FileInsert(ppSt_DBFile[i]); - } + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 404; + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,请求添加文件到数据库失败,文件不存在,文件;%s"), lpszClientAddr, tszFileDir); + return FALSE; + } + if (0 == st_ServiceCfg.st_XSql.nSQLType) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 501; + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,请求添加文件到数据库失败,服务器没有启用数据库,不支持此功能,文件;%s"), lpszClientAddr, tszFileDir); + return FALSE; + } + if (1 == st_ServiceCfg.st_XSql.nSQLType) + { + XStorage_MySql_FileInsert(ppSt_DBFile[i]); + } + else + { + XStorage_SQLite_FileInsert(ppSt_DBFile[i]); } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求添加文件到数据库成功,文件名:%s/%s"), lpszClientAddr, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); } @@ -74,7 +117,7 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_DBFile, nListCount); } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_DEL, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_DEL))) + else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_DELETE, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_DELETE))) { int nListCount = 0; XSTORAGECORE_DBFILE** ppSt_DBFile; @@ -169,54 +212,6 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_DBFile, nListCount); } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_QUERYFILE, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_QUERYFILE))) - { - //查询文件列表 - int nMsgLen = 10240; - TCHAR tszFileName[MAX_PATH]; - TCHAR tszFileHash[MAX_PATH]; - TCHAR tszBucketKey[128]; - TCHAR tszTimeStart[128]; - TCHAR tszTimeEnd[128]; - TCHAR tszMsgBuffer[10240]; - - memset(tszFileName, '\0', MAX_PATH); - memset(tszFileHash, '\0', MAX_PATH); - memset(tszBucketKey, '\0', sizeof(tszBucketKey)); - memset(tszTimeStart, '\0', sizeof(tszTimeStart)); - memset(tszTimeEnd, '\0', sizeof(tszTimeEnd)); - memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); - - int nListCount = 0; - XSTORAGECORE_DBFILE** ppSt_ListFile; - Protocol_StorageParse_QueryFile(lpszMsgBuffer, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); - if (0 == st_ServiceCfg.st_XSql.nSQLType) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 406; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _T("业务客户端:%s,请求查询文件列表失败,服务器没有启用这个功能"), lpszClientAddr); - } - else - { - if (1 == st_ServiceCfg.st_XSql.nSQLType) - { - XStorage_MySql_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); - } - else - { - XStorage_SQLite_FileQuery(&ppSt_ListFile, &nListCount, tszTimeStart, tszTimeEnd, tszBucketKey, tszFileName, tszFileHash); - } - - Protocol_StoragePacket_QueryFile(tszMsgBuffer, &nMsgLen, &ppSt_ListFile, nListCount, tszTimeStart, tszTimeEnd); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszMsgBuffer, nMsgLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListFile, nListCount); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求查询文件列表成功,列表个数:%d"), lpszClientAddr, nListCount); - } - } else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_TASK, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_TASK))) { int nDLCount = 0; @@ -300,99 +295,5 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求删除文件夹:%s,成功"), lpszClientAddr, tszRealDir); } } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_LAN, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_LAN))) - { - TCHAR tszPubAddr[128]; - TCHAR tszPriAddr[128]; - - memset(tszPubAddr, '\0', sizeof(tszPubAddr)); - memset(tszPriAddr, '\0', sizeof(tszPriAddr)); - - if (!Protocol_P2XPParse_List(lpszMsgBuffer, nMsgLen, tszPubAddr, tszPriAddr)) - { - Protocol_P2XPPacket_Common(NULL, tszRVBuffer, &nRVLen, 400, "协议错误"); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("P2XP客户端:%s,列表请求失败,协议解析错误,错误码:%lX"), lpszClientAddr, Protocol_GetLastError()); - return FALSE; - } - //请求同步列表 - if (_tcslen(tszPriAddr) > 0) - { - int nListCount = 0; - XENGINE_P2XPPEER_PROTOCOL** ppSt_ListClients; - if (!P2XPPeer_Manage_GetLan(tszPubAddr, tszPriAddr, &ppSt_ListClients, &nListCount)) - { - Protocol_P2XPPacket_Common(NULL, tszRVBuffer, &nRVLen, 500, "协议错误"); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("P2XP客户端:%s,列表请求失败,请求同步局域网列表失败,公有地址:%s,私有地址:%s,错误码:%lX"), lpszClientAddr, tszPubAddr, tszPriAddr, P2XPPeer_GetLastError()); - return FALSE; - } - Protocol_P2XPPacket_Lan(NULL, &ppSt_ListClients, nListCount, tszRVBuffer, &nRVLen); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListClients, nListCount); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("客户端:%s,请求同步局域网列表成功,公有地址:%s,私有地址:%s"), lpszClientAddr, tszPubAddr, tszPriAddr); - } - else - { - //公网下所有列表 - int nListCount = 0; - TCHAR** ppszClientList; - list stl_ListClient; - if (P2XPPeer_Manage_GetLList(tszPubAddr, &ppszClientList, &nListCount)) - { - for (int i = 0; i < nListCount; i++) - { - int nLanCount = 0; - XENGINE_P2XPPEER_PROTOCOL** ppSt_ListClients; - - if (P2XPPeer_Manage_GetLan(tszPubAddr, ppszClientList[i], &ppSt_ListClients, &nLanCount)) - { - for (int j = 0; j < nLanCount; j++) - { - stl_ListClient.push_back(*ppSt_ListClients[j]); - } - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListClients, nLanCount); - } - } - BaseLib_OperatorMemory_Free((XPPPMEM)&ppszClientList, nListCount); - } - Protocol_P2XPPacket_WLan(NULL, &stl_ListClient, tszRVBuffer, &nRVLen); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("客户端:%s,请求同步局域网列表成功,公有地址:%s,私有地址:%s"), lpszClientAddr, tszPubAddr, tszPriAddr); - } - } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_QUERY, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_QUERY))) - { - TCHAR tszUserName[128]; - XENGINE_P2XP_PEERINFO st_PeerInfo; - - memset(tszUserName, '\0', sizeof(tszUserName)); - memset(&st_PeerInfo, '\0', sizeof(XENGINE_P2XP_PEERINFO)); - if (!Protocol_P2XPParse_User(lpszMsgBuffer, nMsgLen, tszUserName)) - { - Protocol_P2XPPacket_Common(NULL, tszRVBuffer, &nRVLen, 400, "协议错误"); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("P2XP客户端:%s,查询用户失败,协议解析错误,错误码:%lX"), lpszClientAddr, Protocol_GetLastError()); - return FALSE; - - } - if (!P2XPPeer_Manage_GetUser(tszUserName, &st_PeerInfo)) - { - Protocol_P2XPPacket_Common(NULL, tszRVBuffer, &nRVLen, 500, "协议错误"); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("P2XP客户端:%s,查询用户失败,获取用户失败,用户名:%s,错误码:%lX"), lpszClientAddr, tszUserName, P2XPPeer_GetLastError()); - return FALSE; - } - Protocol_P2XPPacket_User(NULL, &st_PeerInfo.st_PeerAddr, tszRVBuffer, &nRVLen); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("客户端:%s,请求查询用户:%s 成功"), lpszClientAddr, tszUserName); - } return TRUE; } \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h index 646ab92..0eda5ee 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h @@ -1,11 +1,9 @@ #pragma once -#define XENGINE_STORAGE_APP_METHOD_ADD _T("Add") -#define XENGINE_STORAGE_APP_METHOD_DEL _T("Del") -#define XENGINE_STORAGE_APP_METHOD_QUERYFILE _T("Query") +#define XENGINE_STORAGE_APP_METHOD_INSERT _T("Insert") +#define XENGINE_STORAGE_APP_METHOD_DELETE _T("Delete") +#define XENGINE_STORAGE_APP_METHOD_QUERY _T("Query") #define XENGINE_STORAGE_APP_METHOD_TASK _T("Task") #define XENGINE_STORAGE_APP_METHOD_DIR _T("Dir") -#define XENGINE_STORAGE_APP_METHOD_LAN _T("Lan") -#define XENGINE_STORAGE_APP_METHOD_QUERY _T("Query") BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int nMsgLen, RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, TCHAR** pptszListHdr, int nHdrCount); \ No newline at end of file -- Gitee From 35985eeae7e1d6d5477d317a99dea4c614705152 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 11 Jan 2022 15:37:03 +0800 Subject: [PATCH 15/34] fixed:dir query crashed fixed:delete method dose not delete file modify:dir and delete method support bucket process. --- .../Storage_APPTask/Storage_TaskManage.cpp | 82 ++++++++++++------- .../Storage_APPTask/Storage_TaskManage.h | 3 +- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp index 930fe5b..f7a9ac6 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp @@ -2,10 +2,10 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int nMsgLen, RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, TCHAR** pptszListHdr, int nHdrCount) { - int nSDLen = 2048; - int nRVLen = 2048; - TCHAR tszSDBuffer[2048]; - TCHAR tszRVBuffer[2048]; + int nSDLen = 10240; + int nRVLen = 10240; + TCHAR tszSDBuffer[10240]; + TCHAR tszRVBuffer[10240]; RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam; memset(tszSDBuffer, '\0', sizeof(tszSDBuffer)); @@ -133,7 +133,7 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XSTORAGECORE_DBFILE** ppSt_DBQuery; if (1 == st_ServiceCfg.st_XSql.nSQLType) { - XStorage_MySql_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); + XStorage_MySql_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, NULL, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); //删除数据库与文件 for (int i = 0; i < nQueryCount; i++) { @@ -141,12 +141,13 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp memset(tszFilePath, '\0', sizeof(tszFilePath)); _stprintf(tszFilePath, _T("%s/%s"), ppSt_DBQuery[i]->st_ProtocolFile.tszFilePath, ppSt_DBQuery[i]->st_ProtocolFile.tszFileName); - XStorage_MySql_FileDelete(NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + XStorage_MySql_FileDelete(NULL, NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + _tremove(tszFilePath); } } else { - XStorage_SQLite_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); + XStorage_SQLite_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, NULL, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); //删除数据库与文件 for (int i = 0; i < nQueryCount; i++) { @@ -154,7 +155,8 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp memset(tszFilePath, '\0', sizeof(tszFilePath)); _stprintf(tszFilePath, _T("%s/%s"), ppSt_DBQuery[i]->st_ProtocolFile.tszFilePath, ppSt_DBQuery[i]->st_ProtocolFile.tszFileName); - XStorage_SQLite_FileDelete(NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + XStorage_SQLite_FileDelete(NULL, NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + _tremove(tszFilePath); } } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求删除文件HASH成功,文件名:%s"), lpszClientAddr, ppSt_DBFile[i]->st_ProtocolFile.tszFileHash); @@ -173,10 +175,14 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XSTORAGECORE_DBFILE** ppSt_DBQuery; memset(tszFileDir, '\0', sizeof(tszFileDir)); + if (_tcslen(ppSt_DBFile[i]->tszBuckKey) > 0) + { + APIHelp_Distributed_GetPathKey(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, ppSt_DBFile[i]->tszBuckKey, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath); + } _stprintf(tszFileDir, _T("%s/%s"), ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); if (1 == st_ServiceCfg.st_XSql.nSQLType) { - XStorage_MySql_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, tszFileDir); + XStorage_MySql_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, tszFileDir); //删除数据库与文件 for (int i = 0; i < nQueryCount; i++) { @@ -184,12 +190,13 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp memset(tszFilePath, '\0', sizeof(tszFilePath)); _stprintf(tszFilePath, _T("%s/%s"), ppSt_DBQuery[i]->st_ProtocolFile.tszFilePath, ppSt_DBQuery[i]->st_ProtocolFile.tszFileName); - XStorage_MySql_FileDelete(NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + XStorage_MySql_FileDelete(NULL, NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + _tremove(tszFilePath); } } else { - XStorage_SQLite_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, tszFileDir); + XStorage_SQLite_FileQuery(&ppSt_DBQuery, &nQueryCount, NULL, NULL, NULL, tszFileDir); //删除数据库与文件 for (int i = 0; i < nQueryCount; i++) { @@ -197,14 +204,15 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp memset(tszFilePath, '\0', sizeof(tszFilePath)); _stprintf(tszFilePath, _T("%s/%s"), ppSt_DBQuery[i]->st_ProtocolFile.tszFilePath, ppSt_DBQuery[i]->st_ProtocolFile.tszFileName); - XStorage_SQLite_FileDelete(NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + XStorage_SQLite_FileDelete(NULL, NULL, ppSt_DBQuery[i]->st_ProtocolFile.tszFileHash); + _tremove(tszFilePath); } } XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求删除文件名称成功,文件名:%s/%s"), lpszClientAddr, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); } else { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,请求删除文件名称失败,因为没有启用数据库,删除的HASH:%s"), lpszClientAddr, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,请求删除文件名称失败,因为没有启用数据库,删除的文件:%s/%s"), lpszClientAddr, ppSt_DBFile[i]->st_ProtocolFile.tszFilePath, ppSt_DBFile[i]->st_ProtocolFile.tszFileName); } } } @@ -212,23 +220,6 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_DBFile, nListCount); } - else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_TASK, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_TASK))) - { - int nDLCount = 0; - int nUPCount = 0; - SESSION_STORAGEINFO** ppSt_DLInfo; - SESSION_STORAGEINFO** ppSt_UPInfo; - - Session_DLStorage_GetAll(&ppSt_DLInfo, &nDLCount); - Session_UPStorage_GetAll(&ppSt_UPInfo, &nUPCount); - - Protocol_StoragePacket_Info(tszRVBuffer, &nRVLen, &ppSt_DLInfo, &ppSt_UPInfo, nDLCount, nUPCount); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_DLInfo, nDLCount); - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_UPInfo, nUPCount); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求获取上传下载信息成功,下载个数:%d,上传个数:%d"), lpszClientAddr, nDLCount, nUPCount); - } else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_DIR, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_DIR))) { int nOPCode = 0; @@ -236,14 +227,26 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp CHAR** ppszListDir = NULL; TCHAR tszUserDir[MAX_PATH]; TCHAR tszBuckKey[MAX_PATH]; + TCHAR tszBuckPath[MAX_PATH]; TCHAR tszRealDir[1024]; memset(tszUserDir, '\0', MAX_PATH); memset(tszBuckKey, '\0', MAX_PATH); + memset(tszBuckPath, '\0', MAX_PATH); memset(tszRealDir, '\0', sizeof(tszRealDir)); Protocol_StorageParse_DirOperator(lpszMsgBuffer, tszUserDir, tszBuckKey, &nOPCode); - _stprintf(tszRealDir, _T("%s/%s"), tszBuckKey, tszUserDir); + APIHelp_Distributed_GetPathKey(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, tszBuckKey, tszBuckPath); + + if (_tcslen(tszUserDir) > 0) + { + _stprintf(tszRealDir, _T("%s/%s"), tszBuckPath, tszUserDir); + } + else + { + _stprintf(tszRealDir, _T("%s"), tszBuckPath); + } + if (0 == nOPCode) { if (!SystemApi_File_EnumFile(tszRealDir, &ppszListDir, &nListCount, NULL, NULL, TRUE, 2)) @@ -295,5 +298,22 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求删除文件夹:%s,成功"), lpszClientAddr, tszRealDir); } } + else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_TASK, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_TASK))) + { + int nDLCount = 0; + int nUPCount = 0; + SESSION_STORAGEINFO** ppSt_DLInfo; + SESSION_STORAGEINFO** ppSt_UPInfo; + + Session_DLStorage_GetAll(&ppSt_DLInfo, &nDLCount); + Session_UPStorage_GetAll(&ppSt_UPInfo, &nUPCount); + + Protocol_StoragePacket_Info(tszRVBuffer, &nRVLen, &ppSt_DLInfo, &ppSt_UPInfo, nDLCount, nUPCount); + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_DLInfo, nDLCount); + BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_UPInfo, nUPCount); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求获取上传下载信息成功,下载个数:%d,上传个数:%d"), lpszClientAddr, nDLCount, nUPCount); + } return TRUE; } \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h index 0eda5ee..e7a65bc 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.h @@ -3,7 +3,8 @@ #define XENGINE_STORAGE_APP_METHOD_INSERT _T("Insert") #define XENGINE_STORAGE_APP_METHOD_DELETE _T("Delete") #define XENGINE_STORAGE_APP_METHOD_QUERY _T("Query") -#define XENGINE_STORAGE_APP_METHOD_TASK _T("Task") #define XENGINE_STORAGE_APP_METHOD_DIR _T("Dir") +#define XENGINE_STORAGE_APP_METHOD_TASK _T("Task") +#define XENGINE_STORAGE_APP_METHOD_P2P _T("P2P") BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int nMsgLen, RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam, TCHAR** pptszListHdr, int nHdrCount); \ No newline at end of file -- Gitee From 34ac6905f765538a77db977c7d3f5406dd7ee9fa Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 12 Jan 2022 09:17:53 +0800 Subject: [PATCH 16/34] modify:Protocol_StorageParse_DirOperator lpszUserDir parament can be null --- .../Protocol_Parse/Protocol_StorageParse.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp index 133cc47..c2c2d11 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Parse/Protocol_StorageParse.cpp @@ -64,7 +64,7 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_QueryFile(LPCTSTR lpszMsgBuff { Protocol_IsErrorOccur = FALSE; - if ((NULL == lpszMsgBuffer) || (NULL == ptszTimeStart) || (NULL == ptszTimeEnd)) + if (NULL == lpszMsgBuffer) { Protocol_IsErrorOccur = TRUE; Protocol_dwErrorCode = ERROR_XENGINE_STORAGE_PROTOCOL_PARAMENT; @@ -266,8 +266,11 @@ BOOL CProtocol_StorageParse::Protocol_StorageParse_DirOperator(LPCTSTR lpszMsgBu pSt_JsonReader = NULL; *pInt_Operator = st_JsonRoot["nOPerator"].asInt(); - _tcscpy(ptszUserDir, st_JsonRoot["lpszUserDir"].asCString()); _tcscpy(ptszBuckKey, st_JsonRoot["lpszBuckKey"].asCString()); + if (!st_JsonRoot["lpszUserDir"].isNull()) + { + _tcscpy(ptszUserDir, st_JsonRoot["lpszUserDir"].asCString()); + } return TRUE; } /******************************************************************** -- Gitee From f224810edaa4c03aec76ce222be8eeff0a029f5c Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 12 Jan 2022 09:21:19 +0800 Subject: [PATCH 17/34] added:get bucket name mapping path for apihelp module --- .../StorageModule_APIHelp/APIHelp_Define.h | 24 +++++++++ .../APIHelp_Distributed.cpp | 51 +++++++++++++++++++ .../APIHelp_Distributed/APIHelp_Distributed.h | 1 + .../StorageModule_APIHelp.def | 1 + XEngine_Source/StorageModule_APIHelp/pch.cpp | 4 ++ 5 files changed, 81 insertions(+) diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h index d737d9f..24e2193 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h @@ -127,6 +127,30 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); +/******************************************************************** +函数名称:APIHelp_Distributed_GetPathKey +函数功能:通过BUCKET名称查找对应路径 + 参数.一:pStl_ListBucket + In/Out:In + 类型:STL容器指针 + 可空:N + 意思:输入要操作的BUCKET容器 + 参数.二:lpszBuckKey + In/Out:In + 类型:常量字符指针 + 可空:N + 意思:输入要匹配的BUCKET名称 + 参数.三:ptszFilePath + In/Out:Out + 类型:字符指针 + 可空:N + 意思:输出找到的路径 +返回值 + 类型:逻辑型 + 意思:是否成功 +备注: +*********************************************************************/ +extern "C" BOOL APIHelp_Distributed_GetPathKey(list* pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR* ptszFilePath); /************************************************************************/ /* 帮助函数 */ /************************************************************************/ diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp index 7de6bc0..62d0a48 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp @@ -283,6 +283,57 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list* pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR* ptszFilePath) +{ + APIHelp_IsErrorOccur = FALSE; + + if ((NULL == pStl_ListBucket) || (NULL == lpszBuckKey) || (NULL == ptszFilePath)) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_PARAMENT; + return FALSE; + } + BOOL bFound = FALSE; + for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) + { + if (0 == _tcsncmp(lpszBuckKey, stl_ListIterator->tszBuckKey, _tcslen(lpszBuckKey))) + { + _tcscpy(ptszFilePath, stl_ListIterator->tszFilePath); + bFound = TRUE; + break; + } + } + if (!bFound) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTFOUND; + return FALSE; + } + return TRUE; +} ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h index 5c9d514..053b58b 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h @@ -23,6 +23,7 @@ public: BOOL APIHelp_Distributed_FileList(list* pStl_ListParse, XSTORAGECORE_DBFILE*** pppSt_ListPacket, int* pInt_ListCount); BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); + BOOL APIHelp_Distributed_GetPathKey(list* pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR* ptszFilePath); protected: BOOL APIHelp_Distributed_FileListParse(LPCTSTR lpszMsgBuffer, int nMsgLen, XSTORAGECORE_DBFILE* pSt_DBFile); __int64u APIHelp_Distributed_GetSize(LPCTSTR lpszMsgBuffer); diff --git a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def index 1602d00..f25a659 100644 --- a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def +++ b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def @@ -8,6 +8,7 @@ EXPORTS APIHelp_Distributed_FileList APIHelp_Distributed_DLStorage APIHelp_Distributed_UPStorage + APIHelp_Distributed_GetPathKey APIHelp_Api_ProxyAuth APIHelp_Api_RangeFile diff --git a/XEngine_Source/StorageModule_APIHelp/pch.cpp b/XEngine_Source/StorageModule_APIHelp/pch.cpp index e41699e..d001c3f 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.cpp +++ b/XEngine_Source/StorageModule_APIHelp/pch.cpp @@ -51,6 +51,10 @@ extern "C" BOOL APIHelp_Distributed_UPStorage(list*pStl_L { return m_APIDistributed.APIHelp_Distributed_UPStorage(pStl_ListBucket, pSt_StorageBucket); } +extern "C" BOOL APIHelp_Distributed_GetPathKey(list*pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR * ptszFilePath) +{ + return m_APIDistributed.APIHelp_Distributed_GetPathKey(pStl_ListBucket, lpszBuckKey, ptszFilePath); +} /************************************************************************/ /* 帮助函数 */ /************************************************************************/ -- Gitee From 51da3175b1c4cde0bdd21d6c81f2bfb5fc8bdef8 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 13 Jan 2022 15:42:59 +0800 Subject: [PATCH 18/34] fixed:app client complie problem modify:app client p2p http request --- .../APPClient_Download/APPClient_Download.cpp | 8 ++++++-- .../APPClient_P2XPClient.cpp | 4 ++-- XEngine_APPClient/XEngine_APPClient.sln | 20 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/XEngine_APPClient/APPClient_Download/APPClient_Download.cpp b/XEngine_APPClient/APPClient_Download/APPClient_Download.cpp index 3b3d885..bd21d79 100644 --- a/XEngine_APPClient/APPClient_Download/APPClient_Download.cpp +++ b/XEngine_APPClient/APPClient_Download/APPClient_Download.cpp @@ -155,10 +155,14 @@ int main() int nBodyLen = 2048; TCHAR *ptszMsgBody = NULL; //请求分布式存储文件所有位置 - LPCTSTR lpszUrl = _T("http://127.0.0.1:5100/7D54D6E40367F2763B8C8056EADC517F"); + LPCTSTR lpszUrl = _T("http://127.0.0.1:5100/Api/Manage/P2P"); LPCTSTR lpszFile = _T("D:\\XEngine_Storage\\XEngine_APPClient\\Debug\\qq.exe"); - if (!APIHelp_HttpRequest_Get(lpszUrl, &ptszMsgBody, &nBodyLen, &nHTTPCode)) + Json::Value st_JsonRoot; + st_JsonRoot["lpszBuckKey"] = "storagekey2"; + st_JsonRoot["lpszFileHash"] = "781E5E245D69B566979B86E28D23F2C7"; + + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nHTTPCode, &ptszMsgBody, &nBodyLen)) { return -1; } diff --git a/XEngine_APPClient/APPClient_P2XPClient/APPClient_P2XPClient.cpp b/XEngine_APPClient/APPClient_P2XPClient/APPClient_P2XPClient.cpp index a61f04c..f4dbb27 100644 --- a/XEngine_APPClient/APPClient_P2XPClient/APPClient_P2XPClient.cpp +++ b/XEngine_APPClient/APPClient_P2XPClient/APPClient_P2XPClient.cpp @@ -33,10 +33,10 @@ SOCKET m_hSocket; int APPClient_P2XPLogin() { - DWORD dwNetType = 0; Json::Value st_JsonRoot; TCHAR tszMsgBuffer[2048]; XENGINE_PROTOCOLHDR st_ProtocolHdr; + ENUM_XENGINE_NETXAPI_SOCKET_CONNECTTYPE dwNetType; memset(tszPublicAddr, '\0', sizeof(tszPublicAddr)); memset(tszPrivateAddr, '\0', sizeof(tszPrivateAddr)); @@ -45,7 +45,7 @@ int APPClient_P2XPLogin() st_ProtocolHdr.wHeader = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_HEADER; st_ProtocolHdr.unOperatorType = ENUM_XENGINE_COMMUNICATION_PROTOCOL_TYPE_P2XP; - st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_AUTH_REQLOGIN; + st_ProtocolHdr.unOperatorCode = XENGINE_COMMUNICATION_PROTOCOL_OPERATOR_CODE_P2XP_REQLOGIN; st_ProtocolHdr.byVersion = 2; st_ProtocolHdr.wTail = XENGIEN_COMMUNICATION_PACKET_PROTOCOL_TAIL; diff --git a/XEngine_APPClient/XEngine_APPClient.sln b/XEngine_APPClient/XEngine_APPClient.sln index adedea9..b046e21 100644 --- a/XEngine_APPClient/XEngine_APPClient.sln +++ b/XEngine_APPClient/XEngine_APPClient.sln @@ -7,6 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "APPClient_P2XPClient", "APP EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "APPClient_Download", "APPClient_Download\APPClient_Download.vcxproj", "{16608D17-1839-48D8-A455-21AAF0257E36}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "APPClient_UPDownload", "APPClient_UPDownload\APPClient_UPDownload.vcxproj", "{01470EBD-47EC-4AC1-BA0D-C75926DD1E60}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "APPClient_RestApi", "APPClient_RestApi\APPClient_RestApi.vcxproj", "{1724FB68-563F-49E5-B36A-C1DF7BF67930}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -31,6 +35,22 @@ Global {16608D17-1839-48D8-A455-21AAF0257E36}.Release|x64.Build.0 = Release|x64 {16608D17-1839-48D8-A455-21AAF0257E36}.Release|x86.ActiveCfg = Release|Win32 {16608D17-1839-48D8-A455-21AAF0257E36}.Release|x86.Build.0 = Release|Win32 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Debug|x64.ActiveCfg = Debug|x64 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Debug|x64.Build.0 = Debug|x64 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Debug|x86.ActiveCfg = Debug|Win32 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Debug|x86.Build.0 = Debug|Win32 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Release|x64.ActiveCfg = Release|x64 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Release|x64.Build.0 = Release|x64 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Release|x86.ActiveCfg = Release|Win32 + {01470EBD-47EC-4AC1-BA0D-C75926DD1E60}.Release|x86.Build.0 = Release|Win32 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Debug|x64.ActiveCfg = Debug|x64 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Debug|x64.Build.0 = Debug|x64 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Debug|x86.ActiveCfg = Debug|Win32 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Debug|x86.Build.0 = Debug|Win32 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Release|x64.ActiveCfg = Release|x64 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Release|x64.Build.0 = Release|x64 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Release|x86.ActiveCfg = Release|Win32 + {1724FB68-563F-49E5-B36A-C1DF7BF67930}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- Gitee From 91279d332bd19399e2429bb283deeae9bc2713dd Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 13 Jan 2022 15:44:30 +0800 Subject: [PATCH 19/34] modify:move XEngine_Task_P2PGet function into XEngine_Task_Manage --- .../XEngine_StorageApp/StorageApp_Center.cpp | 5 - .../Storage_APPTask/Storage_TaskManage.cpp | 150 ++++++++++++++++++ .../Storage_APPTask/Storage_TaskP2p.cpp | 132 --------------- .../Storage_APPTask/Storage_TaskP2p.h | 3 +- 4 files changed, 151 insertions(+), 139 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp index 4a5a0ba..c41fe27 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp @@ -56,7 +56,6 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int memset(&st_HDRParam, '\0', sizeof(RFCCOMPONENTS_HTTP_HDRPARAM)); LPCTSTR lpszMethodPost = _T("POST"); - LPCTSTR lpszMethodGet = _T("GET"); LPCTSTR lpszMethodOption = _T("OPTIONS"); if (st_ServiceCfg.st_XProxy.st_XProxyAuth.bAuth) @@ -159,10 +158,6 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int XEngine_Task_Manage(tszAPIName, lpszClientAddr, lpszMsgBuffer, nMsgLen, pSt_HTTPParam, pptszListHdr, nHdrCount); } } - else if (0 == _tcsnicmp(lpszMethodGet, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodGet))) - { - XEngine_Task_P2PGet(pSt_HTTPParam->tszHttpUri + 1, lpszClientAddr, pSt_HTTPParam); - } else if (0 == _tcsnicmp(lpszMethodOption, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodOption))) { //用于心跳 diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp index f7a9ac6..e108fe1 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskManage.cpp @@ -315,5 +315,155 @@ BOOL XEngine_Task_Manage(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lp BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_UPInfo, nUPCount); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求获取上传下载信息成功,下载个数:%d,上传个数:%d"), lpszClientAddr, nDLCount, nUPCount); } + else if (0 == _tcsnicmp(XENGINE_STORAGE_APP_METHOD_P2P, lpszAPIName, _tcslen(XENGINE_STORAGE_APP_METHOD_P2P))) + { + TCHAR tszBuckKey[MAX_PATH]; + TCHAR tszFileName[MAX_PATH]; + TCHAR tszFileHash[MAX_PATH]; + + memset(tszBuckKey, '\0', MAX_PATH); + memset(tszFileName, '\0', MAX_PATH); + memset(tszFileHash, '\0', MAX_PATH); + + Protocol_StorageParse_QueryFile(lpszMsgBuffer, NULL, NULL, tszBuckKey, tszFileName, tszFileHash); + + if ((_tcslen(tszFileHash) <= 0) && (_tcslen(tszFileName) <= 0)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 400; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求文件查询失败,参数不正确,无法继续"), lpszClientAddr); + return TRUE; + } + //是否启用数据库 + if (0 == st_ServiceCfg.st_XSql.nSQLType) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 501; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求文件查询失败,服务器没有启用数据库,无法继续"), lpszClientAddr); + return TRUE; + } + //首先判断本机存在不 + int nListCount = 0; + XSTORAGECORE_DBFILE** pppSt_ListFile; + if (1 == st_ServiceCfg.st_XSql.nSQLType) + { + XStorage_MySql_FileQuery(&pppSt_ListFile, &nListCount, NULL, NULL, NULL, NULL, tszFileHash); + } + else + { + XStorage_SQLite_FileQuery(&pppSt_ListFile, &nListCount, NULL, NULL, NULL, NULL, tszFileHash); + } + if (nListCount > 0) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 200; + + for (int i = 0; i < nListCount; i++) + { + _stprintf(pppSt_ListFile[i]->tszTableName, _T("127.0.0.1:%d"), st_ServiceCfg.nStorageDLPort); + } + Protocol_StoragePacket_QueryFile(tszRVBuffer, &nRVLen, &pppSt_ListFile, nListCount); + BaseLib_OperatorMemory_Free((XPPPMEM)&pppSt_ListFile, nListCount); + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求文件查询,发现本地拥有此文件.直接返回"), lpszClientAddr); + return TRUE; + } + //根据使用模式来操作 + if (0 == st_ServiceCfg.st_P2xp.nMode) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 405; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,暂时不支持的请求"), lpszClientAddr); + return FALSE; + } + else if (1 == st_ServiceCfg.st_P2xp.nMode) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 405; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,暂时不支持的请求"), lpszClientAddr); + return FALSE; + } + else + { + //开始广播请求文件 + SOCKET hSDSocket; + SOCKET hRVSocket; + list stl_ListFile; + + Protocol_P2XPPacket_QueryFile(tszSDBuffer, &nSDLen, NULL, tszFileHash); + NetCore_BroadCast_SendInit(&hSDSocket, st_ServiceCfg.st_P2xp.nRVPort, st_ServiceCfg.tszIPAddr); + NetCore_BroadCast_RecvInit(&hRVSocket, st_ServiceCfg.st_P2xp.nSDPort); + + if (!NetCore_BroadCast_Send(hSDSocket, tszSDBuffer, nSDLen)) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 500; + + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + NetCore_BroadCast_Close(hSDSocket); + NetCore_BroadCast_Close(hRVSocket); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("业务客户端:%s,发送广播请求失败,错误:%lX"), lpszClientAddr, NetCore_GetLastError()); + return FALSE; + } + NetCore_BroadCast_Close(hSDSocket); + + time_t nTimeStart = time(NULL); + while (1) + { + APIHELP_LBFILEINFO st_FileInfo; + memset(&st_FileInfo, '\0', sizeof(APIHELP_LBFILEINFO)); + + st_FileInfo.nMsgLen = sizeof(st_FileInfo.tszMsgBuffer); + if (NetCore_BroadCast_Recv(hRVSocket, st_FileInfo.tszMsgBuffer, &st_FileInfo.nMsgLen)) + { + stl_ListFile.push_back(st_FileInfo); + } + time_t nTimeEnd = time(NULL); + if ((nTimeEnd - nTimeStart) > st_ServiceCfg.st_P2xp.nTime) + { + //大于ntime秒,退出 + break; + } + } + NetCore_BroadCast_Close(hRVSocket); + + if (stl_ListFile.empty()) + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 404; + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + } + else + { + st_HDRParam.bIsClose = TRUE; + st_HDRParam.nHttpCode = 200; + + int nListCount = 0; + XSTORAGECORE_DBFILE** ppSt_ListPacket; + APIHelp_Distributed_FileList(&stl_ListFile, &ppSt_ListPacket, &nListCount); + Protocol_StoragePacket_QueryFile(tszRVBuffer, &nRVLen, &ppSt_ListPacket, nListCount); + RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszRVBuffer, nRVLen); + BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListPacket, nListCount); + } + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求局域网文件列表成功,文件分布服务器个数:%d"), lpszClientAddr, stl_ListFile.size()); + XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); + stl_ListFile.clear(); + } + } return TRUE; } \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp index 330167e..c027f52 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.cpp @@ -56,136 +56,4 @@ XHTHREAD XEngine_Task_P2PThread() } } return 0; -} -BOOL XEngine_Task_P2PGet(LPCTSTR lpszFileHash, LPCTSTR lpszClientAddr, RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam) -{ - int nSDLen = 2048; - int nRVLen = 2048; - int nMsgLen = 2048; - TCHAR tszSDBuffer[2048]; - TCHAR tszRVBuffer[2048]; - TCHAR tszMsgBuffer[2048]; - RFCCOMPONENTS_HTTP_HDRPARAM st_HDRParam; - - memset(tszSDBuffer, '\0', sizeof(tszSDBuffer)); - memset(tszRVBuffer, '\0', sizeof(tszRVBuffer)); - memset(tszMsgBuffer, '\0', sizeof(tszMsgBuffer)); - memset(&st_HDRParam, '\0', sizeof(RFCCOMPONENTS_HTTP_HDRPARAM)); - //首先判断本机存在不 - if (0 != st_ServiceCfg.st_XSql.nSQLType) - { - int nListCount = 0; - XSTORAGECORE_DBFILE** pppSt_ListFile; - if (1 == st_ServiceCfg.st_XSql.nSQLType) - { - XStorage_MySql_FileQuery(&pppSt_ListFile, &nListCount, NULL, NULL, NULL, lpszFileHash); - } - else - { - XStorage_SQLite_FileQuery(&pppSt_ListFile, &nListCount, NULL, NULL, NULL, lpszFileHash); - } - if (nListCount > 0) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 200; - - _stprintf(pppSt_ListFile[0]->tszTableName, _T("127.0.0.1:%d"), st_ServiceCfg.nStorageDLPort); - Protocol_StoragePacket_QueryFile(tszRVBuffer, &nRVLen, &pppSt_ListFile, nListCount); - BaseLib_OperatorMemory_Free((XPPPMEM)&pppSt_ListFile, nListCount); - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam, tszRVBuffer, nRVLen); - XEngine_Net_SendMsg(lpszClientAddr, tszMsgBuffer, nMsgLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("广播端:%s,请求文件查询,发现本地拥有此文件.直接返回"), lpszClientAddr); - return TRUE; - } - } - //根据使用模式来操作 - if (0 == st_ServiceCfg.st_P2xp.nMode) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 405; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszMsgBuffer, nMsgLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("广播端:%s,暂时不支持的请求"), lpszClientAddr); - return FALSE; - } - else if (1 == st_ServiceCfg.st_P2xp.nMode) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 405; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszMsgBuffer, nMsgLen, STORAGE_NETTYPE_HTTPCENTER); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("广播端:%s,暂时不支持的请求"), lpszClientAddr); - return FALSE; - } - else - { - //开始广播请求文件 - SOCKET hSDSocket; - SOCKET hRVSocket; - list stl_ListFile; - - Protocol_P2XPPacket_QueryFile(tszSDBuffer, &nSDLen, NULL, lpszFileHash); - NetCore_BroadCast_SendInit(&hSDSocket, st_ServiceCfg.st_P2xp.nRVPort, st_ServiceCfg.tszIPAddr); - NetCore_BroadCast_RecvInit(&hRVSocket, st_ServiceCfg.st_P2xp.nSDPort); - - if (!NetCore_BroadCast_Send(hSDSocket, tszSDBuffer, nSDLen)) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 500; - - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam); - XEngine_Net_SendMsg(lpszClientAddr, tszMsgBuffer, nMsgLen, STORAGE_NETTYPE_HTTPCENTER); - NetCore_BroadCast_Close(hSDSocket); - NetCore_BroadCast_Close(hRVSocket); - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("广播端:%s,发送广播请求失败,错误:%lX"), lpszClientAddr, NetCore_GetLastError()); - return FALSE; - } - NetCore_BroadCast_Close(hSDSocket); - - time_t nTimeStart = time(NULL); - while (1) - { - APIHELP_LBFILEINFO st_FileInfo; - memset(&st_FileInfo, '\0', sizeof(APIHELP_LBFILEINFO)); - - st_FileInfo.nMsgLen = sizeof(st_FileInfo.tszMsgBuffer); - if (NetCore_BroadCast_Recv(hRVSocket, st_FileInfo.tszMsgBuffer, &st_FileInfo.nMsgLen)) - { - stl_ListFile.push_back(st_FileInfo); - } - time_t nTimeEnd = time(NULL); - if ((nTimeEnd - nTimeStart) > st_ServiceCfg.st_P2xp.nTime) - { - //大于ntime秒,退出 - break; - } - } - NetCore_BroadCast_Close(hRVSocket); - - if (stl_ListFile.empty()) - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 404; - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam); - } - else - { - st_HDRParam.bIsClose = TRUE; - st_HDRParam.nHttpCode = 200; - - int nListCount = 0; - XSTORAGECORE_DBFILE** ppSt_ListPacket; - APIHelp_Distributed_FileList(&stl_ListFile, &ppSt_ListPacket, &nListCount); - Protocol_StoragePacket_QueryFile(tszRVBuffer, &nRVLen, &ppSt_ListPacket, nListCount); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszMsgBuffer, &nMsgLen, &st_HDRParam, tszRVBuffer, nRVLen); - BaseLib_OperatorMemory_Free((XPPPMEM)&ppSt_ListPacket, nListCount); - } - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("广播端:%s,请求局域网文件列表成功,文件分布服务器个数:%d"), lpszClientAddr, stl_ListFile.size()); - XEngine_Net_SendMsg(lpszClientAddr, tszMsgBuffer, nMsgLen, STORAGE_NETTYPE_HTTPCENTER); - stl_ListFile.clear(); - } - return TRUE; } \ No newline at end of file diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.h b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.h index 7e7cec1..6e051e5 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.h +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskP2p.h @@ -1,4 +1,3 @@ #pragma once -XHTHREAD XEngine_Task_P2PThread(); -BOOL XEngine_Task_P2PGet(LPCTSTR lpszFileHash, LPCTSTR lpszClientAddr, RFCCOMPONENTS_HTTP_REQPARAM* pSt_HTTPParam); \ No newline at end of file +XHTHREAD XEngine_Task_P2PThread(); \ No newline at end of file -- Gitee From 7d54f4bff38d1be399ac62106cd4491571d0c3e6 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 14 Jan 2022 09:18:07 +0800 Subject: [PATCH 20/34] fixed:get file size is incorrent --- XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h | 1 + XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h b/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h index 7d63440..560b6ea 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Hdr.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 2375bb0..381a840 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -223,7 +223,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in _tcscpy(st_ProtocolFile.st_ProtocolFile.tszFilePath, st_StorageBucket.tszFilePath); _tcscpy(st_ProtocolFile.st_ProtocolFile.tszFileName, pSt_HTTPParam->tszHttpUri + 1); - st_ProtocolFile.st_ProtocolFile.nFileSize = nRVCount; + st_ProtocolFile.st_ProtocolFile.nFileSize = st_StorageInfo.ullFSize; OPenSsl_Api_Digest(tszFileDir, tszHashStr, &nHashLen, TRUE, st_ServiceCfg.st_XStorage.nHashMode); BaseLib_OperatorString_StrToHex((char*)tszHashStr, nHashLen, st_ProtocolFile.st_ProtocolFile.tszFileHash); -- Gitee From 1a7aec0e1ea13564e639ac025edd4e81565726be Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 14 Jan 2022 13:50:39 +0800 Subject: [PATCH 21/34] added:app client restapi and upload download test --- .../APPClient_RestApi/APPClient_RestApi.cpp | 179 ++++++++++++++++++ .../APPClient_RestApi.vcxproj | 149 +++++++++++++++ .../APPClient_RestApi.vcxproj.filters | 22 +++ .../APPClient_RestApi.vcxproj.user | 4 + .../APPClient_UPDownload.cpp | 111 +++++++++++ .../APPClient_UPDownload.vcxproj | 149 +++++++++++++++ .../APPClient_UPDownload.vcxproj.filters | 22 +++ .../APPClient_UPDownload.vcxproj.user | 4 + 8 files changed, 640 insertions(+) create mode 100644 XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.cpp create mode 100644 XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj create mode 100644 XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.filters create mode 100644 XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.user create mode 100644 XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp create mode 100644 XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj create mode 100644 XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.filters create mode 100644 XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.user diff --git a/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.cpp b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.cpp new file mode 100644 index 0000000..7f57ff9 --- /dev/null +++ b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.cpp @@ -0,0 +1,179 @@ +#ifdef _WINDOWS +#include +#include +#include +#pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib") +#pragma comment(lib,"XEngine_NetHelp/NetHelp_APIHelp") +#pragma comment(lib,"Ws2_32") +#else +#ifdef _CENTOS +#include +#else +#include +#endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +//g++ -std=c++17 -Wall -g APPClient_RestApi.cpp -o APPClient_RestApi.exe -L ../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_BaseLib -L ../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_NetHelp -lXEngine_BaseLib -lNetHelp_APIHelp -ljsoncpp -Wl,-rpath=../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_BaseLib:../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_NetHelp,--disable-new-dtags + +//查询 +void API_Manage_Query() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5100/Api/Manage/QueryFile"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + Json::Value st_JsonRoot; + st_JsonRoot["lpszTimeStart"]; + st_JsonRoot["lpszTimeEnd"]; + st_JsonRoot["lpszBuckKey"] = "storagekey2"; + + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Query:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Query:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} +//插入 +void API_Manage_Insert() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5100/Api/Manage/Insert"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + Json::Value st_JsonRoot; + Json::Value st_JsonArray; + Json::Value st_JsonObject; + + st_JsonObject["nFileSize"] = 10; + st_JsonObject["tszFileHash"] = "85E62C9D28FCE775A68DD126E0519F25"; + st_JsonObject["tszFileName"] = "2.txt"; + st_JsonObject["tszBuckKey"] = "storagekey2"; + st_JsonArray.append(st_JsonObject); + + st_JsonRoot["List"] = st_JsonArray; + st_JsonRoot["Count"] = 1; + + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Insert:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Insert:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} +//删除 +void API_Manage_Delete() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5100/Api/Manage/Delete"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + Json::Value st_JsonRoot; + Json::Value st_JsonArray; + Json::Value st_JsonObject; + + st_JsonObject["tszFileHash"] = "85E62C9D28FCE775A68DD126E0519F25"; + st_JsonArray.append(st_JsonObject); + + st_JsonRoot["List"] = st_JsonArray; + st_JsonRoot["Count"] = 1; + + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Delete:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Delete:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} +//文件夹 +void API_Manage_Dir() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5100/Api/Manage/Dir"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + Json::Value st_JsonRoot; + //创建 + st_JsonRoot["lpszBuckKey"] = "storagekey1"; + st_JsonRoot["lpszUserDir"] = "user"; + st_JsonRoot["nOPerator"] = 1; + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Dir:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Dir:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); + //查询 + st_JsonRoot.clear(); + st_JsonRoot["lpszBuckKey"] = "storagekey1"; + st_JsonRoot["lpszUserDir"]; + st_JsonRoot["nOPerator"] = 0; + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Dir:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Dir:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); + //删除 + st_JsonRoot.clear(); + st_JsonRoot["lpszBuckKey"] = "storagekey1"; + st_JsonRoot["lpszUserDir"] = "user"; + st_JsonRoot["nOPerator"] = 2; + if (!APIHelp_HttpRequest_Post(lpszUrl, st_JsonRoot.toStyledString().c_str(), &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Dir:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Dir:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} +//任务管理 +void API_Manage_Task() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5100/Api/Manage/Task"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + if (!APIHelp_HttpRequest_Post(lpszUrl, NULL, &nCode, &ptszMsgBuffer, &nLen)) + { + printf("API_Manage_Task:%lX\n", APIHelp_GetLastError()); + return; + } + printf("API_Manage_Task:%d,%s\n", nCode, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} + +int main() +{ +#ifdef _WINDOWS + WSADATA st_WSAData; + WSAStartup(MAKEWORD(2, 2), &st_WSAData); +#endif + + API_Manage_Query(); + API_Manage_Insert(); + API_Manage_Delete(); + API_Manage_Dir(); + API_Manage_Task(); +#ifdef _WINDOWS + WSACleanup(); +#endif + return 0; +} \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj new file mode 100644 index 0000000..34be015 --- /dev/null +++ b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj @@ -0,0 +1,149 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {1724fb68-563f-49e5-b36a-c1df7bf67930} + APPClientRestApi + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(XEngine_Include);$(IncludePath) + $(XEngine_Lib32);$(LibraryPath) + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.filters b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.filters new file mode 100644 index 0000000..53c01f0 --- /dev/null +++ b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.user b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/XEngine_APPClient/APPClient_RestApi/APPClient_RestApi.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp new file mode 100644 index 0000000..b796c4b --- /dev/null +++ b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp @@ -0,0 +1,111 @@ +#ifdef _WINDOWS +#include +#include +#pragma comment(lib,"XEngine_BaseLib/XEngine_BaseLib") +#pragma comment(lib,"XEngine_Core/XEngine_OPenSsl") +#pragma comment(lib,"XEngine_NetHelp/NetHelp_APIHelp") +#pragma comment(lib,"Ws2_32") +#else +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +//g++ -std=c++17 -Wall -g APPClient_UPDownload.cpp -o APPClient_UPDownload.exe -L ../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_BaseLib -L ../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_Core -L ../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_NetHelp -lXEngine_BaseLib -lXEngine_OPenSsl -lNetHelp_APIHelp -Wl,-rpath=../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_BaseLib:../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_Core:../../../XEngine/XEngine_Release/XEngine_Linux/Ubuntu/XEngine_NetHelp,--disable-new-dtags + +//上传文件 +void File_UPLoad() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5102/2.txt"); + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + TCHAR tszBaseBuffer[128]; + TCHAR tszHdrBuffer[MAX_PATH]; + LPCTSTR lpszMsgBuffer = _T("01234"); + LPCTSTR lpszMsgBuffer2 = _T("56789"); + + memset(tszBaseBuffer, '\0', sizeof(tszBaseBuffer)); + memset(tszHdrBuffer, '\0', MAX_PATH); + OPenSsl_Help_BasicEncoder("123123aa", "123123", tszBaseBuffer); + + _stprintf(tszHdrBuffer, _T("Range: bytes=0-5/10\r\nAuthorization: %s\r\n"), tszBaseBuffer); + if (!APIHelp_HttpRequest_Post(lpszUrl, lpszMsgBuffer, &nCode, &ptszMsgBuffer, &nLen, tszHdrBuffer)) + { + printf("upload failed:%lX\n", APIHelp_GetLastError()); + return; + } + printf("upload:%d\n", nCode); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); + + memset(tszHdrBuffer, '\0', MAX_PATH); + _stprintf(tszHdrBuffer, _T("Range: bytes=5-9/10\r\nAuthorization: %s\r\n"), tszBaseBuffer); + if (!APIHelp_HttpRequest_Post(lpszUrl, lpszMsgBuffer2, &nCode, &ptszMsgBuffer, &nLen, tszHdrBuffer)) + { + printf("upload failed:%lX\n", APIHelp_GetLastError()); + return; + } + printf("upload:%d\n", nCode); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} +//下载文件 +void File_Download() +{ + LPCTSTR lpszUrl = _T("http://192.168.1.8:5101/storagekey2/2.txt"); + + int nLen = 0; + int nCode = 0; + TCHAR* ptszMsgBuffer = NULL; + TCHAR tszBaseBuffer[128]; + TCHAR tszHdrBuffer[MAX_PATH]; + + memset(tszBaseBuffer, '\0', sizeof(tszBaseBuffer)); + memset(tszHdrBuffer, '\0', MAX_PATH); + OPenSsl_Help_BasicEncoder("123123aa", "123123", tszBaseBuffer); + + _stprintf(tszHdrBuffer, _T("Range: bytes=0-5\r\nAuthorization: %s\r\n"), tszBaseBuffer); + if (!APIHelp_HttpRequest_Get(lpszUrl, &ptszMsgBuffer, &nLen, &nCode, tszHdrBuffer)) + { + printf("download failed:%lX\n", APIHelp_GetLastError()); + return; + } + printf("download:%d,%s\n", nLen, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); + + memset(tszHdrBuffer, '\0', MAX_PATH); + _stprintf(tszHdrBuffer, _T("Range: bytes=5-10\r\nAuthorization: %s\r\n"), tszBaseBuffer); + if (!APIHelp_HttpRequest_Get(lpszUrl, &ptszMsgBuffer, &nLen, &nCode, tszHdrBuffer)) + { + printf("download failed:%lX\n", APIHelp_GetLastError()); + return; + } + printf("download:%d,%s\n", nLen, ptszMsgBuffer); + BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); +} + +int main() +{ +#ifdef _WINDOWS + WSADATA st_WSAData; + WSAStartup(MAKEWORD(2, 2), &st_WSAData); +#endif + + File_UPLoad(); + File_Download(); + +#ifdef _WINDOWS + WSACleanup(); +#endif + return 0; +} \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj new file mode 100644 index 0000000..062cd1c --- /dev/null +++ b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj @@ -0,0 +1,149 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {01470ebd-47ec-4ac1-ba0d-c75926dd1e60} + APPClientUPDownload + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(XEngine_Include);$(IncludePath) + $(XEngine_Lib32);$(LibraryPath) + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.filters b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.filters new file mode 100644 index 0000000..ba4bde4 --- /dev/null +++ b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + \ No newline at end of file diff --git a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.user b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file -- Gitee From 3a175a00b98da1bd6759ba9d04321260082eb6f3 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 14 Jan 2022 15:14:20 +0800 Subject: [PATCH 22/34] modify:Load balancing can be set for each service --- .../StorageModule_Config/Config_Define.h | 6 ++++-- .../Config_Json/Config_Json.cpp | 15 ++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/XEngine_Source/StorageModule_Config/Config_Define.h b/XEngine_Source/StorageModule_Config/Config_Define.h index de323a4..37ee2b0 100644 --- a/XEngine_Source/StorageModule_Config/Config_Define.h +++ b/XEngine_Source/StorageModule_Config/Config_Define.h @@ -126,11 +126,13 @@ typedef struct BOOL bDistributed; struct { - int nServerMode; + int nCenterMode; + int nUPLoadMode; + int nDownldMode; + int nStorageMode; }st_LBConfig; struct { - list* pStl_ListUseMode; list* pStl_ListCenter; list* pStl_ListDownload; list* pStl_ListUPLoader; diff --git a/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp b/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp index 27a639a..16acdc3 100644 --- a/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp +++ b/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp @@ -293,16 +293,19 @@ BOOL CConfig_Json::Config_Json_LoadBalance(LPCTSTR lpszConfigFile, XENGINE_LBCON } pSt_ServerConfig->bDistributed = st_JsonRoot["bDistributed"].asInt(); - if (st_JsonRoot["LBConfig"].empty() || (1 != st_JsonRoot["LBConfig"].size())) + if (st_JsonRoot["LBConfig"].empty() || (4 != st_JsonRoot["LBConfig"].size())) { Config_IsErrorOccur = TRUE; Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBCONFIG; return FALSE; } Json::Value st_JsonLBConfig = st_JsonRoot["LBConfig"]; - pSt_ServerConfig->st_LBConfig.nServerMode = st_JsonLBConfig["nUseMode"].asInt(); + pSt_ServerConfig->st_LBConfig.nCenterMode = st_JsonLBConfig["nCenterMode"].asInt(); + pSt_ServerConfig->st_LBConfig.nUPLoadMode = st_JsonLBConfig["nUPLoadMode"].asInt(); + pSt_ServerConfig->st_LBConfig.nDownldMode = st_JsonLBConfig["nDownldMode"].asInt(); + pSt_ServerConfig->st_LBConfig.nStorageMode = st_JsonLBConfig["nStorageMode"].asInt(); - if (st_JsonRoot["LoadBalance"].empty() || (5 != st_JsonRoot["LoadBalance"].size())) + if (st_JsonRoot["LoadBalance"].empty() || (4 != st_JsonRoot["LoadBalance"].size())) { Config_IsErrorOccur = TRUE; Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_LAODBALANCE; @@ -310,12 +313,6 @@ BOOL CConfig_Json::Config_Json_LoadBalance(LPCTSTR lpszConfigFile, XENGINE_LBCON } Json::Value st_JsonLoadBalance = st_JsonRoot["LoadBalance"]; - pSt_ServerConfig->st_LoadBalance.pStl_ListUseMode = new list; - for (unsigned int i = 0; i < st_JsonLoadBalance["nUseMode"].size(); i++) - { - pSt_ServerConfig->st_LoadBalance.pStl_ListUseMode->push_back(st_JsonLoadBalance["nUseMode"][i].asInt()); - } - pSt_ServerConfig->st_LoadBalance.pStl_ListCenter = new list; for (unsigned int i = 0; i < st_JsonLoadBalance["CenterAddr"].size(); i++) { -- Gitee From 8c4ef87174c239f0e7fe7fd7af93c0e4afbebfc8 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 17 Jan 2022 09:18:39 +0800 Subject: [PATCH 23/34] delete:APIHelp_Distributed_IsMode function modify:APIHelp_Distributed_RandomAddr support loadbalance mode selection --- .../StorageModule_APIHelp/APIHelp_Define.h | 26 ++---- .../APIHelp_Distributed.cpp | 85 +++++++++---------- .../APIHelp_Distributed/APIHelp_Distributed.h | 3 +- .../StorageModule_APIHelp.def | 1 - XEngine_Source/StorageModule_APIHelp/pch.cpp | 8 +- 5 files changed, 47 insertions(+), 76 deletions(-) diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h index 24e2193..1d0cec5 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h @@ -23,25 +23,6 @@ extern "C" DWORD StorageHelp_GetLastError(int* pInt_SysError = NULL); /* 分布式函数 */ /************************************************************************/ /******************************************************************** -函数名称:APIHelp_Distributed_IsMode -函数功能:判断负载模式是否为指定模式 - 参数.一:pStl_ListMode - In/Out:In - 类型:STL容器指针 - 可空:N - 意思:输入支持的模式列表 - 参数.二:nMode - In/Out:In - 类型:整数型 - 可空:N - 意思:输入要判断的模式 -返回值 - 类型:逻辑型 - 意思:是否成功 -备注: -*********************************************************************/ -extern "C" BOOL APIHelp_Distributed_IsMode(list*pStl_ListMode, int nMode); -/******************************************************************** 函数名称:APIHelp_Distributed_RandomAddr 函数功能:随机选择一个负载的重定向服务器地址 参数.一:pStl_ListAddr @@ -54,12 +35,17 @@ extern "C" BOOL APIHelp_Distributed_IsMode(list*pStl_ListMode, int nMode); 类型:字符指针 可空:N 意思:输出获取到的负载地址 + 参数.三:nMode + In/Out:Out + 类型:整数型 + 可空:N + 意思:负载模式 返回值 类型:逻辑型 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr); +extern "C" BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr, int nMode); /******************************************************************** 函数名称:APIHelp_Distributed_FileList 函数功能:解析所有解析到的内容并且打包成指定结构 diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp index 62d0a48..b73ebef 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp @@ -23,40 +23,6 @@ CAPIHelp_Distributed::~CAPIHelp_Distributed() // к ////////////////////////////////////////////////////////////////////////// /******************************************************************** -ƣAPIHelp_Distributed_IsMode -ܣжϸģʽǷΪָģʽ - .һpStl_ListMode - In/OutIn - ͣSTLָ - ɿգN - ˼ֵ֧ģʽб - .nMode - In/OutIn - ͣ - ɿգN - ˼Ҫжϵģʽ -ֵ - ͣ߼ - ˼Ƿɹ -ע -*********************************************************************/ -BOOL CAPIHelp_Distributed::APIHelp_Distributed_IsMode(list* pStl_ListMode, int nMode) -{ - APIHelp_IsErrorOccur = FALSE; - - BOOL bFound = FALSE; - list::const_iterator stl_ListIterator = pStl_ListMode->begin(); - for (; stl_ListIterator != pStl_ListMode->end(); stl_ListIterator++) - { - if (nMode == *stl_ListIterator) - { - bFound = TRUE; - break; - } - } - return bFound; -} -/******************************************************************** ƣAPIHelp_Distributed_RandomAddr ܣѡһصضַ .һpStl_ListAddr @@ -69,33 +35,58 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_IsMode(list* pStl_ListMode, ַָͣ ɿգN ˼ȡĸصַ + .nMode + In/OutOut + ͣ + ɿգN + ˼ģʽ ֵ ͣ߼ ˼Ƿɹ ע *********************************************************************/ -BOOL CAPIHelp_Distributed::APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr) +BOOL CAPIHelp_Distributed::APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr, int nMode) { APIHelp_IsErrorOccur = FALSE; - BOOL bFound = FALSE; - XNETHANDLE xhToken = 0; - - BaseLib_OperatorHandle_Create(&xhToken, 0, pStl_ListAddr->size(), FALSE); - if (xhToken == pStl_ListAddr->size()) + if (!pStl_ListAddr->empty()) { - xhToken--; + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_PARAMENT; + return FALSE; } - list::const_iterator stl_ListIterator = pStl_ListAddr->begin(); - for (XNETHANDLE i = 0; stl_ListIterator != pStl_ListAddr->end(); stl_ListIterator++, i++) + + BOOL bFound = FALSE; + if (0 == nMode) { - if (xhToken == i) + XNETHANDLE xhToken = 0; + BaseLib_OperatorHandle_Create(&xhToken, 0, pStl_ListAddr->size(), FALSE); + if (xhToken == pStl_ListAddr->size()) { - bFound = TRUE; - _tcscpy(ptszAddr, stl_ListIterator->c_str()); - break; + xhToken--; + } + list::const_iterator stl_ListIterator = pStl_ListAddr->begin(); + for (XNETHANDLE i = 0; stl_ListIterator != pStl_ListAddr->end(); stl_ListIterator++, i++) + { + if (xhToken == i) + { + bFound = TRUE; + _tcscpy(ptszAddr, stl_ListIterator->c_str()); + break; + } } } + else if (1 == nMode) + { + bFound = TRUE; + _tcscpy(ptszAddr, pStl_ListAddr->front().c_str()); + } + else if (2 == nMode) + { + + bFound = TRUE; + _tcscpy(ptszAddr, pStl_ListAddr->back().c_str()); + } return bFound; } /******************************************************************** diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h index 053b58b..39b1af0 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h @@ -18,8 +18,7 @@ public: CAPIHelp_Distributed(); ~CAPIHelp_Distributed(); public: - BOOL APIHelp_Distributed_IsMode(list* pStl_ListMode, int nMode); - BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr); + BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr, int nMode); BOOL APIHelp_Distributed_FileList(list* pStl_ListParse, XSTORAGECORE_DBFILE*** pppSt_ListPacket, int* pInt_ListCount); BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); diff --git a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def index f25a659..9f98967 100644 --- a/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def +++ b/XEngine_Source/StorageModule_APIHelp/StorageModule_APIHelp.def @@ -3,7 +3,6 @@ LIBRARY EXPORTS StorageHelp_GetLastError - APIHelp_Distributed_IsMode APIHelp_Distributed_RandomAddr APIHelp_Distributed_FileList APIHelp_Distributed_DLStorage diff --git a/XEngine_Source/StorageModule_APIHelp/pch.cpp b/XEngine_Source/StorageModule_APIHelp/pch.cpp index d001c3f..8b4201b 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.cpp +++ b/XEngine_Source/StorageModule_APIHelp/pch.cpp @@ -31,13 +31,9 @@ extern "C" DWORD StorageHelp_GetLastError(int* pInt_SysError) /************************************************************************/ /* */ /************************************************************************/ -extern "C" BOOL APIHelp_Distributed_IsMode(list*pStl_ListMode, int nMode) +extern "C" BOOL APIHelp_Distributed_RandomAddr(list*pStl_ListAddr, TCHAR * ptszAddr, int nMode) { - return m_APIDistributed.APIHelp_Distributed_IsMode(pStl_ListMode, nMode); -} -extern "C" BOOL APIHelp_Distributed_RandomAddr(list*pStl_ListAddr, TCHAR * ptszAddr) -{ - return m_APIDistributed.APIHelp_Distributed_RandomAddr(pStl_ListAddr, ptszAddr); + return m_APIDistributed.APIHelp_Distributed_RandomAddr(pStl_ListAddr, ptszAddr, nMode); } extern "C" BOOL APIHelp_Distributed_FileList(list*pStl_ListParse, XSTORAGECORE_DBFILE * **pppSt_ListPacket, int* pInt_ListCount) { -- Gitee From ba6b6342ad44a141ec51d8944e58f40ba6d111fd Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 17 Jan 2022 09:19:57 +0800 Subject: [PATCH 24/34] modify:Redirect distributed judgment method --- XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp | 4 ++-- XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp | 4 ++-- XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp | 4 ++-- .../XEngine_StorageApp/Storage_APPTask/Storage_TaskPass.cpp | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp index c41fe27..daa75ff 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp @@ -118,7 +118,7 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int if (0 == _tcsnicmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPost))) { //使用重定向? - if (APIHelp_Distributed_IsMode(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUseMode, STORAGE_NETTYPE_HTTPCENTER)) + if (st_LoadbalanceCfg.st_LBConfig.nCenterMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -129,7 +129,7 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListCenter, tszStorageAddr); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListCenter, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nCenterMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp index be0ea73..1ed8852 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp @@ -177,7 +177,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bAuth = TRUE; } //使用重定向,这是分布式重定向实现 - if (APIHelp_Distributed_IsMode(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUseMode, STORAGE_NETTYPE_HTTPDOWNLOAD)) + if (st_LoadbalanceCfg.st_LBConfig.nDownldMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -188,7 +188,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListDownload, tszStorageAddr); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListDownload, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nDownldMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 381a840..028c3a0 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -120,7 +120,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bAuth = TRUE; } //使用重定向? - if (APIHelp_Distributed_IsMode(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUseMode, STORAGE_NETTYPE_HTTPUPLOADER)) + if (st_LoadbalanceCfg.st_LBConfig.nUPLoadMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -131,7 +131,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUPLoader, tszStorageAddr); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUPLoader, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nUPLoadMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); diff --git a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskPass.cpp b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskPass.cpp index 27e9474..644e578 100644 --- a/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskPass.cpp +++ b/XEngine_Source/XEngine_StorageApp/Storage_APPTask/Storage_TaskPass.cpp @@ -38,7 +38,6 @@ BOOL XEngine_Task_Pass(LPCTSTR lpszAPIName, LPCTSTR lpszClientAddr, LPCTSTR lpsz memset(tszClientAddr, '\0', sizeof(tszClientAddr)); Protocol_StorageParse_ProxyNotify(lpszMsgBuffer, nMsgLen, tszClientAddr, tszPathKey, tszFileName, tszFileHash, &nFileSize); - RfcComponents_HttpServer_SendMsgEx(xhCenterHttp, tszSDBuffer, &nSDLen, &st_HDRParam); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPCENTER); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("业务客户端:%s,请求的下载文件通知协议成功,文件:%s,大小:%lld"), lpszClientAddr, tszFileName, nFileSize); -- Gitee From 34c0e586b28c6477beef469517861750c9ec6213 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Mon, 17 Jan 2022 14:24:56 +0800 Subject: [PATCH 25/34] modify:st_LBConfig to st_LBDistributed for configure module added:st_LBLocation configure for configure module --- .../StorageModule_Config/Config_Define.h | 9 ++++++- .../StorageModule_Config/Config_Error.h | 5 ++-- .../Config_Json/Config_Json.cpp | 26 ++++++++++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/XEngine_Source/StorageModule_Config/Config_Define.h b/XEngine_Source/StorageModule_Config/Config_Define.h index 37ee2b0..639c02d 100644 --- a/XEngine_Source/StorageModule_Config/Config_Define.h +++ b/XEngine_Source/StorageModule_Config/Config_Define.h @@ -130,7 +130,14 @@ typedef struct int nUPLoadMode; int nDownldMode; int nStorageMode; - }st_LBConfig; + }st_LBDistributed; + struct + { + int nCenterMode; + int nUPLoadMode; + int nDownldMode; + int nStorageMode; + }st_LBLocation; struct { list* pStl_ListCenter; diff --git a/XEngine_Source/StorageModule_Config/Config_Error.h b/XEngine_Source/StorageModule_Config/Config_Error.h index f64314c..556dabb 100644 --- a/XEngine_Source/StorageModule_Config/Config_Error.h +++ b/XEngine_Source/StorageModule_Config/Config_Error.h @@ -25,5 +25,6 @@ #define ERROR_XENGINE_BLOGIC_CONFIG_JSON_P2XP 0x002000A #define ERROR_XENGINE_BLOGIC_CONFIG_JSON_CERT 0x002000B -#define ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBCONFIG 0x0020010 -#define ERROR_XENGINE_BLOGIC_CONFIG_JSON_LAODBALANCE 0x0020011 \ No newline at end of file +#define ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBDISTRIBUTED 0x0020010 +#define ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBLOCATION 0x0020011 +#define ERROR_XENGINE_BLOGIC_CONFIG_JSON_LAODBALANCE 0x0020012 \ No newline at end of file diff --git a/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp b/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp index 16acdc3..d2b546b 100644 --- a/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp +++ b/XEngine_Source/StorageModule_Config/Config_Json/Config_Json.cpp @@ -293,17 +293,29 @@ BOOL CConfig_Json::Config_Json_LoadBalance(LPCTSTR lpszConfigFile, XENGINE_LBCON } pSt_ServerConfig->bDistributed = st_JsonRoot["bDistributed"].asInt(); - if (st_JsonRoot["LBConfig"].empty() || (4 != st_JsonRoot["LBConfig"].size())) + if (st_JsonRoot["LBDistributed"].empty() || (4 != st_JsonRoot["LBDistributed"].size())) { Config_IsErrorOccur = TRUE; - Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBCONFIG; + Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBDISTRIBUTED; return FALSE; } - Json::Value st_JsonLBConfig = st_JsonRoot["LBConfig"]; - pSt_ServerConfig->st_LBConfig.nCenterMode = st_JsonLBConfig["nCenterMode"].asInt(); - pSt_ServerConfig->st_LBConfig.nUPLoadMode = st_JsonLBConfig["nUPLoadMode"].asInt(); - pSt_ServerConfig->st_LBConfig.nDownldMode = st_JsonLBConfig["nDownldMode"].asInt(); - pSt_ServerConfig->st_LBConfig.nStorageMode = st_JsonLBConfig["nStorageMode"].asInt(); + Json::Value st_JsonLBDistributed = st_JsonRoot["LBDistributed"]; + pSt_ServerConfig->st_LBDistributed.nCenterMode = st_JsonLBDistributed["nCenterMode"].asInt(); + pSt_ServerConfig->st_LBDistributed.nUPLoadMode = st_JsonLBDistributed["nUPLoadMode"].asInt(); + pSt_ServerConfig->st_LBDistributed.nDownldMode = st_JsonLBDistributed["nDownldMode"].asInt(); + pSt_ServerConfig->st_LBDistributed.nStorageMode = st_JsonLBDistributed["nStorageMode"].asInt(); + + if (st_JsonRoot["LBLocation"].empty() || (4 != st_JsonRoot["LBLocation"].size())) + { + Config_IsErrorOccur = TRUE; + Config_dwErrorCode = ERROR_XENGINE_BLOGIC_CONFIG_JSON_LBLOCATION; + return FALSE; + } + Json::Value st_JsonLBLocation = st_JsonRoot["LBLocation"]; + pSt_ServerConfig->st_LBLocation.nCenterMode = st_JsonLBLocation["nCenterMode"].asInt(); + pSt_ServerConfig->st_LBLocation.nUPLoadMode = st_JsonLBLocation["nUPLoadMode"].asInt(); + pSt_ServerConfig->st_LBLocation.nDownldMode = st_JsonLBLocation["nDownldMode"].asInt(); + pSt_ServerConfig->st_LBLocation.nStorageMode = st_JsonLBLocation["nStorageMode"].asInt(); if (st_JsonRoot["LoadBalance"].empty() || (4 != st_JsonRoot["LoadBalance"].size())) { -- Gitee From 5b0c08af07d9d92595b2a4f31a556708736ad68c Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 18 Jan 2022 08:54:09 +0800 Subject: [PATCH 26/34] fixed:APIHelp_Distributed_RandomAddr mode type incorrent modify:upload interface support loadbalance mode --- .../StorageModule_APIHelp/APIHelp_Define.h | 7 +- .../APIHelp_Distributed.cpp | 70 +++++++++++++++---- .../APIHelp_Distributed/APIHelp_Distributed.h | 2 +- XEngine_Source/StorageModule_APIHelp/pch.cpp | 4 +- 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h index 1d0cec5..9809b06 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h @@ -107,12 +107,17 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); +extern "C" BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); /******************************************************************** 函数名称:APIHelp_Distributed_GetPathKey 函数功能:通过BUCKET名称查找对应路径 diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp index b73ebef..4757059 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp @@ -57,7 +57,7 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_RandomAddr(list* pStl_Lis } BOOL bFound = FALSE; - if (0 == nMode) + if (1 == nMode) { XNETHANDLE xhToken = 0; BaseLib_OperatorHandle_Create(&xhToken, 0, pStl_ListAddr->size(), FALSE); @@ -76,18 +76,25 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_RandomAddr(list* pStl_Lis } } } - else if (1 == nMode) + else if (2 == nMode) { bFound = TRUE; _tcscpy(ptszAddr, pStl_ListAddr->front().c_str()); } - else if (2 == nMode) + else if (3 == nMode) { bFound = TRUE; _tcscpy(ptszAddr, pStl_ListAddr->back().c_str()); } - return bFound; + + if (!bFound) + { + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTFOUND; + return FALSE; + } + return TRUE; } /******************************************************************** ƣAPIHelp_Distributed_FileList @@ -224,7 +231,7 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, ˼Ƿɹ ע *********************************************************************/ -BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket) +BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode) { APIHelp_IsErrorOccur = FALSE; @@ -234,15 +241,28 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list stl_BuckSelect; + //ȵõС for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) { //ֻõ if (stl_ListIterator->bEnable) { - //ȼ if (stl_ListIterator->nLevel < nLastLevel) + { + nLastLevel = stl_ListIterator->nLevel; //õС + } + } + } + //б + for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) + { + //ֻõ + if (stl_ListIterator->bEnable) + { + //ȼ + if (stl_ListIterator->nLevel == nLastLevel) { int nListCount = 0; __int64u nDirCount = 0; //ǰĿ¼С @@ -260,18 +280,44 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(listnLevel; - *pSt_StorageBucket = *stl_ListIterator; + stl_BuckSelect.push_back(*stl_ListIterator); } } } - if (!bFound) + //ָͨģʽһkey + if (!stl_BuckSelect.empty()) { APIHelp_IsErrorOccur = TRUE; APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTFOUND; return FALSE; } + if (1 == nMode) + { + XNETHANDLE xhToken = 0; + BaseLib_OperatorHandle_Create(&xhToken, 0, stl_BuckSelect.size(), FALSE); + if (xhToken == stl_BuckSelect.size()) + { + xhToken--; + } + list::const_iterator stl_ListIterator = stl_BuckSelect.begin(); + for (XNETHANDLE i = 0; stl_ListIterator != stl_BuckSelect.end(); stl_ListIterator++, i++) + { + if (xhToken == i) + { + *pSt_StorageBucket = *stl_ListIterator; + break; + } + } + } + else if (2 == nMode) + { + *pSt_StorageBucket = stl_BuckSelect.front(); + } + else if (3 == nMode) + { + *pSt_StorageBucket = stl_BuckSelect.back(); + } + return TRUE; } /******************************************************************** diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h index 39b1af0..9d2c80e 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h @@ -21,7 +21,7 @@ public: BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr, int nMode); BOOL APIHelp_Distributed_FileList(list* pStl_ListParse, XSTORAGECORE_DBFILE*** pppSt_ListPacket, int* pInt_ListCount); BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); - BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); + BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); BOOL APIHelp_Distributed_GetPathKey(list* pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR* ptszFilePath); protected: BOOL APIHelp_Distributed_FileListParse(LPCTSTR lpszMsgBuffer, int nMsgLen, XSTORAGECORE_DBFILE* pSt_DBFile); diff --git a/XEngine_Source/StorageModule_APIHelp/pch.cpp b/XEngine_Source/StorageModule_APIHelp/pch.cpp index 8b4201b..d232c66 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.cpp +++ b/XEngine_Source/StorageModule_APIHelp/pch.cpp @@ -43,9 +43,9 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list*pStl_ListBucket, XENGINE_STORAGEBUCKET * pSt_StorageBucket) +extern "C" BOOL APIHelp_Distributed_UPStorage(list*pStl_ListBucket, XENGINE_STORAGEBUCKET * pSt_StorageBucket, int nMode) { - return m_APIDistributed.APIHelp_Distributed_UPStorage(pStl_ListBucket, pSt_StorageBucket); + return m_APIDistributed.APIHelp_Distributed_UPStorage(pStl_ListBucket, pSt_StorageBucket, nMode); } extern "C" BOOL APIHelp_Distributed_GetPathKey(list*pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR * ptszFilePath) { -- Gitee From 49776b3211c1dd4da0ff94c29e213af86bf44f4f Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Tue, 18 Jan 2022 14:29:20 +0800 Subject: [PATCH 27/34] modify:filed name of configure --- XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp | 4 ++-- XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp | 4 ++-- XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp index daa75ff..4277b14 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Center.cpp @@ -118,7 +118,7 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int if (0 == _tcsnicmp(lpszMethodPost, pSt_HTTPParam->tszHttpMethod, _tcslen(lpszMethodPost))) { //使用重定向? - if (st_LoadbalanceCfg.st_LBConfig.nCenterMode > 0) + if (st_LoadbalanceCfg.st_LBDistributed.nCenterMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -129,7 +129,7 @@ BOOL XEngine_Task_HttpCenter(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, int st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListCenter, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nCenterMode); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListCenter, tszStorageAddr, st_LoadbalanceCfg.st_LBDistributed.nCenterMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp index 1ed8852..433ca2e 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp @@ -177,7 +177,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bAuth = TRUE; } //使用重定向,这是分布式重定向实现 - if (st_LoadbalanceCfg.st_LBConfig.nDownldMode > 0) + if (st_LoadbalanceCfg.st_LBDistributed.nDownldMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -188,7 +188,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListDownload, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nDownldMode); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListDownload, tszStorageAddr, st_LoadbalanceCfg.st_LBDistributed.nDownldMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 028c3a0..593072b 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -120,7 +120,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bAuth = TRUE; } //使用重定向? - if (st_LoadbalanceCfg.st_LBConfig.nUPLoadMode > 0) + if (st_LoadbalanceCfg.st_LBDistributed.nUPLoadMode > 0) { TCHAR tszHdrBuffer[1024]; TCHAR tszStorageAddr[128]; @@ -131,7 +131,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 302; - APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUPLoader, tszStorageAddr, st_LoadbalanceCfg.st_LBConfig.nUPLoadMode); + APIHelp_Distributed_RandomAddr(st_LoadbalanceCfg.st_LoadBalance.pStl_ListUPLoader, tszStorageAddr, st_LoadbalanceCfg.st_LBDistributed.nUPLoadMode); _stprintf(tszHdrBuffer, _T("Location: %s%s\r\n"), tszStorageAddr, pSt_HTTPParam->tszHttpUri); RfcComponents_HttpServer_SendMsgEx(xhDLHttp, tszSDBuffer, &nSDLen, &st_HDRParam, NULL, 0, tszHdrBuffer); @@ -146,7 +146,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in XENGINE_STORAGEBUCKET st_StorageBucket; memset(&st_StorageBucket, '\0', sizeof(XENGINE_STORAGEBUCKET)); - if (!APIHelp_Distributed_UPStorage(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, &st_StorageBucket)) + if (!APIHelp_Distributed_UPStorage(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, &st_StorageBucket, st_LoadbalanceCfg.st_LBLocation.nUPLoadMode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,请求上传文件失败,可能BUCKET:% 不正确,错误:%lX"), lpszClientAddr, pSt_HTTPParam->tszHttpUri, APIHelp_GetLastError()); return FALSE; -- Gitee From 13a4a15b1e80dcbfde2ad2e88652084108ed3c83 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Wed, 19 Jan 2022 09:51:47 +0800 Subject: [PATCH 28/34] fixed:download print log incorrent --- XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp index 433ca2e..857ec63 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp @@ -221,7 +221,7 @@ BOOL XEngine_Task_HttpDownload(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in //分布式存储 if (!APIHelp_Distributed_DLStorage(pSt_HTTPParam->tszHttpUri, st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, &st_StorageBucket)) { - XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,请求文件失败,可能BUCKET:% 不正确,错误:%lX"), lpszClientAddr, pSt_HTTPParam->tszHttpUri, APIHelp_GetLastError()); + XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("下载客户端:%s,请求文件失败,可能BUCKET:%s 不正确,错误:%lX"), lpszClientAddr, pSt_HTTPParam->tszHttpUri, APIHelp_GetLastError()); return FALSE; } _stprintf(tszFileDir, _T("%s%s"), st_StorageBucket.tszFilePath, st_StorageBucket.tszFileName); -- Gitee From 48d94e2fc98edcfe76b12e78cdbda82341540e01 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 20 Jan 2022 09:27:10 +0800 Subject: [PATCH 29/34] added:complete notify bDown field --- .../Protocol_Packet/Protocol_StoragePacket.cpp | 10 ++++++++-- .../Protocol_Packet/Protocol_StoragePacket.h | 2 +- .../StorageModule_Protocol/StorageProtocol_Define.h | 9 +++++++-- XEngine_Source/StorageModule_Protocol/pch.cpp | 4 ++-- .../XEngine_StorageApp/StorageApp_Download.cpp | 2 +- .../XEngine_StorageApp/StorageApp_UPLoader.cpp | 2 +- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp index 6ed5806..0b633ba 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.cpp @@ -353,7 +353,12 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMetho 类型:整数型 可空:N 意思:文件大小 - 参数.七:lpszFileHash + 参数.七:bDown + In/Out:In + 类型:逻辑型 + 可空:N + 意思:是上传还是下载 + 参数.八:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -363,7 +368,7 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMetho 意思:是否成功 备注: *********************************************************************/ -BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash /* = NULL */) +BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, BOOL bDown, LPCTSTR lpszFileHash /* = NULL */) { Protocol_IsErrorOccur = FALSE; @@ -375,6 +380,7 @@ BOOL CProtocol_StoragePacket::Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer } Json::Value st_JsonRoot; + st_JsonRoot["bDown"] = bDown; st_JsonRoot["lpszBuckKey"] = lpszBuckKey; st_JsonRoot["lpszFileName"] = lpszFileName; st_JsonRoot["lpszClientAddr"] = lpszClientAddr; diff --git a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h index c5bfa48..c864df8 100644 --- a/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h +++ b/XEngine_Source/StorageModule_Protocol/Protocol_Packet/Protocol_StoragePacket.h @@ -21,5 +21,5 @@ public: BOOL Protocol_StoragePacket_Info(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, SESSION_STORAGEINFO*** pppSt_DLInfo, SESSION_STORAGEINFO*** pppSt_UPInfo, int nDLCount, int nUPCount); BOOL Protocol_StoragePacket_DirOperator(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, TCHAR*** pppszListEnum, int nListCount); BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lpszPostUrl, LPCTSTR lpszClientAddr, LPCTSTR lpszUser, LPCTSTR lpszPass, TCHAR* ptszMsgBuffer, int* pInt_MsgLen); - BOOL Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash = NULL); + BOOL Protocol_StoragePacket_UPDown(TCHAR* ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, BOOL bDown, LPCTSTR lpszFileHash = NULL); }; diff --git a/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h b/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h index de32538..35c0165 100644 --- a/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h +++ b/XEngine_Source/StorageModule_Protocol/StorageProtocol_Define.h @@ -518,7 +518,12 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps 类型:整数型 可空:N 意思:文件大小 - 参数.七:lpszFileHash + 参数.七:bDown + In/Out:In + 类型:逻辑型 + 可空:N + 意思:是上传还是下载 + 参数.八:lpszFileHash In/Out:In 类型:常量字符指针 可空:Y @@ -528,7 +533,7 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps 意思:是否成功 备注: *********************************************************************/ -extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash = NULL); +extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, BOOL bDown, LPCTSTR lpszFileHash = NULL); /******************************************************************** 函数名称:Protocol_StorageParse_QueryFile 函数功能:查询回复打包协议 diff --git a/XEngine_Source/StorageModule_Protocol/pch.cpp b/XEngine_Source/StorageModule_Protocol/pch.cpp index ce4f401..0cc739b 100644 --- a/XEngine_Source/StorageModule_Protocol/pch.cpp +++ b/XEngine_Source/StorageModule_Protocol/pch.cpp @@ -98,9 +98,9 @@ extern "C" BOOL Protocol_StoragePacket_BasicAuth(LPCTSTR lpszMethod, LPCTSTR lps { return m_StoragePacket.Protocol_StoragePacket_BasicAuth(lpszMethod, lpszPostUrl, lpszClientAddr, lpszUser, lpszPass, ptszMsgBuffer, pInt_MsgLen); } -extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, LPCTSTR lpszFileHash) +extern "C" BOOL Protocol_StoragePacket_UPDown(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, LPCTSTR lpszBuckKey, LPCTSTR lpszFileName, LPCTSTR lpszClientAddr, __int64x nFileSize, BOOL bDown, LPCTSTR lpszFileHash) { - return m_StoragePacket.Protocol_StoragePacket_UPDown(ptszMsgBuffer, pInt_MsgLen, lpszBuckKey, lpszFileName, lpszClientAddr, nFileSize, lpszFileHash); + return m_StoragePacket.Protocol_StoragePacket_UPDown(ptszMsgBuffer, pInt_MsgLen, lpszBuckKey, lpszFileName, lpszClientAddr, nFileSize, bDown, lpszFileHash); } extern "C" BOOL Protocol_StoragePacket_QueryFile(TCHAR * ptszMsgBuffer, int* pInt_MsgLen, XSTORAGECORE_DBFILE * **pppSt_DBFile, int nListCount, LPCTSTR lpszTimeStart, LPCTSTR lpszTimeEnd) { diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp index 857ec63..8106562 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_Download.cpp @@ -65,7 +65,7 @@ void CALLBACK XEngine_Download_CBSend(LPCSTR lpszClientAddr, SOCKET hSocket, LPV Session_DLStroage_GetInfo(lpszClientAddr, &st_StorageInfo); - Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszFileDir, st_StorageInfo.tszBuckKey, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, st_StorageInfo.tszFileHash); + Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszFileDir, st_StorageInfo.tszBuckKey, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, TRUE, st_StorageInfo.tszFileHash); if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszDLPass, tszProxyStr, &nHttpCode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("下载客户端:%s,请求完成通知返回值:%d,文件:%s,地址:%s"), lpszClientAddr, nHttpCode, st_StorageInfo.tszFileDir, st_ServiceCfg.st_XProxy.st_XProxyPass.tszDLPass); diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 593072b..777c7d3 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -296,7 +296,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in memset(&st_StorageInfo, '\0', sizeof(SESSION_STORAGEINFO)); Session_UPStroage_GetInfo(lpszClientAddr, &st_StorageInfo); - Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszBuckKey, st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, st_ProtocolFile.st_ProtocolFile.tszFileHash); + Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszBuckKey, st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, FALSE, st_ProtocolFile.st_ProtocolFile.tszFileHash); if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass, tszProxyStr, &nHttpCode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求完成通知返回值:%d,文件:%s,地址:%s"), lpszClientAddr, nHttpCode, st_StorageInfo.tszFileDir, st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass); -- Gitee From 72c97b2a13eec2bdcca91fb72b2f462125848833 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 20 Jan 2022 09:47:26 +0800 Subject: [PATCH 30/34] added:return file info after upload complete --- .../StorageApp_UPLoader.cpp | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 777c7d3..5a03f96 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -199,7 +199,11 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in RfcComponents_HttpServer_GetRecvModeEx(xhUPHttp, lpszClientAddr, &nRVMode, &nRVCount, &nHDSize); if (nHDSize >= nRVCount) { + int nPLen = MAX_PATH; + TCHAR tszPassNotify[MAX_PATH]; SESSION_STORAGEINFO st_StorageInfo; + + memset(tszPassNotify, '\0', MAX_PATH); memset(&st_StorageInfo, '\0', sizeof(SESSION_STORAGEINFO)); Session_UPStroage_Close(lpszClientAddr); @@ -248,6 +252,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in } BOOL bRet = TRUE; + Protocol_StoragePacket_UPDown(tszPassNotify, &nPLen, st_StorageInfo.tszBuckKey, st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, FALSE, st_ProtocolFile.st_ProtocolFile.tszFileHash); if (0 != st_ServiceCfg.st_XSql.nSQLType) { _tcscpy(st_ProtocolFile.tszBuckKey, st_StorageBucket.tszBuckKey); @@ -263,7 +268,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in { st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 200; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszPassNotify, nPLen); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求上传文件成功,文件名:%s,大小:%d"), lpszClientAddr, tszFileDir, nRVCount); } @@ -271,7 +276,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in { st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 403; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszPassNotify, nPLen); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求上传文件失败,插入数据库失败:%s,错误:%lX"), lpszClientAddr, tszFileDir, XStorageDB_GetLastError()); } @@ -280,24 +285,15 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in { st_HDRParam.bIsClose = TRUE; st_HDRParam.nHttpCode = 200; - RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam); + RfcComponents_HttpServer_SendMsgEx(xhUPHttp, tszSDBuffer, &nSDLen, &st_HDRParam, tszPassNotify, nPLen); XEngine_Net_SendMsg(lpszClientAddr, tszSDBuffer, nSDLen, STORAGE_NETTYPE_HTTPUPLOADER); XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _T("上传客户端:%s,请求上传文件成功,文件名:%s,大小:%d,数据库没有启用,不插入数据库"), lpszClientAddr, tszFileDir, nRVCount); } //PASS代理 if (st_ServiceCfg.st_XProxy.st_XProxyPass.bUPPass && bRet) { - int nPLen = MAX_PATH; int nHttpCode = 0; - TCHAR tszProxyStr[MAX_PATH]; - SESSION_STORAGEINFO st_StorageInfo; - - memset(tszProxyStr, '\0', MAX_PATH); - memset(&st_StorageInfo, '\0', sizeof(SESSION_STORAGEINFO)); - - Session_UPStroage_GetInfo(lpszClientAddr, &st_StorageInfo); - Protocol_StoragePacket_UPDown(tszProxyStr, &nPLen, st_StorageInfo.tszBuckKey, st_StorageInfo.tszFileDir, st_StorageInfo.tszClientAddr, st_StorageInfo.ullRWCount, FALSE, st_ProtocolFile.st_ProtocolFile.tszFileHash); - if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass, tszProxyStr, &nHttpCode)) + if (APIHelp_HttpRequest_Post(st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass, tszPassNotify, &nHttpCode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _T("上传客户端:%s,请求完成通知返回值:%d,文件:%s,地址:%s"), lpszClientAddr, nHttpCode, st_StorageInfo.tszFileDir, st_ServiceCfg.st_XProxy.st_XProxyPass.tszUPPass); } -- Gitee From 3f4f6210eec3d290ae236cdc660b4f556ce02830 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 20 Jan 2022 13:27:35 +0800 Subject: [PATCH 31/34] added:Upload files support specifying bucket or not specifying --- .../StorageModule_APIHelp/APIHelp_Define.h | 15 +- .../APIHelp_Distributed.cpp | 138 ++++++++++-------- .../APIHelp_Distributed/APIHelp_Distributed.h | 2 +- XEngine_Source/StorageModule_APIHelp/pch.cpp | 4 +- .../StorageApp_UPLoader.cpp | 2 +- 5 files changed, 93 insertions(+), 68 deletions(-) diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h index 9809b06..fcf6900 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Define.h @@ -97,27 +97,32 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); +extern "C" BOOL APIHelp_Distributed_UPStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); /******************************************************************** 函数名称:APIHelp_Distributed_GetPathKey 函数功能:通过BUCKET名称查找对应路径 diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp index 4757059..a72bdd5 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.cpp @@ -216,22 +216,32 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, /******************************************************************** ƣAPIHelp_Distributed_UPStorage ܣֲͨʽ洢бһ洢ַ - .һpStl_ListBucket + .һlpszMsgBuffer + In/OutIn + ַָͣ + ɿգN + ˼ҪURL + .pStl_ListBucket In/OutIn ָͣ ɿգN ˼Ҫб - .pSt_StorageBucket + .pSt_StorageBucket In/OutOut ͣݽṹָ ɿգN ˼ȡĿô洢 + .ģnMode + In/OutIn + ͣ + ɿգN + ˼LBģʽ ֵ ͣ߼ ˼Ƿɹ ע *********************************************************************/ -BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode) +BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode) { APIHelp_IsErrorOccur = FALSE; @@ -241,81 +251,91 @@ BOOL CAPIHelp_Distributed::APIHelp_Distributed_UPStorage(list stl_BuckSelect; - //ȵõС - for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) + if (4 == nMode) { - //ֻõ - if (stl_ListIterator->bEnable) + if (!APIHelp_Distributed_DLStorage(lpszMsgBuffer, pStl_ListBucket, pSt_StorageBucket)) { - if (stl_ListIterator->nLevel < nLastLevel) - { - nLastLevel = stl_ListIterator->nLevel; //õС - } + return FALSE; } } - //б - for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) + else { - //ֻõ - if (stl_ListIterator->bEnable) + int nLastLevel = 99999; + list stl_BuckSelect; + //ȵõС + for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) { - //ȼ - if (stl_ListIterator->nLevel == nLastLevel) + //ֻõ + if (stl_ListIterator->bEnable) { - int nListCount = 0; - __int64u nDirCount = 0; //ǰĿ¼С - CHAR** ppListFile; - SystemApi_File_EnumFile(stl_ListIterator->tszFilePath, &ppListFile, &nListCount, NULL, NULL, TRUE, 1); - for (int j = 0; j < nListCount; j++) + if (stl_ListIterator->nLevel < nLastLevel) { - struct __stat64 st_FStat; - _stat64(ppListFile[j], &st_FStat); - nDirCount += st_FStat.st_size; + nLastLevel = stl_ListIterator->nLevel; //õС } - BaseLib_OperatorMemory_Free((XPPPMEM)&ppListFile, nListCount); - //ǰĿ¼С趨ĴС.ô - if (nDirCount >= APIHelp_Distributed_GetSize(stl_ListIterator->tszBuckSize)) + } + } + //б + for (auto stl_ListIterator = pStl_ListBucket->begin(); stl_ListIterator != pStl_ListBucket->end(); stl_ListIterator++) + { + //ֻõ + if (stl_ListIterator->bEnable) + { + //ȼ + if (stl_ListIterator->nLevel == nLastLevel) { - continue; + int nListCount = 0; + __int64u nDirCount = 0; //ǰĿ¼С + CHAR** ppListFile; + SystemApi_File_EnumFile(stl_ListIterator->tszFilePath, &ppListFile, &nListCount, NULL, NULL, TRUE, 1); + for (int j = 0; j < nListCount; j++) + { + struct __stat64 st_FStat; + _stat64(ppListFile[j], &st_FStat); + nDirCount += st_FStat.st_size; + } + BaseLib_OperatorMemory_Free((XPPPMEM)&ppListFile, nListCount); + //ǰĿ¼С趨ĴС.ô + if (nDirCount >= APIHelp_Distributed_GetSize(stl_ListIterator->tszBuckSize)) + { + continue; + } + stl_BuckSelect.push_back(*stl_ListIterator); } - stl_BuckSelect.push_back(*stl_ListIterator); } } - } - //ָͨģʽһkey - if (!stl_BuckSelect.empty()) - { - APIHelp_IsErrorOccur = TRUE; - APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTFOUND; - return FALSE; - } - if (1 == nMode) - { - XNETHANDLE xhToken = 0; - BaseLib_OperatorHandle_Create(&xhToken, 0, stl_BuckSelect.size(), FALSE); - if (xhToken == stl_BuckSelect.size()) + //ָͨģʽһkey + if (stl_BuckSelect.empty()) { - xhToken--; + APIHelp_IsErrorOccur = TRUE; + APIHelp_dwErrorCode = ERROR_STORAGE_MODULE_APIHELP_NOTFOUND; + return FALSE; } - list::const_iterator stl_ListIterator = stl_BuckSelect.begin(); - for (XNETHANDLE i = 0; stl_ListIterator != stl_BuckSelect.end(); stl_ListIterator++, i++) + if (1 == nMode) { - if (xhToken == i) + XNETHANDLE xhToken = 0; + BaseLib_OperatorHandle_Create(&xhToken, 0, stl_BuckSelect.size(), FALSE); + if (xhToken == stl_BuckSelect.size()) { - *pSt_StorageBucket = *stl_ListIterator; - break; + xhToken--; + } + list::const_iterator stl_ListIterator = stl_BuckSelect.begin(); + for (XNETHANDLE i = 0; stl_ListIterator != stl_BuckSelect.end(); stl_ListIterator++, i++) + { + if (xhToken == i) + { + *pSt_StorageBucket = *stl_ListIterator; + break; + } } } - } - else if (2 == nMode) - { - *pSt_StorageBucket = stl_BuckSelect.front(); - } - else if (3 == nMode) - { - *pSt_StorageBucket = stl_BuckSelect.back(); + else if (2 == nMode) + { + *pSt_StorageBucket = stl_BuckSelect.front(); + } + else if (3 == nMode) + { + *pSt_StorageBucket = stl_BuckSelect.back(); + } } return TRUE; diff --git a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h index 9d2c80e..4241442 100644 --- a/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h +++ b/XEngine_Source/StorageModule_APIHelp/APIHelp_Distributed/APIHelp_Distributed.h @@ -21,7 +21,7 @@ public: BOOL APIHelp_Distributed_RandomAddr(list* pStl_ListAddr, TCHAR* ptszAddr, int nMode); BOOL APIHelp_Distributed_FileList(list* pStl_ListParse, XSTORAGECORE_DBFILE*** pppSt_ListPacket, int* pInt_ListCount); BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket); - BOOL APIHelp_Distributed_UPStorage(list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); + BOOL APIHelp_Distributed_UPStorage(LPCTSTR lpszMsgBuffer, list* pStl_ListBucket, XENGINE_STORAGEBUCKET* pSt_StorageBucket, int nMode); BOOL APIHelp_Distributed_GetPathKey(list* pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR* ptszFilePath); protected: BOOL APIHelp_Distributed_FileListParse(LPCTSTR lpszMsgBuffer, int nMsgLen, XSTORAGECORE_DBFILE* pSt_DBFile); diff --git a/XEngine_Source/StorageModule_APIHelp/pch.cpp b/XEngine_Source/StorageModule_APIHelp/pch.cpp index d232c66..69853fe 100644 --- a/XEngine_Source/StorageModule_APIHelp/pch.cpp +++ b/XEngine_Source/StorageModule_APIHelp/pch.cpp @@ -43,9 +43,9 @@ extern "C" BOOL APIHelp_Distributed_DLStorage(LPCTSTR lpszMsgBuffer, list*pStl_ListBucket, XENGINE_STORAGEBUCKET * pSt_StorageBucket, int nMode) +extern "C" BOOL APIHelp_Distributed_UPStorage(LPCTSTR lpszMsgBuffer, list*pStl_ListBucket, XENGINE_STORAGEBUCKET * pSt_StorageBucket, int nMode) { - return m_APIDistributed.APIHelp_Distributed_UPStorage(pStl_ListBucket, pSt_StorageBucket, nMode); + return m_APIDistributed.APIHelp_Distributed_UPStorage(lpszMsgBuffer, pStl_ListBucket, pSt_StorageBucket, nMode); } extern "C" BOOL APIHelp_Distributed_GetPathKey(list*pStl_ListBucket, LPCTSTR lpszBuckKey, TCHAR * ptszFilePath) { diff --git a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp index 5a03f96..086ebbb 100644 --- a/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp +++ b/XEngine_Source/XEngine_StorageApp/StorageApp_UPLoader.cpp @@ -146,7 +146,7 @@ BOOL XEngine_Task_HttpUPLoader(LPCTSTR lpszClientAddr, LPCTSTR lpszMsgBuffer, in XENGINE_STORAGEBUCKET st_StorageBucket; memset(&st_StorageBucket, '\0', sizeof(XENGINE_STORAGEBUCKET)); - if (!APIHelp_Distributed_UPStorage(st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, &st_StorageBucket, st_LoadbalanceCfg.st_LBLocation.nUPLoadMode)) + if (!APIHelp_Distributed_UPStorage(pSt_HTTPParam->tszHttpUri, st_LoadbalanceCfg.st_LoadBalance.pStl_ListBucket, &st_StorageBucket, st_LoadbalanceCfg.st_LBLocation.nUPLoadMode)) { XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _T("上传客户端:%s,请求上传文件失败,可能BUCKET:% 不正确,错误:%lX"), lpszClientAddr, pSt_HTTPParam->tszHttpUri, APIHelp_GetLastError()); return FALSE; -- Gitee From c1f9f13f7ccb6a837716c83c69eac3c62c375317 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Thu, 20 Jan 2022 13:41:51 +0800 Subject: [PATCH 32/34] modify:configure file --- .../APPClient_UPDownload.cpp | 2 +- .../XEngine_Config/XEngine_Config.json | 1 + .../XEngine_Config/XEngine_LBConfig.json | 79 +++++++++++-------- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp index b796c4b..a8b8cc9 100644 --- a/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp +++ b/XEngine_APPClient/APPClient_UPDownload/APPClient_UPDownload.cpp @@ -56,7 +56,7 @@ void File_UPLoad() printf("upload failed:%lX\n", APIHelp_GetLastError()); return; } - printf("upload:%d\n", nCode); + printf("upload:%d\n%s\n", nCode, ptszMsgBuffer); BaseLib_OperatorMemory_FreeCStyle((XPPMEM)&ptszMsgBuffer); } //下载文件 diff --git a/XEngine_Release/XEngine_Config/XEngine_Config.json b/XEngine_Release/XEngine_Config/XEngine_Config.json index 2a7363e..58f2a32 100644 --- a/XEngine_Release/XEngine_Config/XEngine_Config.json +++ b/XEngine_Release/XEngine_Config/XEngine_Config.json @@ -75,6 +75,7 @@ }, "XVer":{ "StorageVersion":[ + "3.4.0.1001 Build20220121", "3.3.0.1001 Build20220106", "3.2.0.1001 Build20211211", "3.1.0.1001 Build20211109", diff --git a/XEngine_Release/XEngine_Config/XEngine_LBConfig.json b/XEngine_Release/XEngine_Config/XEngine_LBConfig.json index 3bd91f7..31cddc3 100644 --- a/XEngine_Release/XEngine_Config/XEngine_LBConfig.json +++ b/XEngine_Release/XEngine_Config/XEngine_LBConfig.json @@ -1,36 +1,45 @@ { - "bDistributed":1, - "LBConfig":{ - "nServerMode":1 - }, - "LoadBalance":{ - "nUseMode":[ - 0 - ], - "CenterAddr":[ - "http://192.168.1.9:5100" - ], - "DownloadAddr":[ - "http://192.168.1.9:5010" - ], - "UPLoaderAddr":[ - "http://192.168.1.9:5102" - ], - "StorageAddr":[ - { - "bEnable":1, - "nLevel":1, - "Size":"1024MB", - "XEngine_Key":"storagekey1", - "XEngine_Path":"./XEngine_File" - }, - { - "bEnable":1, - "nLevel":1, - "Size":"1024MB", - "XEngine_Key":"storagekey2", - "XEngine_Path":"./XEngine_File2" - } - ] - } -} \ No newline at end of file + "bDistributed":1, + "LBDistributed":{ + "nCenterMode":0, + "nUPLoadMode":0, + "nDownldMode":0, + "nStorageMode":0 + }, + "LBLocation":{ + "nCenterMode":0, + "nUPLoadMode":1, + "nDownldMode":0, + "nStorageMode":0 + }, + "LoadBalance":{ + "CenterAddr":[ + "http://192.168.1.9:5100" + ], + "DownloadAddr":[ + "http://192.168.1.9:5010" + ], + "UPLoaderAddr":[ + "http://192.168.1.9:5102" + ], + "StorageAddr":[ + { + "bEnable":1, + "nLevel":1, + "Size":"1024MB", + "XEngine_Key":"storagekey1", + "XEngine_Path":"./XEngine_File" + } +, + { + "bEnable":1, + "nLevel":1, + "Size":"1024MB", + "XEngine_Key":"storagekey2", + "XEngine_Path":"./XEngine_File2" + } + + ] + } + +} -- Gitee From cebd8af22d2f6713668dd44bb4683753ca6a2063 Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 21 Jan 2022 09:07:23 +0800 Subject: [PATCH 33/34] update:readme and docment --- README.en.md | 5 ++--- README.md | 5 ++--- XEngine_Docment/Docment_en.docx | Bin 620751 -> 625123 bytes XEngine_Docment/Docment_zh.docx | Bin 620389 -> 624348 bytes 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.en.md b/README.en.md index ef69ad3..5bb0aa9 100644 --- a/README.en.md +++ b/README.en.md @@ -7,8 +7,8 @@ c c++ 存储服务 c c++ 文件存储服务 c c++ file storage service This is an api gateway for uploading and downloading. The service is for users who have business needs for upload and download services (such as developers who need to upload and download servers). -This server is more inclined to store the API interface direction -best storage service for http,batter than nginx and more convenient to manage. On going maintenance +This server is more inclined to storestorage transfer and API Manage interface +best storage service for http,batter than nginx and more convenient to manage,more concise code. On going maintenance ## Software feature The purpose of development and implementation based on libXEngine is a cross-platform network storage service @@ -97,7 +97,6 @@ P2P distributed download is the same as the hyper-threaded download of other dow ## now task P2P WAN file search and download support -upload file code optimization ## other problems You can refer to the document under the docment directory. It contains API protocol and service description. diff --git a/README.md b/README.md index 30d6a34..b218776 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ c c++ 存储服务 c c++ 文件存储服务 c c++ file storage service 这是一个上传下载服务API网关,不是文件同步服务,也不是云存储. 这个服务的主要目的是为了给有上传下载服务业务需求的用户使用(比如需要开发上传下载服务的开发人员). -此服务器更偏向于存储API接口方向. -目前最好的HTTP存储服务,比NGINX更优秀,更方便管理.持续维护中... +此服务器更偏向于存储传输与API接口管理. +目前最好的HTTP存储服务,比NGINX更优秀,更方便管理,代码更简洁.持续维护中... ## 软件特性 基于libXEngine开发并实现的一套简洁高性能跨平台网络存储服务 @@ -95,7 +95,6 @@ P2P分布式下载与其他下载工具的超线程下载一样,原理是使用H ## 当前任务 P2P广域网文件查找与下载支持 -文件上传代码优化 ## 其他问题 你可以参考docment目录下的文档.里面包含了API协议和服务说明. diff --git a/XEngine_Docment/Docment_en.docx b/XEngine_Docment/Docment_en.docx index 81e8d770eff7ba93b323fdc194d0008773a5566a..ddd228e6d17b9554c8af1db6737101bda568e451 100644 GIT binary patch delta 121572 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

`xW#xhB;IQ3D6Bgv>54_>RO$f96~aTiXmsIeQV< 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

=Cytjsql$ z6{O2U-&lzX=@lDrCl~{U8 zgfg&Na76rJlQr1LFute>5KVmB$>>Aj?9#F7Zw-L!66JXQVHE@*p!Cl=Ui=oJb z=RJt&M9?)%4`f#F5PVATpXuLtUHU{GPb*)@p?}Kf!>T~*+{KK9 zW*%isHaAK}tw7(rUu`zP>?^a5&rHSy-Y1;lfXe>YP9eCge*C9S)Sdp=A;&+``^@oK zG(Mm|KUfU-NU`XaV2}~8^)!5^n>lO$nV)o!e|KISvUg#FB-lNk>qha9$cg?Gb@cr| zCpW!-UC=Hf$)y8|U5SnaqDlQ@;C6XT;R>^is#a(9TaZk&BpD^bFWxfi;}uuJ^+xV} zU=;;suTxVLw4X2^A6PbltPv(>Zo@BLDSr#3O2YCx7r$(zyow&TF zTkUJFH5ipYtqmqb@=vqTCmz;$e)=@fpozJDM6V}kbMcFB9_+2NDaW}QU6k*c#puqp z+YwqL`}1W;x(@YpQEm5H<(-kE@^v|>Ooo^Z_?RXYwBK4HquW5zkCo-8+noMq%NUeG zK6qq|6PlB1lTZKNd39a#)u8B&F;*>9+cG_05W4={A<%+Z60+e96#6ACtue7-2tN#`{ozFICZ>U^nS?G8X~(P5V5p)ymtwb^IX=F ze2NFV+_ORsEIuA)(?5=e6j?J|+ss(a_vD3EvUp?*9Ime8J|GoEOq6=n5&G`S{%` z4>6v{`sGL4!ahtT@^q0(y&`P}{f3Xo-j=;E=n(Ii1gwJSC;`61WejoE56DO}Hx_%4 zs}ej;N;-!RSmQ@zeC!Eb62@PcStD?s4g`m{pEw~uBVKFA)G|DGt!XZ((&ob?oW^M; zZ`p>w-CUH77TPjpa7F;?+8+<;Z7qzX{asQ{`@OW|a=5d&xL=Z*tJrqGyjOy--UE5|Lk~ac z9J3}s#0wBChN1(6s{HgI?<>zvXwo!mE!3QTn|^l#zs=eZ)->)}S0h{j-W z!fB}vI=s3-r&uI(f!|c+RUq65;Lui>boC$GImlC&Necsmh*zX1(wSRFzT02sb3hFlnsSIglt2 zQ6xnDGbba8oG6M$t8+>oG$=6w8}0{I20ea)?eGIjK{KC#0e1c_UMO++KO>et5X^z) z@CVa^PX1!W{J}D`J)vNLQy?k;>22ZdC62}UfmyII{^0AN!%*zLKXF3m1*XFG2ZHIa z-@L$d5Mo&X00A)KxD)oz0&UQZE35(vtV}XT3c`k>zz7mL00@it31q`gqrf60Eo2}p zNdP#LY~^4cZi+1o0Gk4}uonSf6<`ilDG)3LS`Wwi27+Zl5Dc~?5De$|LYf?~5(NO* zl7a#B|LjM6{%6bWC)lGvFfZqS7pniPs38YoZv}zxKoebo|69M10WSX7FDNiGw$~Q; z|8HRIjI9m=E0Gvdfv`V=z%nEu#22ApunOqj7Soe+U`5ejB~Wr8)*TI&C20!;VwHV?EZAl=n2y{v3QRoWzW}}#1LObz delta 117110 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 dn&R>3F>rEFMiY1lh@25+Wv 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

@{3|n$ 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 A5dZ)H -- Gitee From b7c8614146bcf6261c6c227dc02c6f159c1d4afa Mon Sep 17 00:00:00 2001 From: qyt <486179@qq.com> Date: Fri, 21 Jan 2022 09:14:56 +0800 Subject: [PATCH 34/34] added:lb storage dir --- XEngine_Release/XEngine_File2/.gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 XEngine_Release/XEngine_File2/.gitignore diff --git a/XEngine_Release/XEngine_File2/.gitignore b/XEngine_Release/XEngine_File2/.gitignore new file mode 100644 index 0000000..e69de29 -- Gitee