aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/microhttpd.h82
-rw-r--r--src/microhttpd/connection.c2
-rw-r--r--src/microhttpd/daemon.c46
-rw-r--r--src/microhttpd/internal.h74
4 files changed, 170 insertions, 34 deletions
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index c3c2c6f0..28c3792b 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
130 * Current version of the library. 130 * Current version of the library.
131 * 0x01093001 = 1.9.30-1. 131 * 0x01093001 = 1.9.30-1.
132 */ 132 */
133#define MHD_VERSION 0x00093903 133#define MHD_VERSION 0x00093904
134 134
135/** 135/**
136 * MHD-internal return code for "YES". 136 * MHD-internal return code for "YES".
@@ -871,7 +871,19 @@ enum MHD_OPTION
871 * `const char *` argument. 871 * `const char *` argument.
872 * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY. 872 * This should be used in conjunction with #MHD_OPTION_HTTPS_MEM_KEY.
873 */ 873 */
874 MHD_OPTION_HTTPS_KEY_PASSWORD = 26 874 MHD_OPTION_HTTPS_KEY_PASSWORD = 26,
875
876 /**
877 * Register a function that should be called whenever a connection is
878 * started or closed.
879 *
880 * This option should be followed by TWO pointers. First a pointer
881 * to a function of type #MHD_NotifyConnectionCallback and second a
882 * pointer to a closure to pass to the request completed callback.
883 * The second pointer maybe NULL.
884 */
885 MHD_OPTION_NOTIFY_CONNECTION = 27
886
875}; 887};
876 888
877 889
@@ -1006,6 +1018,29 @@ enum MHD_RequestTerminationCode
1006 1018
1007 1019
1008/** 1020/**
1021 * The `enum MHD_ConnectionNotificationCode` specifies types
1022 * of connection notifications.
1023 * @ingroup request
1024 */
1025enum MHD_ConnectionNotificationCode
1026{
1027
1028 /**
1029 * A new connection has been started.
1030 * @ingroup request
1031 */
1032 MHD_CONNECTION_NOTIFY_STARTED = 0,
1033
1034 /**
1035 * A connection is closed.
1036 * @ingroup request
1037 */
1038 MHD_CONNECTION_NOTIFY_CLOSED = 1
1039
1040};
1041
1042
1043/**
1009 * Information about a connection. 1044 * Information about a connection.
1010 */ 1045 */
1011union MHD_ConnectionInfo 1046union MHD_ConnectionInfo
@@ -1046,6 +1081,12 @@ union MHD_ConnectionInfo
1046 * daemons running). 1081 * daemons running).
1047 */ 1082 */
1048 struct MHD_Daemon *daemon; 1083 struct MHD_Daemon *daemon;
1084
1085 /**
1086 * Socket-specific client context. Points to the same address as
1087 * the "socket_context" of the #MHD_NotifyConnectionCallback.
1088 */
1089 void **socket_context;
1049}; 1090};
1050 1091
1051 1092
@@ -1104,7 +1145,17 @@ enum MHD_ConnectionInfoType
1104 * No extra arguments should be passed. 1145 * No extra arguments should be passed.
1105 * @ingroup request 1146 * @ingroup request
1106 */ 1147 */
1107 MHD_CONNECTION_INFO_CONNECTION_FD 1148 MHD_CONNECTION_INFO_CONNECTION_FD,
1149
1150 /**
1151 * Returns the client-specific pointer to a `void *` that was (possibly)
1152 * set during a #MHD_NotifyConnectionCallback when the socket was
1153 * first accepted. Note that this is NOT the same as the "con_cls"
1154 * argument of the #MHD_AccessHandlerCallback. The "con_cls" is
1155 * fresh for each HTTP request, while the "socket_context" is fresh
1156 * for each socket.
1157 */
1158 MHD_CONNECTION_INFO_SOCKET_CONTEXT
1108 1159
1109}; 1160};
1110 1161
@@ -1243,6 +1294,31 @@ typedef void
1243 void **con_cls, 1294 void **con_cls,
1244 enum MHD_RequestTerminationCode toe); 1295 enum MHD_RequestTerminationCode toe);
1245 1296
1297/**
1298 * Signature of the callback used by MHD to notify the
1299 * application about started/stopped connections
1300 *
1301 * @param cls client-defined closure
1302 * @param connection connection handle
1303 * @param socket_context socket-specific pointer where the
1304 * client can associate some state specific
1305 * to the TCP connection; note that this is
1306 * different from the "con_cls" which is per
1307 * HTTP request. The client can initialize
1308 * during #MHD_CONNECTION_NOTIFY_STARTED and
1309 * cleanup during #MHD_CONNECTION_NOTIFY_CLOSED
1310 * and access in the meantime using
1311 * #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
1312 * @param toe reason for connection notification
1313 * @see #MHD_OPTION_NOTIFY_CONNECTION
1314 * @ingroup request
1315 */
1316typedef void
1317(*MHD_NotifyConnectionCallback) (void *cls,
1318 struct MHD_Connection *connection,
1319 void **socket_context,
1320 enum MHD_ConnectionNotificationCode toe);
1321
1246 1322
1247/** 1323/**
1248 * Iterator over key-value pairs. This iterator 1324 * Iterator over key-value pairs. This iterator
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index e346b99f..efc858c0 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff 3 Copyright (C) 2007-2015 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 39ea3e85..dd2234fd 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -796,6 +796,7 @@ MHD_handle_connection (void *data)
796 struct pollfd p[1]; 796 struct pollfd p[1];
797#endif 797#endif
798 798
799
799 timeout = con->daemon->connection_timeout; 800 timeout = con->daemon->connection_timeout;
800 while ( (MHD_YES != con->daemon->shutdown) && 801 while ( (MHD_YES != con->daemon->shutdown) &&
801 (MHD_CONNECTION_CLOSED != con->state) ) 802 (MHD_CONNECTION_CLOSED != con->state) )
@@ -958,6 +959,13 @@ exit:
958 MHD_destroy_response (con->response); 959 MHD_destroy_response (con->response);
959 con->response = NULL; 960 con->response = NULL;
960 } 961 }
962
963 if (NULL != con->daemon->notify_connection)
964 con->daemon->notify_connection (con->daemon->notify_connection_cls,
965 con,
966 &con->socket_context,
967 MHD_CONNECTION_NOTIFY_CLOSED);
968
961 return (MHD_THRD_RTRN_TYPE_)0; 969 return (MHD_THRD_RTRN_TYPE_)0;
962} 970}
963 971
@@ -1301,7 +1309,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
1301 errno = eno; 1309 errno = eno;
1302 return MHD_NO; 1310 return MHD_NO;
1303 } 1311 }
1304 memset (connection, 0, sizeof (struct MHD_Connection)); 1312 memset (connection,
1313 0,
1314 sizeof (struct MHD_Connection));
1305 connection->pool = MHD_pool_create (daemon->pool_size); 1315 connection->pool = MHD_pool_create (daemon->pool_size);
1306 if (NULL == connection->pool) 1316 if (NULL == connection->pool)
1307 { 1317 {
@@ -1445,11 +1455,19 @@ internal_add_connection (struct MHD_Daemon *daemon,
1445 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1455 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1446 MHD_PANIC ("Failed to release cleanup mutex\n"); 1456 MHD_PANIC ("Failed to release cleanup mutex\n");
1447 1457
1458 if (NULL != daemon->notify_connection)
1459 daemon->notify_connection (daemon->notify_connection_cls,
1460 connection,
1461 &connection->socket_context,
1462 MHD_CONNECTION_NOTIFY_STARTED);
1463
1448 /* attempt to create handler thread */ 1464 /* attempt to create handler thread */
1449 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 1465 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1450 { 1466 {
1451 res_thread_create = create_thread (&connection->pid, daemon, 1467 res_thread_create = create_thread (&connection->pid,
1452 &MHD_handle_connection, connection); 1468 daemon,
1469 &MHD_handle_connection,
1470 connection);
1453 if (0 != res_thread_create) 1471 if (0 != res_thread_create)
1454 { 1472 {
1455 eno = errno; 1473 eno = errno;
@@ -1508,6 +1526,11 @@ internal_add_connection (struct MHD_Daemon *daemon,
1508 daemon->connections++; 1526 daemon->connections++;
1509 return MHD_YES; 1527 return MHD_YES;
1510 cleanup: 1528 cleanup:
1529 if (NULL != daemon->notify_connection)
1530 daemon->notify_connection (daemon->notify_connection_cls,
1531 connection,
1532 &connection->socket_context,
1533 MHD_CONNECTION_NOTIFY_CLOSED);
1511 if (0 != MHD_socket_close_ (client_socket)) 1534 if (0 != MHD_socket_close_ (client_socket))
1512 MHD_PANIC ("close failed\n"); 1535 MHD_PANIC ("close failed\n");
1513 MHD_ip_limit_del (daemon, addr, addrlen); 1536 MHD_ip_limit_del (daemon, addr, addrlen);
@@ -1921,12 +1944,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
1921 } 1944 }
1922 MHD_pool_destroy (pos->pool); 1945 MHD_pool_destroy (pos->pool);
1923#if HTTPS_SUPPORT 1946#if HTTPS_SUPPORT
1924 if (pos->tls_session != NULL) 1947 if (NULL != pos->tls_session)
1925 gnutls_deinit (pos->tls_session); 1948 gnutls_deinit (pos->tls_session);
1926#endif 1949#endif
1927 MHD_ip_limit_del (daemon, 1950 if (NULL != daemon->notify_connection)
1928 (struct sockaddr *) pos->addr, 1951 daemon->notify_connection (daemon->notify_connection_cls,
1929 pos->addr_len); 1952 pos,
1953 &pos->socket_context,
1954 MHD_CONNECTION_NOTIFY_CLOSED);
1955 MHD_ip_limit_del (daemon, pos->addr, pos->addr_len);
1930#if EPOLL_SUPPORT 1956#if EPOLL_SUPPORT
1931 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) 1957 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1932 { 1958 {
@@ -2993,6 +3019,11 @@ parse_options_va (struct MHD_Daemon *daemon,
2993 va_arg (ap, MHD_RequestCompletedCallback); 3019 va_arg (ap, MHD_RequestCompletedCallback);
2994 daemon->notify_completed_cls = va_arg (ap, void *); 3020 daemon->notify_completed_cls = va_arg (ap, void *);
2995 break; 3021 break;
3022 case MHD_OPTION_NOTIFY_CONNECTION:
3023 daemon->notify_connection =
3024 va_arg (ap, MHD_NotifyConnectionCallback);
3025 daemon->notify_connection_cls = va_arg (ap, void *);
3026 break;
2996 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 3027 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
2997 daemon->per_ip_connection_limit = va_arg (ap, unsigned int); 3028 daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
2998 break; 3029 break;
@@ -3234,6 +3265,7 @@ parse_options_va (struct MHD_Daemon *daemon,
3234 break; 3265 break;
3235 /* all options taking two pointers */ 3266 /* all options taking two pointers */
3236 case MHD_OPTION_NOTIFY_COMPLETED: 3267 case MHD_OPTION_NOTIFY_COMPLETED:
3268 case MHD_OPTION_NOTIFY_CONNECTION:
3237 case MHD_OPTION_URI_LOG_CALLBACK: 3269 case MHD_OPTION_URI_LOG_CALLBACK:
3238 case MHD_OPTION_EXTERNAL_LOGGER: 3270 case MHD_OPTION_EXTERNAL_LOGGER:
3239 case MHD_OPTION_UNESCAPE_CALLBACK: 3271 case MHD_OPTION_UNESCAPE_CALLBACK:
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index c2cab42d..c0700ddf 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2013 Daniel Pittman and Christian Grothoff 3 Copyright (C) 2007-2015 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -487,8 +487,10 @@ MHD_state_to_string (enum MHD_CONNECTION_STATE state);
487 * @param max_bytes maximum number of bytes to receive 487 * @param max_bytes maximum number of bytes to receive
488 * @return number of bytes written to write_to 488 * @return number of bytes written to write_to
489 */ 489 */
490typedef ssize_t (*ReceiveCallback) (struct MHD_Connection * conn, 490typedef ssize_t
491 void *write_to, size_t max_bytes); 491(*ReceiveCallback) (struct MHD_Connection *conn,
492 void *write_to,
493 size_t max_bytes);
492 494
493 495
494/** 496/**
@@ -499,8 +501,10 @@ typedef ssize_t (*ReceiveCallback) (struct MHD_Connection * conn,
499 * @param max_bytes maximum number of bytes to transmit 501 * @param max_bytes maximum number of bytes to transmit
500 * @return number of bytes transmitted 502 * @return number of bytes transmitted
501 */ 503 */
502typedef ssize_t (*TransmitCallback) (struct MHD_Connection * conn, 504typedef ssize_t
503 const void *write_to, size_t max_bytes); 505(*TransmitCallback) (struct MHD_Connection *conn,
506 const void *write_to,
507 size_t max_bytes);
504 508
505 509
506/** 510/**
@@ -578,14 +582,23 @@ struct MHD_Connection
578 struct MemoryPool *pool; 582 struct MemoryPool *pool;
579 583
580 /** 584 /**
581 * We allow the main application to associate some 585 * We allow the main application to associate some pointer with the
582 * pointer with the connection. Here is where we 586 * HTTP request, which is passed to each #MHD_AccessHandlerCallback
583 * store it. (MHD does not know or care what it 587 * and some other API calls. Here is where we store it. (MHD does
584 * is). 588 * not know or care what it is).
585 */ 589 */
586 void *client_context; 590 void *client_context;
587 591
588 /** 592 /**
593 * We allow the main application to associate some pointer with the
594 * TCP connection (which may span multiple HTTP requests). Here is
595 * where we store it. (MHD does not know or care what it is).
596 * The location is given to the #MHD_NotifyConnectionCallback and
597 * also accessible via #MHD_CONNECTION_INFO_SOCKET_CONTEXT.
598 */
599 void *socket_context;
600
601 /**
589 * Request method. Should be GET/POST/etc. Allocated 602 * Request method. Should be GET/POST/etc. Allocated
590 * in pool. 603 * in pool.
591 */ 604 */
@@ -606,7 +619,7 @@ struct MHD_Connection
606 /** 619 /**
607 * Buffer for reading requests. Allocated 620 * Buffer for reading requests. Allocated
608 * in pool. Actually one byte larger than 621 * in pool. Actually one byte larger than
609 * read_buffer_size (if non-NULL) to allow for 622 * @e read_buffer_size (if non-NULL) to allow for
610 * 0-termination. 623 * 0-termination.
611 */ 624 */
612 char *read_buffer; 625 char *read_buffer;
@@ -620,7 +633,8 @@ struct MHD_Connection
620 /** 633 /**
621 * Last incomplete header line during parsing of headers. 634 * Last incomplete header line during parsing of headers.
622 * Allocated in pool. Only valid if state is 635 * Allocated in pool. Only valid if state is
623 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED. 636 * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
637 * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
624 */ 638 */
625 char *last; 639 char *last;
626 640
@@ -628,12 +642,13 @@ struct MHD_Connection
628 * Position after the colon on the last incomplete header 642 * Position after the colon on the last incomplete header
629 * line during parsing of headers. 643 * line during parsing of headers.
630 * Allocated in pool. Only valid if state is 644 * Allocated in pool. Only valid if state is
631 * either HEADER_PART_RECEIVED or FOOTER_PART_RECEIVED. 645 * either #MHD_CONNECTION_HEADER_PART_RECEIVED or
646 * #MHD_CONNECTION_FOOTER_PART_RECEIVED.
632 */ 647 */
633 char *colon; 648 char *colon;
634 649
635 /** 650 /**
636 * Foreign address (of length addr_len). MALLOCED (not 651 * Foreign address (of length @e addr_len). MALLOCED (not
637 * in pool!). 652 * in pool!).
638 */ 653 */
639 struct sockaddr *addr; 654 struct sockaddr *addr;
@@ -676,7 +691,7 @@ struct MHD_Connection
676 691
677 /** 692 /**
678 * How many more bytes of the body do we expect 693 * How many more bytes of the body do we expect
679 * to read? MHD_SIZE_UNKNOWN for unknown. 694 * to read? #MHD_SIZE_UNKNOWN for unknown.
680 */ 695 */
681 uint64_t remaining_upload_size; 696 uint64_t remaining_upload_size;
682 697
@@ -800,17 +815,17 @@ struct MHD_Connection
800 /** 815 /**
801 * Handler used for processing read connection operations 816 * Handler used for processing read connection operations
802 */ 817 */
803 int (*read_handler) (struct MHD_Connection * connection); 818 int (*read_handler) (struct MHD_Connection *connection);
804 819
805 /** 820 /**
806 * Handler used for processing write connection operations 821 * Handler used for processing write connection operations
807 */ 822 */
808 int (*write_handler) (struct MHD_Connection * connection); 823 int (*write_handler) (struct MHD_Connection *connection);
809 824
810 /** 825 /**
811 * Handler used for processing idle connection operations 826 * Handler used for processing idle connection operations
812 */ 827 */
813 int (*idle_handler) (struct MHD_Connection * connection); 828 int (*idle_handler) (struct MHD_Connection *connection);
814 829
815 /** 830 /**
816 * Function used for reading HTTP request stream. 831 * Function used for reading HTTP request stream.
@@ -864,9 +879,10 @@ struct MHD_Connection
864 * @param con connection handle 879 * @param con connection handle
865 * @return new closure 880 * @return new closure
866 */ 881 */
867typedef void * (*LogCallback)(void * cls, 882typedef void *
868 const char * uri, 883(*LogCallback)(void * cls,
869 struct MHD_Connection *con); 884 const char * uri,
885 struct MHD_Connection *con);
870 886
871/** 887/**
872 * Signature of function called to unescape URIs. See also 888 * Signature of function called to unescape URIs. See also
@@ -877,9 +893,10 @@ typedef void * (*LogCallback)(void * cls,
877 * @param uri 0-terminated string to unescape (should be updated) 893 * @param uri 0-terminated string to unescape (should be updated)
878 * @return length of the resulting string 894 * @return length of the resulting string
879 */ 895 */
880typedef size_t (*UnescapeCallback)(void *cls, 896typedef size_t
881 struct MHD_Connection *conn, 897(*UnescapeCallback)(void *cls,
882 char *uri); 898 struct MHD_Connection *conn,
899 char *uri);
883 900
884 901
885/** 902/**
@@ -1000,6 +1017,17 @@ struct MHD_Daemon
1000 void *notify_completed_cls; 1017 void *notify_completed_cls;
1001 1018
1002 /** 1019 /**
1020 * Function to call when we are starting/stopping
1021 * a connection. May be NULL.
1022 */
1023 MHD_NotifyConnectionCallback notify_connection;
1024
1025 /**
1026 * Closure argument to notify_connection.
1027 */
1028 void *notify_connection_cls;
1029
1030 /**
1003 * Function to call with the full URI at the 1031 * Function to call with the full URI at the
1004 * beginning of request processing. May be NULL. 1032 * beginning of request processing. May be NULL.
1005 * <p> 1033 * <p>