summaryrefslogtreecommitdiff
path: root/protocols/Facebook/src/mqtt.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-12-23 17:11:01 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-12-23 17:11:01 +0300
commite016a7802692a2ccfba34c2505dbd4b14a39d715 (patch)
treedc9b5f584ed60859e3e8b0a211056e31575d4f46 /protocols/Facebook/src/mqtt.cpp
parent8d2d77dbdc720b55647e107305162b25067457f4 (diff)
Facebook: unzip support
Diffstat (limited to 'protocols/Facebook/src/mqtt.cpp')
-rw-r--r--protocols/Facebook/src/mqtt.cpp46
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;