Hello,
Thanks a lot.
For me, 0.9.49 does not work - it never enters the
"AccessHandlerCallback()" handler. I have attached
a small testcase.
Steps to reproduce:
g++ -o testmhd test.cpp -I/tmp/libmicrohttpd-0.9.49/src/include/
-L/tmp/libmicrohttpd-0.9.49/src/microhttpd/.libs/ -lmicrohttpd
LD_LIBRARY_PATH=/tmp/libmicrohttpd-0.9.49/src/microhttpd/.libs/
./testmhd
wget -O /dev/null 127.0.0.1:8080
Best wishes,
Markus
Am Samstag, den 09.04.2016, 16:39 +0200 schrieb Christian Grothoff:
> Dear all,
>
> I'm happy to announce the release of libmicrohttpd 0.9.49.
>
> GNU libmicrohttpd is a small C library that is supposed to make it
> easy
> to run an HTTP server as part of another application. GNU
> libmicrohttpd
> is fully HTTP 1.1 compliant and supports IPv6. Finally, GNU
> libmicrohttpd is fast, portable and has a simple API and (without TLS
> support and other optional features) a small binary size (~32k).
>
>
> Major changes include:
>
> * use US-ASCII only (instead of user locale settings) when performing
> caseless string comparison.
> * Send response properly if sendfile() failed with EINVAL
> * do not crash if pthread_create() fails
> * various minor bugfixes (see ChangeLog)
> * use non-blocking sockets on all platforms
> * various improvements to the documentation
> * reducing number of system calls
>
> You can download GNU libmicrohttpd from
>
> * ftp://ftp.gnu.org/gnu/libmicrohttpd/ and all GNU FTP mirrors.
> * Our Subversion repository at https://gnunet.org/svn/libmicrohttpd/
>
> Please report bugs to our bugtracker at https://gnunet.org/bugs/.
>
> The documentation (including a reference manual and tutorial) can be
> found at http://www.gnu.org/software/libmicrohttpd/.
>
>
> Happy hacking!
>
> Christian & Evgeny
>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <microhttpd.h>
static void http_PanicCallback( void *cls, const char *file, unsigned int line, const char *reason )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
}
static void http_NotifyConnectionCallback( void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
}
static int http_AcceptPolicyCallback( void *cls, const struct sockaddr *addr, socklen_t addrlen )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
return MHD_YES;
}
static void* http_InitializeHandlerCallback( void *cls, const char *uri, struct MHD_Connection *connection )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
return NULL;
}
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 )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
return MHD_YES;
}
static void http_RequestCompletedCallback( void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe )
{
fprintf( stderr, "%s\n", __PRETTY_FUNCTION__ );
}
int main()
{
// create a socket on port 8080
int ai_family = AF_INET;
struct sockaddr addr_socket;
struct sockaddr_in *in_addr = (struct sockaddr_in *) &addr_socket;
memset( in_addr, 0, sizeof(*in_addr) );
in_addr->sin_family = AF_INET;
in_addr->sin_port = htons( 8080 );
in_addr->sin_addr.s_addr = htonl( INADDR_ANY );
socklen_t addr_len = sizeof(*in_addr);
// Create socket
int listening_socket = socket( ai_family, SOCK_STREAM, IPPROTO_TCP );
if( listening_socket == -1 )
{
fprintf( stderr, "Error: Could not create socket: %s.\n", strerror(errno) );
return EXIT_FAILURE;
}
// Bind socket
int bound = bind( listening_socket, &addr_socket, addr_len );
if( bound == -1 )
{
close( listening_socket );
fprintf( stderr, "Error: Bind failed: %s\n", strerror(errno) );
return EXIT_FAILURE;
}
// Start listening
int listening = listen( listening_socket, 31 );
if( listening == -1 )
{
close( listening_socket );
fprintf( stderr, "Listen failed: %s\n", strerror(errno) );
return EXIT_FAILURE;
}
// Panic callback
MHD_set_panic_func( http_PanicCallback, NULL );
// Options
struct MHD_OptionItem options_default[] =
{
// Thrading
{ MHD_OPTION_THREAD_POOL_SIZE, 1, NULL },
{ MHD_OPTION_THREAD_STACK_SIZE, 0, NULL },
{ MHD_OPTION_NOTIFY_CONNECTION, (intptr_t)http_NotifyConnectionCallback, NULL },
{ MHD_OPTION_URI_LOG_CALLBACK, (intptr_t)http_InitializeHandlerCallback, NULL },
{ MHD_OPTION_NOTIFY_COMPLETED, (intptr_t)http_RequestCompletedCallback, NULL },
{ MHD_OPTION_END, 0, NULL }
};
struct MHD_OptionItem option_socket[] =
{
{ MHD_OPTION_LISTEN_SOCKET, listening_socket, NULL },
{ MHD_OPTION_END, 0, NULL }
};
// Create daemon
unsigned int daemon_flags = MHD_USE_SELECT_INTERNALLY | MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_SUSPEND_RESUME | MHD_USE_PIPE_FOR_SHUTDOWN;
struct MHD_Daemon *daemon = MHD_start_daemon( daemon_flags, 0,
http_AcceptPolicyCallback, NULL,
http_AccessHandlerCallback, NULL,
MHD_OPTION_ARRAY, options_default,
MHD_OPTION_ARRAY, option_socket,
MHD_OPTION_END );
if( daemon == NULL )
return EXIT_FAILURE;
sleep( 10000 );
// Stop daemon
MHD_stop_daemon( daemon );
return EXIT_SUCCESS;
}