#include #include #include #include #include #include #include #include #include #include #include #include static char usage [] = " port\n" " \n\n" ; char *thisprog; static void Usage(void) { fprintf(stderr, "%s: usage:\n%s", thisprog, usage); exit(1); } static const int one = 1; int getcon(int port, struct sockaddr *addr, socklen_t *addrlen) { static int listenfd = -1; if (listenfd < 0) { struct sockaddr_in ipaddr; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } (void) setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); memset(&ipaddr, 0, sizeof(ipaddr)); ipaddr.sin_family = AF_INET; ipaddr.sin_addr.s_addr = htonl(INADDR_ANY); ipaddr.sin_port = htons(port); if (bind(listenfd, (struct sockaddr *)&ipaddr, sizeof(ipaddr)) < 0) { perror("bind"); return -1; } fprintf(stderr, "Listening on port %d\n",(int)port); if (listen(listenfd, 5) < 0) { perror("listen"); return -1; } } int confd = accept(listenfd, addr, addrlen); if (confd < 0) { perror("accept"); return -1; } fprintf(stderr, "Accept returned %d\n", confd); return confd; } static int print_out_key (void *cls, enum MHD_ValueKind kind, const char *key, const char *value) { fprintf(stderr, "kind %d : %s -> %s\n", (int)kind, key, value); return MHD_YES; } static int answer_to_connection( void *cls, struct MHD_Connection *conn, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { fprintf(stderr, "answer_to_connection\n"); if (NULL == *con_cls) { // First call, look at headers, method etc. fprintf(stderr, "METHOD: %s\n", method); MHD_get_connection_values(conn,MHD_HEADER_KIND,&print_out_key,0); *con_cls = (void *)1; return MHD_YES; } struct MHD_Response *response = MHD_create_response_from_buffer(0, 0, MHD_RESPMEM_PERSISTENT); if (NULL == response ) { fprintf(stderr, "create_response failed\n"); return MHD_YES; } MHD_add_response_header (response, "Location", "http://go.to.hell/index.html"); MHD_add_response_header (response, "Connection", "close"); int ret = MHD_queue_response(conn, 302, response); MHD_destroy_response(response); return ret; } static void notify_connection_callback( void *cls, struct MHD_Connection *conn, void **socket_context, enum MHD_ConnectionNotificationCode toe) { switch (toe) { case MHD_CONNECTION_NOTIFY_STARTED: fprintf(stderr, "notify_connection_callback: started\n"); break; case MHD_CONNECTION_NOTIFY_CLOSED: fprintf(stderr, "notify_connection_callback: closed\n"); break; } } static void request_completed_callback( void *cls, struct MHD_Connection *conn, void **con_cls, enum MHD_RequestTerminationCode toe) { fprintf(stderr, "Request completed\n"); } static int op_flags; #define OPT_MOINS 0x1 int main(int argc, char **argv) { int fd; int port; struct MHD_Daemon *mhd; thisprog = argv[0]; argc--; argv++; if (argc != 1) Usage(); port = atoi(*argv++);argc --; mhd = MHD_start_daemon( MHD_USE_NO_LISTEN_SOCKET | MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG, -1, /* Accept policy callback and arg */ NULL, NULL, /* handler and arg */ &answer_to_connection, NULL, MHD_OPTION_CONNECTION_TIMEOUT, 1, MHD_OPTION_NOTIFY_COMPLETED, request_completed_callback, NULL, MHD_OPTION_NOTIFY_CONNECTION, notify_connection_callback, NULL, MHD_OPTION_END); if (NULL == mhd) { fprintf(stderr, "MHD_start_daemon failed\n"); return 1; } struct sockaddr addr; socklen_t addrlen=sizeof(addr); for (;;) { if ((fd = getcon(port, &addr, &addrlen)) < 0) exit(1); if (MHD_add_connection(mhd, fd, &addr, addrlen) != MHD_YES) { fprintf(stderr, "Add_connection failed\n"); return 0; } #if 0 const union MHD_DaemonInfo *info = MHD_get_daemon_info(mhd, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); if (info) { fprintf(stderr, "Connection count: %d\n", info->num_connections); } else { fprintf(stderr, "MHD_get_daemon_info returned null\n"); } #endif } exit(0); }