diff options
author | George Hazan <ghazan@miranda.im> | 2019-12-23 17:11:01 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-12-23 17:11:01 +0300 |
commit | e016a7802692a2ccfba34c2505dbd4b14a39d715 (patch) | |
tree | dc9b5f584ed60859e3e8b0a211056e31575d4f46 /protocols/Facebook/src/mqtt.cpp | |
parent | 8d2d77dbdc720b55647e107305162b25067457f4 (diff) |
Facebook: unzip support
Diffstat (limited to 'protocols/Facebook/src/mqtt.cpp')
-rw-r--r-- | protocols/Facebook/src/mqtt.cpp | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/protocols/Facebook/src/mqtt.cpp b/protocols/Facebook/src/mqtt.cpp index 160048318d..72ed222079 100644 --- a/protocols/Facebook/src/mqtt.cpp +++ b/protocols/Facebook/src/mqtt.cpp @@ -50,7 +50,7 @@ static uint8_t encodeType(int type) } } -uint8_t* FacebookProto::doZip(size_t cbData, const void *pData, size_t &cbRes) +uint8_t *FacebookProto::doZip(size_t cbData, const void *pData, size_t &cbRes) { size_t dataSize = cbData + 100; uint8_t *pRes = (uint8_t *)mir_alloc(dataSize); @@ -75,6 +75,31 @@ uint8_t* FacebookProto::doZip(size_t cbData, const void *pData, size_t &cbRes) return pRes; } +uint8_t *FacebookProto::doUnzip(size_t cbData, const void *pData, size_t &cbRes) +{ + size_t dataSize = cbData * 10; + uint8_t *pRes = (uint8_t *)mir_alloc(dataSize); + + z_stream zStreamOut = {}; + inflateInit(&zStreamOut); + zStreamOut.avail_in = (unsigned)cbData; + zStreamOut.next_in = (uint8_t *)pData; + zStreamOut.avail_out = (unsigned)dataSize; + zStreamOut.next_out = (uint8_t *)pRes; + + switch (inflate(&zStreamOut, Z_FINISH)) { + case Z_STREAM_END: debugLogA("Deflate: Z_STREAM_END"); break; + case Z_OK: debugLogA("Deflate: Z_OK"); break; + case Z_BUF_ERROR: debugLogA("Deflate: Z_BUF_ERROR"); break; + case Z_DATA_ERROR: debugLogA("Deflate: Z_DATA_ERROR"); break; + case Z_MEM_ERROR: debugLogA("Deflate: Z_MEM_ERROR"); break; + } + + inflateEnd(&zStreamOut); + cbRes = dataSize - zStreamOut.avail_out; + return pRes; +} + ///////////////////////////////////////////////////////////////////////////////////////// FbThrift& FbThrift::operator<<(uint8_t value) @@ -219,7 +244,7 @@ bool FacebookProto::MqttParse(const MqttMessage &payload) bool FacebookProto::MqttRead(MqttMessage &payload) { uint8_t b; - int res = Netlib_Recv(m_mqttConn, (char *)&b, sizeof(b)); + int res = Netlib_Recv(m_mqttConn, (char *)&b, sizeof(b), MSG_NODUMP); if (res != 1) return false; @@ -227,13 +252,15 @@ bool FacebookProto::MqttRead(MqttMessage &payload) uint32_t m = 1, remainingBytes = 0; do { - if ((res = Netlib_Recv(m_mqttConn, (char *)&b, sizeof(b))) != 1) + if ((res = Netlib_Recv(m_mqttConn, (char *)&b, sizeof(b), MSG_NODUMP)) != 1) return false; remainingBytes += (b & 0x7F) * m; m *= 128; } while ((b & 0x80) != 0); + debugLogA("Received message of type=%d, flags=%x, body length=%d", payload.getType(), payload.getFlags(), remainingBytes); + if (remainingBytes != 0) { while (remainingBytes > 0) { uint8_t buf[1024]; @@ -244,6 +271,19 @@ bool FacebookProto::MqttRead(MqttMessage &payload) payload.writeBuf(buf, res); remainingBytes -= res; } + + // that might be a zipped buffer + if (payload.size() >= 2) { + auto *p = (const uint8_t *)payload.data(); + if ((((p[0] << 8) | p[1]) % 31) == 0 && (p[0] & 0x0F) == 8) { // zip header ok + size_t dataSize; + void *pData = doUnzip(payload.size(), payload.data(), dataSize); + if (pData != nullptr) { + payload.reset(dataSize, pData); + mir_free(pData); + } + } + } } return true; |