/*
     This file is part of libmicrohttpd
     Copyright (C) 2019 Christian Grothoff (and other contributing authors)
     Copyright (C) 2019-2022 Evgeny Grin (Karlson2k)

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
/**
 * @file http_chunked_compression.c
 * @brief example for how to compress a chunked HTTP response
 * @author Silvio Clecio (silvioprog)
 * @author Karlson2k (Evgeny Grin)
 */

#include "platform.h"
#ifndef ZLIB_CONST
/* Correct API with const pointer for input data is required */
#define ZLIB_CONST 1
#endif /* ! ZLIB_CONST */
#include <zlib.h>
#include <microhttpd.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif /* HAVE_LIMITS_H */
#include <stddef.h>
#include <stdint.h>

#ifndef SSIZE_MAX
#ifdef __SSIZE_MAX__
#define SSIZE_MAX __SSIZE_MAX__
#elif defined(PTRDIFF_MAX)
#define SSIZE_MAX PTRDIFF_MAX
#elif defined(INTPTR_MAX)
#define SSIZE_MAX INTPTR_MAX
#else
#define SSIZE_MAX ((ssize_t) (((size_t) -1) >> 1))
#endif
#endif /* ! SSIZE_MAX */

#define CHUNK 16384

struct Holder
{
  FILE *file;
  z_stream stream;
  void *buf;
};

static enum MHD_Result
compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset,
              void **dest, size_t *dest_size,
              void *tmp)
{
  unsigned int have;
  enum MHD_Result ret;
  int flush;
  void *tmp_dest;
  *dest = NULL;
  *dest_size = 0;
  do
  {
    if (src_size > CHUNK)
    {
      strm->avail_in = CHUNK;
      src_size -= CHUNK;
      flush = Z_NO_FLUSH;
    }
    else
    {
      strm->avail_in = (uInt) src_size;
      flush = Z_SYNC_FLUSH;
    }
    *offset += strm->avail_in;
    strm->next_in = (const Bytef *) src;
    do
    {
      strm->avail_out = CHUNK;
      strm->next_out = tmp;
      ret = (Z_OK == deflate (strm, flush)) ? MHD_YES : MHD_NO;
      have = CHUNK - strm->avail_out;
      *dest_size += have;
      tmp_dest = realloc (*dest, *dest_size);
      if (NULL == tmp_dest)
      {
        free (*dest);
        *dest = NULL;
        return MHD_NO;
      }
      *dest = tmp_dest;
      memcpy (((uint8_t *) (*dest)) + ((*dest_size) - have), tmp, have);
    }
    while (0 == strm->avail_out);
  }
  while (flush != Z_SYNC_FLUSH);
  return ret;
}


static ssize_t
read_cb (void *cls, uint64_t pos, char *mem, size_t size)
{
  struct Holder *holder = cls;
  void *src;
  void *buf;
  ssize_t ret;
  size_t offset;
  size_t r_size;

  if (pos > SSIZE_MAX)
    return MHD_CONTENT_READER_END_WITH_ERROR;
  offset = (size_t) pos;
  src = malloc (size);
  if (NULL == src)
    return MHD_CONTENT_READER_END_WITH_ERROR;
  r_size = fread (src, 1, size, holder->file);
  if (0 == r_size)
  {
    ret = (0 != ferror (holder->file)) ?
          MHD_CONTENT_READER_END_WITH_ERROR : MHD_CONTENT_READER_END_OF_STREAM;
    goto done;
  }
  if (MHD_YES != compress_buf (&holder->stream, src, r_size, &offset, &buf,
                               &size, holder->buf))
    ret = MHD_CONTENT_READER_END_WITH_ERROR;
  else
  {
    memcpy (mem, buf, size);
    ret = (ssize_t) size;
  }
  free (buf); /* Buf may be set even on error return. */
done:
  free (src);
  return ret;
}


static void
free_cb (void *cls)
{
  struct Holder *holder = cls;
  fclose (holder->file);
  deflateEnd (&holder->stream);
  free (holder->buf);
  free (holder);
}


static enum MHD_Result
ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const
          char *method, const char *version,
          const char *upload_data, size_t *upload_size, void **req_cls)
{
  struct Holder *holder;
  struct MHD_Response *res;
  enum MHD_Result ret;
  (void) cls;
  (void) url;
  (void) method;
  (void) version;
  (void) upload_data;
  (void) upload_size;
  if (NULL == *req_cls)
  {
    *req_cls = (void *) 1;
    return MHD_YES;
  }
  *req_cls = NULL;
  holder = calloc (1, sizeof (struct Holder));
  if (! holder)
    return MHD_NO;
  holder->file = fopen (__FILE__, "rb");
  if (NULL == holder->file)
    goto file_error;
  if (Z_OK != deflateInit (&holder->stream, Z_BEST_COMPRESSION))
    goto stream_error;
  holder->buf = malloc (CHUNK);
  if (NULL == holder->buf)
    goto buf_error;
  res = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024, &read_cb,
                                           holder, &free_cb);
  if (NULL == res)
    goto error;
  ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_ENCODING,
                                 "deflate");
  if (MHD_YES != ret)
    goto res_error;
  ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_TYPE, "text/x-c");
  if (MHD_YES != ret)
    goto res_error;
  ret = MHD_queue_response (con, MHD_HTTP_OK, res);
res_error:
  MHD_destroy_response (res);
  return ret;
error:
  free (holder->buf);
buf_error:
  deflateEnd (&holder->stream);
stream_error:
  fclose (holder->file);
file_error:
  free (holder);
  return MHD_NO;
}


int
main (int argc, char *const *argv)
{
  struct MHD_Daemon *d;
  unsigned int port;
  if ((argc != 2) ||
      (1 != sscanf (argv[1], "%u", &port)) ||
      (UINT16_MAX < port))
  {
    fprintf (stderr, "%s PORT\n", argv[0]);
    return 1;
  }
  d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
                        (uint16_t) port, NULL, NULL,
                        &ahc_echo, NULL,
                        MHD_OPTION_END);
  if (NULL == d)
    return 1;
  if (0 == port)
    MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT, &port);
  fprintf (stdout,
           "HTTP server running at http://localhost:%u\n\nPress ENTER to stop the server ...\n",
           port);
  (void) getc (stdin);
  MHD_stop_daemon (d);
  return 0;
}
