[√]cocos2dx lua_xml_http_request配合腾讯云上传经过zlib压缩的数据遇到的问题

lua 复制代码
if xhr.readyState ~= 4 then
if xhr.status ~= 200 then
c++ 复制代码
// Ready States (http://www.w3.org/TR/XMLHttpRequest/#interface-xmlhttprequest)
static const unsigned short UNSENT = 0;
static const unsigned short OPENED = 1;
static const unsigned short HEADERS_RECEIVED = 2;
static const unsigned short LOADING = 3;
static const unsigned short DONE = 4;

问题现象

原数据为:

json 复制代码
{"age":100}

经过ffi zlib压缩后数据为

1F 8B 08 00 00 00 00 00 00 0B AB 56 4A 4C 4F 55 B2 32 34 30 A8 05 00 8D AD 6F 89 0B 00 00 00

压缩的数据长度为31,但是从cdn上下载的数据长度为10 发现数据发生了丢失

追查c++部分上传的数据

注意Header的Content-Length

c++ 复制代码
static int lua_cocos2dx_XMLHttpRequest_send(lua_State* L)
{
if ( 1 == argc )
    {
#if COCOS2D_DEBUG >= 1
        if (!tolua_isstring(L, 2, 0, &tolua_err))
            goto tolua_lerror;
#endif
        //data = tolua_tostring(L, 2, "");
        data = (const char*) lua_tolstring(L, 2, &size);
    }
    
    if (size > 0 &&
        (self->getMethod().compare("post") == 0 || self->getMethod().compare("POST") == 0
         || self->getMethod().compare("put") == 0 || self->getMethod().compare("PUT") == 0 )&&
        nullptr != self->getHttpRequest())
    {
        self->getHttpRequest()->setRequestData(data,size);
    }

}
std::vector<char>           _requestData;    /// used for POST
void setRequestData(const char* buffer, size_t len)
{
    _requestData.assign(buffer, buffer + len);
}

c++接收到的数据正常,并且长度也是31

发现header的content-length出现了问题,这个长度应该是加密后的长度,我没有更新导致的,11是json原数据的长度。

HTTP下载和CDN文件内容不一致

HTTP下载后的数据长度是17,发现直接从CDN下载的文件内容和通过HTTP下载的内容不一样

  • HTTP下载的数据
go 复制代码
[LUA-print] deCompressDataLen: 17
[LUA-print] deCompressData:    31139800000011171
[LUA-print] deCompressBin:     33 31 31 33 39 38 30 30 30 30 30 30 31 31 31 37 31 
[LUA-print] INFLATE: data error 这个是解压的日志,提示解压数据有问题
[LUA-print] deCompress failed
[LUA-print] download failed
  • CDN下载的文件

怀疑是Content-Type导致的,设置为application/octet-stream,依旧同样的报错,MDN对这个类型有解释:

  • text/plain 表示文本文件的默认值。一个文本文件应当是人类可读的,并且不包含二进制数据。
  • application/octet-stream 表示所有其他情况的默认值。一种未知的文件类型应当使用此类型。浏览器在处理这些文件时会特别小心,试图防止、避免用户的危险行为。

怀疑是申请签名的长度问题,申请的签名长度必须是压缩后的数据长度,但是依旧同样的报错。

看来还是得从报错下手。

上传响应报错

调整Content-LengthContent-Type后,重新发送,响应出错:

当设置:

css 复制代码
xhr:setRequestHeader("Content-Type", "application/octet-stream")

报错如下:

vbscript 复制代码
Curl curl_easy_getinfo failed: No error
Response failed, error buffer: 
come in handler, handler is 21

感觉应该是腾讯云对这个类型不支持。

对应的代码:

c++ 复制代码
if (!response->isSucceed())
{
    // 这里出错了
    CCLOG("Response failed, error buffer: %s", response->getErrorBuffer());
    if(statusCode == 0)
    {
        _errorFlag = true;
        _status    = 0;
        _statusText.clear();
    }
    // TODO: call back lua function
    int handler = cocos2d::ScriptHandlerMgr::getInstance()->getObjectHandler((void*)this, cocos2d::ScriptHandlerMgr::HandlerType::XMLHTTPREQUEST_READY_STATE_CHANGE );

    if (0 != handler)
    {
        // 提示handler是20
        CCLOG("come in handler, handler is %d", handler);
        cocos2d::CommonScriptData data(handler,"");
        cocos2d::ScriptEvent event(cocos2d::ScriptEventType::kCommonEvent,(void*)&data);
        cocos2d::ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
    }
    return;
}
/// @param responseCode Null not allowed
bool perform(long *responseCode)
{

    if (CURLE_OK != curl_easy_perform(_curl))
        return false;
    CURLcode code = curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, responseCode);
    if (code != CURLE_OK || !(*responseCode >= 200 && *responseCode < 300)) {
        // 报错:Curl curl_easy_getinfo failed: No error
        CCLOGERROR("Curl curl_easy_getinfo failed: %s", curl_easy_strerror(code));
        return false;
    }
    // Get some mor data.

    return true;
}

当设置为text/plan时,上传成功了,但是下载的内容不一致

csharp 复制代码
[LUA-print] originalData:    {"age":100}
[LUA-print] compressBin:     1F 8B 08 00 00 00 00 00 00 0B AB 56 4A 4C 4F 55 B2 32 34 30 A8 05 00 8D AD 6F 89 0B 00 00 00 
[LUA-print] compressDataLen: 31
[LUA-print] upload succeed: 


[LUA-print] deCompressDataLen: 58
[LUA-print] deCompressData:    3113980000001117186747679851785052481685014117311113711000
[LUA-print] deCompressBin:     33 31 31 33 39 38 30 30 30 30 30 30 31 31 31 37 31 38 36 37 34 37 36 37 39 38 35 31 37 38 35 30 35 32 34 38 31 36 38 35 30 31 34 31 31 37 33 31 31 31 31 33 37 31 31 30 30 30 
[LUA-print] INFLATE: data error

直接CDN下载的文件内容为:

定位到问题了,是下载的数据是个table,table的长度是和源数据长度一致的

lua 复制代码
if (type(data) == "table") then
    dump(data)
    data = table.concat(data, '') -- 这里将二进制流数据转为zlib解压数据出了问题
end

将table里面的ASCII码转为char,再进行解压,至此就完全正常了

lua 复制代码
local tbl = {65, 66, 67}
local str = ""
for i = 1, #tbl do
  str = str .. string.char(tbl[i])
end
print(str)
相关推荐
胡萝卜术3 小时前
从API调用到手写LRU:力扣146「LRU缓存」的哈希表+双向链表终极进化之路
前端·javascript·面试
科技道人3 小时前
记录 默认置灰/禁用 app ‘Search Engine Selector‘ 的disable按钮
开发语言·前端·javascript
天疆说4 小时前
Zotero Connector 在 Edge 里找不到桌面 Zotero(Linux / Zotero 9.0.6 / Edge 150)
linux·前端·edge
李伟_Li慢慢5 小时前
02-从硬件说起WebGL
前端·three.js
kyriewen6 小时前
看了微软几万人用AI编程的数据——效率涨24%的代价没人提
前端·ai编程·claude
2601_963771376 小时前
How to Scale Your WordPress Store Traffic in 2026
前端·php·plugin
亿元程序员6 小时前
老板说我的3D箭头游戏用来做试玩太普通了,没人想玩,让我变点花样...
前端
李伟_Li慢慢7 小时前
01-threejs架构原理-课程简介
前端·three.js
_瑞8 小时前
深入理解 iOS 渲染原理
前端·ios
IT_陈寒8 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端