mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
adding test from Markus (adapted by me to C and MHD-style)
This commit is contained in:
@@ -23,6 +23,7 @@ Matthew Moore
|
||||
Colin Caughie <c.caughie@indigovision.com>
|
||||
David Carvalho <andaris@gmail.com>
|
||||
David Reiss <dreiss@facebook.com>
|
||||
Markus Doppelbauer <doppelbauer@gmx.net>
|
||||
Matt Holiday
|
||||
Michael Cronenworth <mike@cchtml.com>
|
||||
Milan Straka <straka@ufal.mff.cuni.cz>
|
||||
|
||||
@@ -52,6 +52,7 @@ check_PROGRAMS = \
|
||||
if HAVE_POSIX_THREADS
|
||||
check_PROGRAMS += \
|
||||
test_quiesce \
|
||||
test_quiesce_stream \
|
||||
test_concurrent_stop \
|
||||
perf_get_concurrent
|
||||
endif
|
||||
@@ -114,6 +115,14 @@ test_quiesce_LDADD = \
|
||||
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
|
||||
$(PTHREAD_LIBS) @LIBCURL@
|
||||
|
||||
test_quiesce_stream_SOURCES = \
|
||||
test_quiesce_stream.c
|
||||
test_quiesce_stream_CFLAGS = \
|
||||
$(PTHREAD_CFLAGS) $(AM_CFLAGS)
|
||||
test_quiesce_stream_LDADD = \
|
||||
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
|
||||
$(PTHREAD_LIBS) @LIBCURL@
|
||||
|
||||
test_callback_SOURCES = \
|
||||
test_callback.c
|
||||
test_callback_LDADD = \
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2016 Christian Grothoff
|
||||
|
||||
libmicrohttpd is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your
|
||||
option) any later version.
|
||||
|
||||
libmicrohttpd 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
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with libmicrohttpd; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
* @file test_quiesce_stream.c
|
||||
* @brief Testcase for libmicrohttpd quiescing
|
||||
* @author Markus Doppelbauer
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <microhttpd.h>
|
||||
|
||||
|
||||
static volatile unsigned int request_counter;
|
||||
|
||||
|
||||
static void
|
||||
http_PanicCallback (void *cls,
|
||||
const char *file,
|
||||
unsigned int line,
|
||||
const char *reason)
|
||||
{
|
||||
fprintf( stderr,
|
||||
"PANIC: exit process: %s at %s:%u\n",
|
||||
reason,
|
||||
file,
|
||||
line);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
resume_connection (void *arg)
|
||||
{
|
||||
struct MHD_Connection *connection = arg;
|
||||
|
||||
MHD_resume_connection (connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
suspend_connection (struct MHD_Connection *connection)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
|
||||
MHD_suspend_connection (connection);
|
||||
int status = pthread_create (&thread_id,
|
||||
NULL,
|
||||
&resume_connection,
|
||||
connection);
|
||||
if (0 != status)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Could not create thead\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
pthread_detach (thread_id);
|
||||
}
|
||||
|
||||
|
||||
struct ContentReaderUserdata
|
||||
{
|
||||
int bytes_written;
|
||||
struct MHD_Connection *connection;
|
||||
};
|
||||
|
||||
|
||||
static ssize_t
|
||||
http_ContentReaderCallback (void *cls,
|
||||
uint64_t pos,
|
||||
char *buf,
|
||||
size_t max)
|
||||
{
|
||||
static const char alphabet[] = "\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
struct ContentReaderUserdata *userdata = cls;
|
||||
|
||||
if( userdata->bytes_written >= 1024)
|
||||
{
|
||||
fprintf( stderr,
|
||||
"finish: %d\n",
|
||||
request_counter);
|
||||
return MHD_CONTENT_READER_END_OF_STREAM;
|
||||
}
|
||||
userdata->bytes_written++;
|
||||
buf[0] = alphabet[userdata->bytes_written % (sizeof(alphabet) - 1)];
|
||||
suspend_connection (userdata->connection);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
http_AccessHandlerCallback (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
const char *url,
|
||||
const char *method,
|
||||
const char *version,
|
||||
const char *upload_data,
|
||||
size_t *upload_data_size,
|
||||
void **con_cls )
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Never respond on first call */
|
||||
if (NULL == *con_cls)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"start: %d\n",
|
||||
++request_counter);
|
||||
|
||||
struct ContentReaderUserdata *userdata = malloc (sizeof(struct ContentReaderUserdata));
|
||||
|
||||
if (NULL == userdata)
|
||||
return MHD_NO;
|
||||
userdata->bytes_written = 0;
|
||||
userdata->connection = connection;
|
||||
*con_cls = userdata;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
/* Second call: create response */
|
||||
struct MHD_Response *response
|
||||
= MHD_create_response_from_callback (-1,
|
||||
32 * 1024,
|
||||
&http_ContentReaderCallback,
|
||||
*con_cls,
|
||||
NULL);
|
||||
ret = MHD_queue_response (connection,
|
||||
MHD_HTTP_OK,
|
||||
response);
|
||||
MHD_destroy_response (response);
|
||||
|
||||
suspend_connection (connection);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
// Panic callback
|
||||
MHD_set_panic_func (&http_PanicCallback,
|
||||
NULL);
|
||||
|
||||
// Flags
|
||||
unsigned int daemon_flags
|
||||
= MHD_USE_SELECT_INTERNALLY
|
||||
| MHD_USE_EPOLL
|
||||
| MHD_USE_SUSPEND_RESUME
|
||||
| MHD_USE_PIPE_FOR_SHUTDOWN;
|
||||
|
||||
// Create daemon
|
||||
struct MHD_Daemon *daemon = MHD_start_daemon (daemon_flags,
|
||||
8000,
|
||||
NULL,
|
||||
NULL,
|
||||
&http_AccessHandlerCallback,
|
||||
NULL,
|
||||
MHD_OPTION_END);
|
||||
if (NULL == daemon)
|
||||
return EXIT_FAILURE;
|
||||
if (0 != system ("wget --server-response -q -O - 127.0.0.1:8000"))
|
||||
{
|
||||
MHD_stop_daemon (daemon);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// wait for a request
|
||||
while (0 == request_counter)
|
||||
sleep (1);
|
||||
|
||||
fprintf (stderr,
|
||||
"quiesce\n");
|
||||
MHD_quiesce_daemon (daemon);
|
||||
|
||||
/* wait a second */
|
||||
sleep (1);
|
||||
|
||||
fprintf (stderr,
|
||||
"stopping daemon\n");
|
||||
MHD_stop_daemon (daemon);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user