[libsoup] SoupContentDecoder: add support for deflate Content-Encoding
- From: Sergio Villar Senin <svillar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] SoupContentDecoder: add support for deflate Content-Encoding
- Date: Thu, 17 Nov 2011 18:09:55 +0000 (UTC)
commit 6d8ff9731eae9bf57982de273c8a45673996bcb4
Author: Sergio Villar Senin <svillar igalia com>
Date: Thu Oct 13 18:37:24 2011 +0200
SoupContentDecoder: add support for deflate Content-Encoding
Claim that we support both gzip and deflate content encodings. Added support
to handle data compressed with deflate with and without zlib headers.
https://bugzilla.gnome.org/show_bug.cgi?id=661682
libsoup/soup-content-decoder.c | 10 +++++++++-
libsoup/soup-message-io.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletions(-)
---
diff --git a/libsoup/soup-content-decoder.c b/libsoup/soup-content-decoder.c
index 3ab240c..2146612 100644
--- a/libsoup/soup-content-decoder.c
+++ b/libsoup/soup-content-decoder.c
@@ -66,7 +66,7 @@ G_DEFINE_TYPE_WITH_CODE (SoupContentDecoder, soup_content_decoder, G_TYPE_OBJECT
soup_content_decoder_session_feature_init))
/* This is constant for now */
-#define ACCEPT_ENCODING_HEADER "gzip"
+#define ACCEPT_ENCODING_HEADER "gzip, deflate"
static GConverter *
gzip_decoder_creator (void)
@@ -74,6 +74,12 @@ gzip_decoder_creator (void)
return (GConverter *)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
}
+static GConverter *
+zlib_decoder_creator (void)
+{
+ return (GConverter *)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
+}
+
static void
soup_content_decoder_init (SoupContentDecoder *decoder)
{
@@ -87,6 +93,8 @@ soup_content_decoder_init (SoupContentDecoder *decoder)
gzip_decoder_creator);
g_hash_table_insert (decoder->priv->decoders, "x-gzip",
gzip_decoder_creator);
+ g_hash_table_insert (decoder->priv->decoders, "deflate",
+ zlib_decoder_creator);
}
static void
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 4f2e839..b589ef2 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -338,6 +338,7 @@ content_decode_one (SoupBuffer *buf, GConverter *converter, GError **error)
gsize outbuf_length, outbuf_used, outbuf_cur, input_used, input_cur;
char *outbuf;
GConverterResult result;
+ gboolean dummy_zlib_header_used = FALSE;
outbuf_length = MAX (buf->length * 2, 1024);
outbuf = g_malloc (outbuf_length);
@@ -357,6 +358,39 @@ content_decode_one (SoupBuffer *buf, GConverter *converter, GError **error)
g_clear_error (error);
outbuf_length *= 2;
outbuf = g_realloc (outbuf, outbuf_length);
+ } else if (input_cur == 0 &&
+ !dummy_zlib_header_used &&
+ G_IS_ZLIB_DECOMPRESSOR (converter) &&
+ g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) {
+
+ GZlibCompressorFormat format;
+ g_object_get (G_OBJECT (converter), "format", &format, NULL);
+
+ if (format == G_ZLIB_COMPRESSOR_FORMAT_ZLIB) {
+ /* Some servers (especially Apache with mod_deflate)
+ * return RAW compressed data without the zlib headers
+ * when the client claims to support deflate. For
+ * those cases use a dummy header (stolen from
+ * Mozilla's nsHTTPCompressConv.cpp) and try to
+ * continue uncompressing data.
+ */
+ static char dummy_zlib_header[2] = { 0x78, 0x9C };
+
+ g_converter_reset (converter);
+ result = g_converter_convert (converter,
+ dummy_zlib_header, sizeof(dummy_zlib_header),
+ outbuf + outbuf_cur, outbuf_length - outbuf_cur,
+ 0, &input_used, &outbuf_used, NULL);
+ dummy_zlib_header_used = TRUE;
+ if (result == G_CONVERTER_CONVERTED) {
+ g_clear_error (error);
+ continue;
+ }
+ }
+
+ g_free (outbuf);
+ return NULL;
+
} else if (*error) {
/* GZlibDecompressor can't ever return
* G_IO_ERROR_PARTIAL_INPUT unless we pass it
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]