コード例 #1
0
/**
 * Entry point to demo.  Note: this HTTP server will make all
 * files in the current directory and its subdirectories available
 * to anyone.  Press ENTER to stop the server once it has started.
 *
 * @param argc number of arguments in argv
 * @param argv first and only argument should be the port number
 * @return 0 on success
 */
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;
    }
#ifndef MINGW
  ignore_sigpipe ();
#endif
  magic = magic_open (MAGIC_MIME_TYPE);
  (void) magic_load (magic, NULL);

  (void) pthread_mutex_init (&mutex, NULL);
  file_not_found_response = MHD_create_response_from_buffer (strlen (FILE_NOT_FOUND_PAGE),
							     (void *) FILE_NOT_FOUND_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (file_not_found_response);
  request_refused_response = MHD_create_response_from_buffer (strlen (REQUEST_REFUSED_PAGE),
							     (void *) REQUEST_REFUSED_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (request_refused_response);
  internal_error_response = MHD_create_response_from_buffer (strlen (INTERNAL_ERROR_PAGE),
							     (void *) INTERNAL_ERROR_PAGE,
							     MHD_RESPMEM_PERSISTENT);
  mark_as_html (internal_error_response);
  update_directory ();
  d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port,
                        NULL, NULL,
			&generate_page, NULL,
			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (256 * 1024),
#if PRODUCTION
			MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) (64),
#endif
			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) (120 /* seconds */),
			MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
			MHD_OPTION_NOTIFY_COMPLETED, &response_completed_callback, NULL,
			MHD_OPTION_END);
  if (NULL == d)
    return 1;
  fprintf (stderr, "HTTP server running. Press ENTER to stop the server\n");
  (void) getc (stdin);
  MHD_stop_daemon (d);
  MHD_destroy_response (file_not_found_response);
  MHD_destroy_response (request_refused_response);
  MHD_destroy_response (internal_error_response);
  update_cached_response (NULL);
  (void) pthread_mutex_destroy (&mutex);
  magic_close (magic);
  return 0;
}
コード例 #2
0
ファイル: demo.c プロジェクト: andreyuzunov/libmicrohttpd
/**
 * Re-scan our local directory and re-build the index.
 */
static void
update_directory ()
{
  static size_t initial_allocation = 32 * 1024; /* initial size for response buffer */
  struct MHD_Response *response;
  struct ResponseDataContext rdc;
  unsigned int language_idx;
  unsigned int category_idx;
  const struct Language *language;
  const char *category;
  char dir_name[128];
  struct stat sbuf;

  rdc.buf_len = initial_allocation;
  if (NULL == (rdc.buf = malloc (rdc.buf_len)))
    {
      update_cached_response (NULL);
      return;
    }
  rdc.off = snprintf (rdc.buf, rdc.buf_len,
		      "%s",
		      INDEX_PAGE_HEADER);
  for (language_idx = 0; NULL != languages[language_idx].dirname; language_idx++)
    {
      language = &languages[language_idx];

      if (0 != stat (language->dirname, &sbuf))
	continue; /* empty */
      /* we ensured always +1k room, filenames are ~256 bytes,
	 so there is always still enough space for the header
	 without need for an additional reallocation check. */
      rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
			   "<h2>%s</h2>\n",
			   language->longname);
      for (category_idx = 0; NULL != categories[category_idx]; category_idx++)
	{
	  category = categories[category_idx];
	  snprintf (dir_name, sizeof (dir_name),
		    "%s/%s",
		    language->dirname,
		    category);
	  if (0 != stat (dir_name, &sbuf))
	    continue; /* empty */

	  /* we ensured always +1k room, filenames are ~256 bytes,
	     so there is always still enough space for the header
	     without need for an additional reallocation check. */
	  rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
			       "<h3>%s</h3>\n",
			       category);

	  if (MHD_NO == list_directory (&rdc, dir_name))
	    {
	      free (rdc.buf);
	      update_cached_response (NULL);
	      return;
	    }
	}
    }
  /* we ensured always +1k room, filenames are ~256 bytes,
     so there is always still enough space for the footer
     without need for a final reallocation check. */
  rdc.off += snprintf (&rdc.buf[rdc.off], rdc.buf_len - rdc.off,
		       "%s",
		       INDEX_PAGE_FOOTER);
  initial_allocation = rdc.buf_len; /* remember for next time */
  response = MHD_create_response_from_buffer (rdc.off,
					      rdc.buf,
					      MHD_RESPMEM_MUST_FREE);
  mark_as_html (response);
#if FORCE_CLOSE
  (void) MHD_add_response_header (response,
				  MHD_HTTP_HEADER_CONNECTION,
				  "close");
#endif
  update_cached_response (response);
}