diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/IO/http.c | 14 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/decode.c | 90 |
3 files changed, 101 insertions, 5 deletions
diff --git a/src/IO/http.c b/src/IO/http.c index 3c178bf1..d552664d 100644 --- a/src/IO/http.c +++ b/src/IO/http.c @@ -2,7 +2,7 @@ * File: http.c * * Copyright (C) 2000-2007 Jorge Arellano Cid <jcid@dillo.org> - * Copyright (C) 2024 Rodrigo Arias Mallo <rodarima@gmail.com> + * Copyright (C) 2024-2025 Rodrigo Arias Mallo <rodarima@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -425,7 +425,11 @@ static Dstr *Http_make_query_str(DilloWeb *web, bool_t use_proxy, bool_t use_tls "User-Agent: %s\r\n" "Accept: %s\r\n" "%s" /* language */ - "Accept-Encoding: gzip, deflate\r\n" + "Accept-Encoding: gzip, deflate" +#ifdef ENABLE_BROTLI + ", br" +#endif + "\r\n" "%s" /* auth */ "DNT: 1\r\n" "%s" /* proxy auth */ @@ -449,7 +453,11 @@ static Dstr *Http_make_query_str(DilloWeb *web, bool_t use_proxy, bool_t use_tls "User-Agent: %s\r\n" "Accept: %s\r\n" "%s" /* language */ - "Accept-Encoding: gzip, deflate\r\n" + "Accept-Encoding: gzip, deflate" +#ifdef ENABLE_BROTLI + ", br" +#endif + "\r\n" "%s" /* auth */ "DNT: 1\r\n" "%s" /* proxy auth */ diff --git a/src/Makefile.am b/src/Makefile.am index bc3a2b37..b34745a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ dillo_LDADD = \ $(top_builddir)/dw/libDw-core.a \ $(top_builddir)/lout/liblout.a \ @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ \ - @LIBICONV_LIBS@ @LIBPTHREAD_LIBS@ @LIBX11_LIBS@ @LIBSSL_LIBS@ + @LIBICONV_LIBS@ @LIBPTHREAD_LIBS@ @LIBX11_LIBS@ @LIBSSL_LIBS@ @BROTLI_LIBS@ dillo_SOURCES = \ dillo.cc \ diff --git a/src/decode.c b/src/decode.c index 0e95f386..535a5971 100644 --- a/src/decode.c +++ b/src/decode.c @@ -2,6 +2,7 @@ * File: decode.c * * Copyright 2007-2008 Jorge Arellano Cid <jcid@dillo.org> + * Copyright 2025 Rodrigo Arias Mallo <rodarima@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -9,11 +10,17 @@ * (at your option) any later version. */ +#include "config.h" + #include <zlib.h> #include <iconv.h> #include <errno.h> #include <stdlib.h> /* strtol */ +#ifdef ENABLE_BROTLI +#include <brotli/decode.h> +#endif + #include "decode.h" #include "utf8.hh" #include "msg.h" @@ -232,6 +239,82 @@ static Dstr *Decode_deflate(Decode *dc, const char *instr, int inlen) return output; } +#ifdef ENABLE_BROTLI +/** + * Decode brotli compressed data in stream mode. + */ +static Dstr *Decode_brotli_process(Decode *dc, const char *instr, int inlen) +{ + Dstr *output = dStr_new(""); + BrotliDecoderState *st = (BrotliDecoderState *) dc->state; + + const uint8_t *next_in = (const uint8_t *) instr; + size_t avail_in = inlen; + BrotliDecoderResult res; + + _MSG("Decode_brotli_process inlen=%d\n", inlen); + + /* Handle empty case */ + if (avail_in == 0) + return output; + + do { + /* Always reset output buffer */ + uint8_t *next_out = (uint8_t *) dc->buffer; + size_t avail_out = bufsize; + + _MSG("Decode_brotli_process decoding %zd bytes\n", avail_in); + + res = BrotliDecoderDecompressStream(st, + &avail_in, &next_in, &avail_out, &next_out, NULL); + + _MSG("Decode_brotli_process res=%d\n", res); + + if (res == BROTLI_DECODER_RESULT_ERROR) { + MSG_ERR("brotli decompression error\n"); + break; + } + + size_t delta = bufsize - avail_out; + _MSG("Decode_brotli_process delta=%zd\n", delta); + dStr_append_l(output, dc->buffer, delta); + + } while (res == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT); + + _MSG("Decode_brotli_process exitting with res=%d\n", res); + + return output; +} + +static void Decode_brotli_free(Decode *dc) +{ + BrotliDecoderState *st = (BrotliDecoderState *) dc->state; + BrotliDecoderDestroyInstance(st); + + dFree(dc->buffer); +} + +static Decode *Decode_brotli_init(void) +{ + BrotliDecoderState *st = BrotliDecoderCreateInstance(NULL, NULL, NULL); + if (st == NULL) { + MSG_ERR("Cannot create brotli decoder instance\n"); + return NULL; + } + + Decode *dc = dNew0(Decode, 1); + + dc->buffer = dNew(char, bufsize); + dc->state = st; + dc->leftover = NULL; /* not used */ + dc->decode = Decode_brotli_process; + dc->free = Decode_brotli_free; + + return dc; +} +#endif /* ENABLE_BROTLI */ + + /** * Translate to desired character set (UTF-8) */ @@ -322,7 +405,7 @@ static Decode *Decode_content_init_common(void) } /** - * Initialize content decoder. Currently handles 'gzip' and 'deflate'. + * Initialize content decoder. Currently handles 'gzip', 'deflate' and 'br'. */ Decode *a_Decode_content_init(const char *format) { @@ -348,6 +431,11 @@ Decode *a_Decode_content_init(const char *format) inflateInit(zs); dc->decode = Decode_deflate; +#ifdef ENABLE_BROTLI + } else if (!dStrAsciiCasecmp(format, "br")) { + _MSG("brotli data!\n"); + dc = Decode_brotli_init(); +#endif } else { MSG("Content-Encoding '%s' not recognized.\n", format); } |