--[[ 用于执行HttpRequest的模块 使用说明: Step1:接入HttpReq模块 local HttpReq = require('Http/HttpReq') Step2:创建Http对象,根据持有的句柄,添加协议头Header与字段Field local handle = HttpReq.Create(url, methodType, callback) HttpReq.AddHeader(handle, k1, v1) ··· HttpReq.SetField(handle, k1, v1) HttpReq.SetField(handle, k2, v2) ··· Step3:根据句柄发送Http协议,可以选择添加一组预先设置好的公共Fields;以及是否开启缓存,开启缓存后未成功的请求会被保存,并尝试再次发送 HttpReq.Send(handle, baseFieldsID, needCache) 可以创建可供重复利用的共用字段组(非必须) local baseFieldID = HttpReq.AskForBaseFields() HttpReq.SetBaseField(baseFieldID, k1, v1) HttpReq.SetBaseField(baseFieldID, k2, v2) ]] -- local HttpReq = { HTTPMethods = { Get = 0, Head = 1, Post = 2, Put = 3, Delete = 4, Patch = 5, Merge = 6, Options = 7, Connect = 8 }, HTTPRequestState = { Initial = 0, Queued = 1, Processing = 2, Finished = 3, Error = 4, Aborted = 5, ConnectionTimedOut = 6, TimedOut = 7, } } local reqFieldsDict = {} local reqHeadersDict = {} local cacheHandleDict = {} local baseFieldIDDict = {} local downloadingCallbackDict = {} local InitHttpEnvironment = CSExt.InitHttpEnvironment local CreateHttpRequestBaseFields = CSExt.CreateHttpRequestBaseFields local DisposeHttpRequestBaseFields = CSExt.DisposeHttpRequestBaseFields local SetHttpRequestBaseField = CSExt.SetHttpRequestBaseField local CreateHttpRequest = CSExt.CreateHttpRequest local SendHttpRequest = CSExt.SendHttpRequest local AbortHttpRequest = CSExt.AbortHttpRequest local UntrackHttpRequest = CSExt.UntrackHttpRequest local SetHttpDownloadCallback = CSExt.SetHttpDownloadCallback local StartHttpDownload = CSExt.StartHttpDownload local AbortHttpDownload = CSExt.AbortHttpDownload local CSAbortAllHttpDownload = CSExt.AbortAllHttpDownload HttpReq.DefaultToBase64PlanX = CSExt.DefaultToBase64PlanX HttpReq.Base64PlanXToUTF8 = CSExt.Base64PlanXToUTF8 HttpReq.DefaultToBase64URL = CSExt.DefaultToBase64URL HttpReq.DefaultMD5HashToBase64PlanX = CSExt.DefaultMD5HashToBase64PlanX local InitHttpEnvironmentError = function(msg) logging.error(LTAG.ERROR, "InitHttpEnvironmentError执行失败, 删除httpcache", msg) LuaExt.FileDelete("httpcache"); end xpcall(InitHttpEnvironment, InitHttpEnvironmentError, 3) function HttpReq.AskForBaseFields() local baseFieldID = CreateHttpRequestBaseFields() baseFieldIDDict[baseFieldID] = true return baseFieldID end function HttpReq.DisposeBaseFields(id) DisposeHttpRequestBaseFields(id) end function HttpReq.SetBaseField(id, key, value) SetHttpRequestBaseField(id, key, value) end function HttpReq.SetRawDataByStr(id, rawDataStr, useUtf8) if CSExt.SetHttpRequestRawDataByStr then CSExt.SetHttpRequestRawDataByStr(id, rawDataStr, useUtf8) end end function HttpReq.AddBinaryDataByFilePath(id, fieldName, filePath) if CSExt.AddBinaryDataByFilePath then CSExt.AddBinaryDataByFilePath(id, fieldName, filePath) end end local EmptyFunction = function() end function HttpReq.Create(url, methodType, callback) local handle = CreateHttpRequest(url, methodType, HttpReq.OnRequestFinishedCallback) reqFieldsDict[handle] = {} reqHeadersDict[handle] = {} cacheHandleDict[handle] = callback or EmptyFunction return handle end function HttpReq.OnRequestFinishedCallback(handle, ...) local callback = cacheHandleDict[handle] if callback then callback(handle, ...) end cacheHandleDict[handle] = nil end function HttpReq.AddHeader(handle, key, value) local headers = reqHeadersDict[handle] if headers then local list = headers[key] if not list then list = {} headers[key] = list end table.insert(list, value) end end function HttpReq.RemoveHeader(handle, key, value) local headers = reqHeadersDict[handle] if headers then local list = headers[key] if list then table.removebyvalue(list, value) if #list == 0 then headers[key] = nil end end end end function HttpReq.SetField(handle, key, value) local fields = reqFieldsDict[handle] if fields then fields[key] = value end end function HttpReq.Untrack(handle) UntrackHttpRequest(handle) reqHeadersDict[handle] = nil reqFieldsDict[handle] = nil cacheHandleDict[handle] = nil end --region header iter local headersIterTable local headersIterKey local headerIndex = 0 local headerValues local nextHeader = function() headersIterKey, headerValues = next(headersIterTable, headersIterKey) headerIndex = 0 if headersIterKey and headerValues then if headerIndex < #headerValues then headerIndex = headerIndex + 1 return headersIterKey, headerValues[headerIndex] end end end local iterCurrentHeader = function() headerIndex = headerIndex + 1 return headersIterKey, headerValues[headerIndex] end local headersIterFunc = function() if headersIterKey and headerValues then if headerIndex < #headerValues then return iterCurrentHeader() else return nextHeader() end else return nextHeader() end end --endregion header iter --region field iter local fieldsIterTable local fieldsIterKey local fieldsIterFunc = function() local value fieldsIterKey, value = next(fieldsIterTable, fieldsIterKey) return fieldsIterKey, value end --endregion field iter ---@param handle int ---@param baseFieldID int_可为nil ---@param needCache bool_可为nil function HttpReq.Send(handle, baseFieldID, needCache, useSrcFieldValue) local headers = reqHeadersDict[handle] local fields = reqFieldsDict[handle] reqHeadersDict[handle] = nil reqFieldsDict[handle] = nil if headers and fields then --for headers iter headersIterKey = nil headersIterTable = headers headerIndex = 0 headerValues = nil --for fields iter fieldsIterKey = nil fieldsIterTable = fields if GameAppInfo.IsPCPackage() then SendHttpRequest(handle, headersIterFunc, baseFieldID, fieldsIterFunc, needCache or false, useSrcFieldValue or false) elseif GameAppInfo.IsChinesePackage() and GameAppInfo.IsVersionGreaterThan16000() then SendHttpRequest(handle, headersIterFunc, baseFieldID, fieldsIterFunc, needCache or false, useSrcFieldValue or false) elseif GameAppInfo.IsOverseaPackage() and GameAppInfo.IsVersionGreaterThan17000() then SendHttpRequest(handle, headersIterFunc, baseFieldID, fieldsIterFunc, needCache or false, useSrcFieldValue or false) elseif GameAppInfo.IsJapanesePackage() and GameAppInfo.IsVersionGreaterThan16000() then SendHttpRequest(handle, headersIterFunc, baseFieldID, fieldsIterFunc, needCache or false, useSrcFieldValue or false) else SendHttpRequest(handle, headersIterFunc, baseFieldID, fieldsIterFunc, needCache or false) end end end function HttpReq.Abort(handle) AbortHttpRequest(handle) end --下载 --callback(isSuccess, statusCode) function HttpReq.StartHttpDownload(url, path, callback) if GameAppInfo.IsVersionGreaterThan15000() or GameAppInfo.IsChinesePackage() then local handle = StartHttpDownload(url, path, callback) downloadingCallbackDict[handle] = callback return handle end end local function OnHttpDownloadFinish(handle, isSuccess, statusCode) local callback = downloadingCallbackDict[handle] if callback then callback(isSuccess, statusCode) end end function HttpReq.AbortHttpDownload(handle) if GameAppInfo.IsVersionGreaterThan15000() or GameAppInfo.IsChinesePackage() then AbortHttpDownload(handle) downloadingCallbackDict[handle] = nil end end local function AbortAllHttpDownload() if GameAppInfo.IsVersionGreaterThan15000() or GameAppInfo.IsChinesePackage() then CSAbortAllHttpDownload() table.clear(downloadingCallbackDict) SetHttpDownloadCallback(nil) end end --设置下载回调 if GameAppInfo.IsVersionGreaterThan15000() or GameAppInfo.IsChinesePackage() then SetHttpDownloadCallback(OnHttpDownloadFinish) end local function ClearAllHandle() for handle, _ in pairs(cacheHandleDict) do HttpReq.Untrack(handle) end cacheHandleDict = nil for baseFieldID, _ in pairs(baseFieldIDDict) do HttpReq.DisposeBaseFields(baseFieldID) end baseFieldIDDict = nil end function HttpReq.OnShutdown() AbortAllHttpDownload() ClearAllHandle() end return HttpReq