Blame src/examples/chunked_example.c

Packit 875988
/*
Packit 875988
     This file is part of libmicrohttpd
Packit 875988
     Copyright (C) 2015 Christian Grothoff (and other contributing authors)
Packit 875988
Packit 875988
     This library is free software; you can redistribute it and/or
Packit 875988
     modify it under the terms of the GNU Lesser General Public
Packit 875988
     License as published by the Free Software Foundation; either
Packit 875988
     version 2.1 of the License, or (at your option) any later version.
Packit 875988
Packit 875988
     This library is distributed in the hope that it will be useful,
Packit 875988
     but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 875988
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 875988
     Lesser General Public License for more details.
Packit 875988
Packit 875988
     You should have received a copy of the GNU Lesser General Public
Packit 875988
     License along with this library; if not, write to the Free Software
Packit 875988
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 875988
*/
Packit 875988
/**
Packit 875988
 * @file chunked_example.c
Packit 875988
 * @brief example for generating chunked encoding with libmicrohttpd
Packit 875988
 * @author Christian Grothoff
Packit 875988
 * @author Karlson2k (Evgeny Grin)
Packit 875988
 */
Packit 875988
Packit 875988
#include "platform.h"
Packit 875988
#include <microhttpd.h>
Packit 875988
Packit 875988
struct ResponseContentCallbackParam
Packit 875988
{
Packit 875988
  const char *response_data;
Packit 875988
  size_t response_size;
Packit 875988
};
Packit 875988
Packit 875988
Packit 875988
static ssize_t
Packit 875988
callback (void *cls,
Packit 875988
          uint64_t pos,
Packit 875988
          char *buf,
Packit 875988
          size_t buf_size)
Packit 875988
{
Packit 875988
  size_t size_to_copy;
Packit 875988
  struct ResponseContentCallbackParam * const param =
Packit 875988
      (struct ResponseContentCallbackParam *)cls;
Packit 875988
Packit 875988
  /* Note: 'pos' will never exceed size of transmitted data. */
Packit 875988
  /* You can use 'pos == param->response_size' in next check. */
Packit 875988
  if (pos >= param->response_size)
Packit 875988
    { /* Whole response was sent. Signal end of response. */
Packit 875988
      return MHD_CONTENT_READER_END_OF_STREAM;
Packit 875988
    }
Packit 875988
Packit 875988
  /* Pseudo code.        *
Packit 875988
  if (data_not_ready)
Packit 875988
    {
Packit 875988
      // Callback will be called again on next loop.
Packit 875988
      // Consider suspending connection until data will be ready.
Packit 875988
      return 0;
Packit 875988
    }
Packit 875988
   * End of pseudo code. */
Packit 875988
Packit 875988
  if (buf_size < (param->response_size - pos))
Packit 875988
    size_to_copy = buf_size;
Packit 875988
  else
Packit 875988
    size_to_copy = param->response_size - pos;
Packit 875988
Packit 875988
  memcpy (buf, param->response_data + pos, size_to_copy);
Packit 875988
Packit 875988
  /* Pseudo code.        *
Packit 875988
  if (error_preparing_response)
Packit 875988
    {
Packit 875988
      // Close connection with error.
Packit 875988
      return MHD_CONTENT_READER_END_WITH_ERROR;
Packit 875988
    }
Packit 875988
   * End of pseudo code. */
Packit 875988
Packit 875988
  /* Return amount of data copied to buffer. */
Packit 875988
  return size_to_copy;
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
static void
Packit 875988
free_callback_param (void *cls)
Packit 875988
{
Packit 875988
  free(cls);
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
static const char simple_response_text[] = "<html><head><title>Simple response</title></head>"
Packit 875988
                                           "<body>Simple response text</body></html>";
Packit 875988
Packit 875988
Packit 875988
static int
Packit 875988
ahc_echo (void *cls,
Packit 875988
          struct MHD_Connection *connection,
Packit 875988
          const char *url,
Packit 875988
          const char *method,
Packit 875988
          const char *version,
Packit 875988
          const char *upload_data,
Packit 875988
          size_t *upload_data_size,
Packit 875988
          void **ptr)
Packit 875988
{
Packit 875988
  static int aptr;
Packit 875988
  struct ResponseContentCallbackParam *callback_param;
Packit 875988
  struct MHD_Response *response;
Packit 875988
  int ret;
Packit 875988
  (void)cls;               /* Unused. Silent compiler warning. */
Packit 875988
  (void)url;               /* Unused. Silent compiler warning. */
Packit 875988
  (void)version;           /* Unused. Silent compiler warning. */
Packit 875988
  (void)upload_data;       /* Unused. Silent compiler warning. */
Packit 875988
  (void)upload_data_size;  /* Unused. Silent compiler warning. */
Packit 875988
Packit 875988
  if (0 != strcmp (method, "GET"))
Packit 875988
    return MHD_NO;              /* unexpected method */
Packit 875988
  if (&aptr != *ptr)
Packit 875988
    {
Packit 875988
      /* do never respond on first call */
Packit 875988
      *ptr = &apt;;
Packit 875988
      return MHD_YES;
Packit 875988
    }
Packit 875988
Packit 875988
  callback_param = malloc (sizeof(struct ResponseContentCallbackParam));
Packit 875988
  if (NULL == callback_param)
Packit 875988
    return MHD_NO; /* Not enough memory. */
Packit 875988
Packit 875988
  callback_param->response_data = simple_response_text;
Packit 875988
  callback_param->response_size = (sizeof(simple_response_text)/sizeof(char)) - 1;
Packit 875988
Packit 875988
  *ptr = NULL;                  /* reset when done */
Packit 875988
  response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
Packit 875988
                                                1024,
Packit 875988
                                                &callback,
Packit 875988
                                                callback_param,
Packit 875988
                                                &free_callback_param);
Packit 875988
  if (NULL == response)
Packit 875988
  {
Packit 875988
    free (callback_param);
Packit 875988
    return MHD_NO;
Packit 875988
  }
Packit 875988
  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
Packit 875988
  MHD_destroy_response (response);
Packit 875988
  return ret;
Packit 875988
}
Packit 875988
Packit 875988
Packit 875988
int
Packit 875988
main (int argc, char *const *argv)
Packit 875988
{
Packit 875988
  struct MHD_Daemon *d;
Packit 875988
  int port;
Packit 875988
Packit 875988
  if (argc != 2)
Packit 875988
    {
Packit 875988
      printf ("%s PORT\n", argv[0]);
Packit 875988
      return 1;
Packit 875988
    }
Packit 875988
  port = atoi (argv[1]);
Packit 875988
  if ( (1 > port) ||
Packit 875988
       (port > UINT16_MAX) )
Packit 875988
    {
Packit 875988
      fprintf (stderr,
Packit 875988
               "Port must be a number between 1 and 65535\n");
Packit 875988
      return 1;
Packit 875988
    }
Packit 875988
  d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
Packit 875988
                        MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
Packit 875988
                        /* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
Packit 875988
			/* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
Packit 875988
			/* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
Packit 875988
                        (uint16_t) port,
Packit 875988
                        NULL, NULL,
Packit 875988
                        &ahc_echo, NULL,
Packit 875988
			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
Packit 875988
			MHD_OPTION_END);
Packit 875988
  if (NULL == d)
Packit 875988
    return 1;
Packit 875988
  (void) getc (stdin);
Packit 875988
  MHD_stop_daemon (d);
Packit 875988
  return 0;
Packit 875988
}