Чтение сжатой полезной нагрузки сообщения rabbitmq с помощью pika

в отчаянии после двух дней гугления. Я получаю сообщение с pika, пришедшее от rabbitmq. Я знаю, что это base64, а content_encoding — gzip. У меня получилось закодировать тело байтов в utf-8. Теперь мне все равно нужно его как-то распаковать. Вот код на данный момент:

    1 def callback(channel, method, properties, body):
    2    if properties.content_encoding == 'gzip':
    3    
    4        decoded_body  = base64.b64encode(bytes(str(body), 'utf-8'))
    5        #eliminating the leading 'b
    6        decoded_body = decoded_body.decode()
    7
    8        #this snippet is just copied from another solution
    9        buf = io.StringIO(decoded_body)
    10       f = gzip.GzipFile(fileobj=buf)
    11       decompressed_body = f.read()
    12       print(decompressed_body)

В строке 11 появляется следующее сообщение об ошибке.

 return self._buffer[read:] + \
 TypeError: can't concat str to bytes

Очевидно, что в файле gzip есть \, который мне нужно преобразовать в b\. Но я не знаю как. Я вообще на правильном пути или можно решить проще?

Большое спасибо за твою помощь!

Here is the payload of the message when opening it in rabbitmq: AFN3oPUfiwgAAAAAAAQAhU89T8MwEP0ryGJrHJ3t2mo8AqqK+BhIqGC8JKc0UuKUxBmqqv+di4pYGFhOenfv495ZvNA0YUOv2JPw4n77ke4Ix1gSRpGIPY1T OwS+qFQzLtqe8oj9kTcatJJgpDaFWnvrPOg0g40Ca1agPADz30P7NdPjA9OzUpFzTktnMyfXWNYSyVmZmUpXCg2ylhX5MI/V8srTcPgc5tCkGzAgTZrnMn+W AFYttALHhqLwYe66RLwRp0xxybkuflrdDfVJ+LO4jafjn3rJDUO24rnDUHf/h/5Kt+MSGCo2FwD+2vZy+QYahuynTgEAAA==

Вот что я получаю при печати тела без кодировки: b\x00Sw\xa0\xf5\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\x85O=O\xc30\x10\ xfd+\xc8bk\x1c\x9d\xed\xdaj‹\x02\xaa\x8a\xf8\x18H\xa8\xbc$\xa74R\xe2\x94\xc4\x19\xaa\xaa\xff\x9d\x8b\x8aX\x18XNzw\xef\xe3\xdeY\xbc\xd04aC\xaf\xd8\x93\xf0\xe2~\xfb\x91\xee\x08\xc7X\x12F\x91\x88=\x8dS;\x04\xbe\xa8T3.\xda\x9e\xf2\x88\xfd\x917\x1a\xb4\x92\xa46\x85Z{\xeb‹\xe84\x83\x8d\x02kV\xa0‹\x00\xf3\xdfC\ xfb5\xd3\xe3\x03\xd3\xb3R\x91sNKg3'\xd7X\xd6\x12\xc9Y\x99\x99JW\n\r\xb2\x96\x15\xf90\x8f\xd5\xf2\xca\xd3p\xf8 \x1c\xe6\xd0\xa4\x1b0 M\x9a\xe72\x7f\x96\x00V-\xb4\x02\xc7\x86\xa2\xf0a\xee\xbaD\xbc\x11\xa7Lq\xc9\xb9.~ Z\xdd\r\xf5I\xf8\xb3\xb8\x8d\xa7\xe3\x9fz\xc9\rC\xb6\xe2\xb9\xc3Pw\xff\x87\xfeJ\xb7\xe3\x12\x18*6\ x17\x00\xfe\xda\xf6r\xf9\x06\x1a\x86\xec\xa7N\x01\x00\x00


person m1ch4    schedule 26.03.2021    source источник


Ответы (2)


В вашем сообщении перед потоком gzip есть пять байтов. Вам нужно начать декодирование gzip с 1f 8b.

person Mark Adler    schedule 26.03.2021
comment
привет Марк, спасибо за вашу рекомендацию. Я попробую это и вернусь к вам. Как узнать, где начинается поток gzip? - person m1ch4; 27.03.2021
comment
Потоки gzip всегда начинаются с 1f 8b. - person Mark Adler; 27.03.2021
comment
Дорогой Марк, теперь я смог начать распаковку, но это привело меня к ошибке EOF: поднять EOFError (сжатый файл закончился до того, как код был: gzip.decompress (тело [5: -1]) Это потому, что я вырезал байты в начало? - person m1ch4; 27.03.2021
comment
Нет. -1 отбрасывает последний байт. Вы хотите body[5:]. - person Mark Adler; 28.03.2021
comment
дорогой Марк, большое спасибо. Теперь это работает. После распаковки сообщения я также могу прочитать полезную нагрузку в виде открытого текста без декодирования base64. - person m1ch4; 28.03.2021

Здесь происходит много ненужного кодирования и декодирования.

Это работает?

buf = io.BytesIO(body)
f = gzip.GzipFile(fileobj=buf)
decompressed_body = f.read()
print(decompressed_body)
person Durtal    schedule 26.03.2021
comment
К сожалению нет. при чтении f.read() он говорит: gzip.BadGzipFile: не сжатый файл (b'\x00S') - person m1ch4; 26.03.2021
comment
@ m1ch4 Опубликуйте сообщение в виде текста в своем вопросе (а не в виде изображения). - person Durtal; 26.03.2021
comment
@ m1ch4 Я подозреваю, что сообщение повреждено. Если вы записываете двоичный файл в файл, это все равно не сжатый файл. Но я могу что-то упустить во всех этих кодировках. - person Durtal; 26.03.2021
comment
Я не могу прочитать ни одно из сжатых сообщений, хранящихся на rabbitmq. Я не ожидаю, что все будут испорчены. По крайней мере, я на это не надеюсь :) Может быть, есть другой способ получить тело открытого текста без всех этих кодировок, которых я не знаю. - person m1ch4; 26.03.2021