libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit c2e56cafe8e03f3945ba2de012c3640f2fb1e448
parent fb582792db5b99b5fefa0bb1edd84e726b2cb025
Author: Nils Durner <durner@gnunet.org>
Date:   Sat,  7 Nov 2009 19:23:09 +0000

MHD_set_panic_func

Diffstat:
Msrc/daemon/EXPORT.sym | 1+
Msrc/daemon/connection.c | 14+++++++-------
Msrc/daemon/daemon.c | 58+++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/daemon/internal.h | 7+++++++
Msrc/daemon/postprocessor.c | 8++++----
Msrc/include/microhttpd.h | 27+++++++++++++++++++++++----
6 files changed, 85 insertions(+), 30 deletions(-)

diff --git a/src/daemon/EXPORT.sym b/src/daemon/EXPORT.sym @@ -20,3 +20,4 @@ MHD_post_process MHD_destroy_post_processor MHD_get_daemon_info MHD_get_connection_info +MHD_set_panic_func diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -296,7 +296,7 @@ MHD_connection_close (struct MHD_Connection *connection, connection->daemon->notify_completed (connection->daemon-> notify_completed_cls, connection, &connection->client_context, - termination_code); + termination_code); connection->client_aware = MHD_NO; } @@ -341,7 +341,7 @@ try_ready_normal_body (struct MHD_Connection *connection) connection->response_write_position)); if ((ret == 0) && (0 != (connection->daemon->options & MHD_USE_SELECT_INTERNALLY))) - abort (); /* serious client API violation */ + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, "API violation"); if (ret == -1) { /* either error or http 1.0 transfer, close @@ -494,7 +494,7 @@ add_extra_headers (struct MHD_Connection *connection) MHD_HTTP_HEADER_CONTENT_LENGTH)) { SPRINTF (buf, - "%llu", + "%llu", (unsigned long long)connection->response->total_size); MHD_add_response_header (connection->response, MHD_HTTP_HEADER_CONTENT_LENGTH, buf); @@ -630,7 +630,7 @@ build_header_response (struct MHD_Connection *connection) memcpy (&data[off], "\r\n", 2); off += 2; if (off != size) - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); connection->write_buffer = data; connection->write_buffer_append_offset = size; connection->write_buffer_send_offset = 0; @@ -986,8 +986,8 @@ parse_cookie_header (struct MHD_Connection *connection) char old; int quotes; - hdr = MHD_lookup_connection_value (connection, - MHD_HEADER_KIND, + hdr = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, MHD_HTTP_HEADER_COOKIE); if (hdr == NULL) return MHD_YES; @@ -1259,7 +1259,7 @@ call_connection_handler (struct MHD_Connection *connection) return; } if (processed > used) - abort (); /* fatal client API violation! */ + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, "API violation"); if (processed != 0) instant_retry = MHD_NO; /* client did not process everything */ used -= processed; diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -76,6 +76,20 @@ static void pthread_kill (int, int) { #endif // __SYMBIAN32__ /** + * Default implementation of the panic function + */ +void mhd_panic_std(void *cls, + const char *file, + unsigned int line, + const char *reason) +{ + abort (); +} + +MHD_PanicCallback mhd_panic; +void *mhd_panic_cls; + +/** * Trace up to and return master daemon. If the supplied daemon * is a master, then return the daemon itself. */ @@ -465,7 +479,7 @@ MHD_handle_connection (void *data) unsigned int now; if (con == NULL) - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); timeout = con->daemon->connection_timeout; while ((!con->daemon->shutdown) && (con->socket_fd != -1)) { @@ -486,7 +500,7 @@ MHD_handle_connection (void *data) { /* do not block (we're waiting for our callback to succeed) */ tv.tv_sec = 0; - } + } } else { @@ -586,7 +600,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) #if HAVE_INET6 if (sizeof (struct sockaddr) > sizeof (struct sockaddr_in6)) - abort (); /* fatal, serious error */ + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); /* fatal, serious error */ #endif addrlen = sizeof (addrstorage); memset (addr, 0, sizeof (addrstorage)); @@ -615,7 +629,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) "Socket descriptor larger than FD_SETSIZE: %d > %d\n", s, FD_SETSIZE); -#endif +#endif CLOSE (s); return MHD_NO; } @@ -720,7 +734,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) "Failed to setup TLS credentials: unknown credential type %d\n", connection->daemon->cred_type); #endif - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, "Unknown credential type"); } MHD__gnutls_transport_set_ptr (connection->tls_session, (MHD_gnutls_transport_ptr_t) connection); @@ -792,7 +806,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) MHD_DLOG (daemon, "Failed to join a thread: %s\n", STRERROR (rc)); #endif - abort(); + abort(); } } MHD_destroy_response (pos->response); @@ -880,7 +894,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) timeout.tv_sec = 0; timeout.tv_usec = 0; if (daemon == NULL) - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); if (daemon->shutdown == MHD_YES) return MHD_NO; FD_ZERO (&rs); @@ -907,11 +921,11 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) return MHD_NO; FD_SET (max, &rs); } - + /* in case we are missing the SIGALRM, keep going after at most 1s; see http://lists.gnu.org/archive/html/libmicrohttpd/2009-10/msg00013.html */ timeout.tv_usec = 0; - timeout.tv_sec = 1; + timeout.tv_sec = 1; if (may_block == MHD_NO) { timeout.tv_usec = 0; @@ -1188,7 +1202,7 @@ MHD_start_daemon_va (unsigned int options, opt); } #endif - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); } } @@ -1228,7 +1242,7 @@ MHD_start_daemon_va (unsigned int options, } #endif else - socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); + socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); if (socket_fd < 0) { #if HAVE_MESSAGES @@ -1247,9 +1261,9 @@ MHD_start_daemon_va (unsigned int options, "Socket descriptor larger than FD_SETSIZE: %d > %d\n", socket_fd, FD_SETSIZE); -#endif +#endif CLOSE (socket_fd); - free (retVal); + free (retVal); return NULL; } #endif @@ -1528,7 +1542,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) MHD_DLOG (daemon, "Failed to join a thread: %s\n", STRERROR (rc)); #endif - abort(); + abort(); } MHD_close_connections (&daemon->worker_pool[i]); } @@ -1612,6 +1626,17 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon, } /** + * Sets the global error handler to a different implementation + * @param cb new error handler + * @param cls passed to error handler + */ +void MHD_set_panic_func (MHD_PanicCallback cb, void *cls) +{ + mhd_panic = cb; + mhd_panic_cls = cls; +} + +/** * Obtain the version of this library * * @return static version string, e.g. "0.4.1" @@ -1648,6 +1673,9 @@ sigalrmHandler (int sig) */ void ATTRIBUTE_CONSTRUCTOR MHD_init () { + mhd_panic = mhd_panic_std; + mhd_panic_cls = NULL; + #ifndef WINDOWS /* make sure SIGALRM does not kill us */ memset (&sig, 0, sizeof (struct sigaction)); @@ -1668,7 +1696,7 @@ void ATTRIBUTE_DESTRUCTOR MHD_fini () { #if HTTPS_SUPPORT if (0 != pthread_mutex_destroy(&MHD_gnutls_init_mutex)) - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); #endif #ifndef WINDOWS sigaction (SIGALRM, &old, &sig); diff --git a/src/daemon/internal.h b/src/daemon/internal.h @@ -45,6 +45,13 @@ */ #define MHD_BUF_INC_SIZE 2048 +/** + * Error handler + */ +extern MHD_PanicCallback mhd_panic; +extern void *mhd_panic_cls; + + #if HAVE_MESSAGES /** * fprintf-like helper function for logging debug diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c @@ -256,7 +256,7 @@ MHD_create_post_processor (struct MHD_Connection *connection, size_t blen; if ((buffer_size < 256) || (connection == NULL) || (ikvi == NULL)) - abort (); + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); encoding = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_TYPE); @@ -304,7 +304,7 @@ MHD_create_post_processor (struct MHD_Connection *connection, */ static int post_process_urlencoded (struct MHD_PostProcessor *pp, - const char *post_data, + const char *post_data, size_t post_data_len) { size_t equals; @@ -440,7 +440,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, } return MHD_NO; default: - abort (); /* should never happen! */ + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); /* should never happen! */ } } return MHD_YES; @@ -960,7 +960,7 @@ post_process_multipart (struct MHD_PostProcessor *pp, state_changed = 1; break; default: - abort (); /* should never happen! */ + mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); /* should never happen! */ } AGAIN: if (ioff > 0) diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -577,7 +577,7 @@ enum MHD_ConnectionInfoType /** * Obtain IP address of the client. - * Takes no extra arguments. + * Takes no extra arguments. */ MHD_CONNECTION_INFO_CLIENT_ADDRESS }; @@ -637,6 +637,18 @@ struct MHD_Response; struct MHD_PostProcessor; /** + * Callback for serious error condition. The default action is to abort(). + * @param cls user specified value + * @param file where the error occured + * @param line where the error occured + * @param reason error detail, may be NULL + */ +typedef void (*MHD_PanicCallback) (void *cls, + const char *file, + unsigned int line, + const char *reason); + +/** * Allow or deny a client to connect. * * @param addr address information from the client @@ -758,8 +770,8 @@ typedef int * requests using the same TCP connection). */ typedef int - (*MHD_ContentReaderCallback) (void *cls, - uint64_t pos, + (*MHD_ContentReaderCallback) (void *cls, + uint64_t pos, char *buf, int max); @@ -953,6 +965,13 @@ MHD_set_connection_value (struct MHD_Connection *connection, const char *key, const char *value); /** + * Sets the global error handler to a different implementation + * @param cb new error handler + * @param cls passed to error handler + */ +void MHD_set_panic_func (MHD_PanicCallback cb, void *cls); + +/** * Get a particular header value. If multiple * values match the kind, return any one of them. * @@ -1212,7 +1231,7 @@ const union MHD_DaemonInfo *MHD_get_daemon_info (struct MHD_Daemon *daemon, /** * Obtain the version of this library - * + * * @return static version string, e.g. "0.4.1" */ const char* MHD_get_version(void);