adding test from Markus (adapted by me to C and MHD-style)

This commit is contained in:
Christian Grothoff
2016-11-04 21:57:17 +01:00
parent d7392e0882
commit 94ff070774
3 changed files with 217 additions and 0 deletions
+1
View File
@@ -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>
+9
View File
@@ -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 = \
+207
View File
@@ -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;
}