Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00029 #include "internal.h"
00030 #include "connection.h"
00031 #include "memorypool.h"
00032 #include "response.h"
00033 #include "reason_phrase.h"
00034 #include <gnutls/gnutls.h>
00035
00046 static void
00047 MHD_tls_connection_close (struct MHD_Connection *connection,
00048 enum MHD_RequestTerminationCode termination_code)
00049 {
00050 gnutls_bye (connection->tls_session, GNUTLS_SHUT_RDWR);
00051 MHD_connection_close (connection, termination_code);
00052 }
00053
00054
00072 static int
00073 MHD_tls_connection_handle_read (struct MHD_Connection *connection)
00074 {
00075 int ret;
00076
00077 connection->last_activity = time (NULL);
00078 if (connection->state == MHD_TLS_CONNECTION_INIT)
00079 {
00080 ret = gnutls_handshake (connection->tls_session);
00081 if (ret == GNUTLS_E_SUCCESS)
00082 {
00083
00084 connection->state = MHD_CONNECTION_INIT;
00085 return MHD_YES;
00086 }
00087 if ( (ret == GNUTLS_E_AGAIN) ||
00088 (ret == GNUTLS_E_INTERRUPTED) )
00089 {
00090
00091 return MHD_YES;
00092 }
00093
00094 #if HAVE_MESSAGES
00095 MHD_DLOG (connection->daemon,
00096 "Error: received handshake message out of context\n");
00097 #endif
00098 MHD_tls_connection_close (connection,
00099 MHD_REQUEST_TERMINATED_WITH_ERROR);
00100 return MHD_NO;
00101 }
00102 return MHD_connection_handle_read (connection);
00103 }
00104
00105
00115 static int
00116 MHD_tls_connection_handle_write (struct MHD_Connection *connection)
00117 {
00118 int ret;
00119
00120 connection->last_activity = time (NULL);
00121 #if DEBUG_STATES
00122 MHD_DLOG (connection->daemon, "%s: state: %s\n",
00123 __FUNCTION__, MHD_state_to_string (connection->state));
00124 #endif
00125 if (connection->state == MHD_TLS_CONNECTION_INIT)
00126 {
00127 ret = gnutls_handshake (connection->tls_session);
00128 if (ret == GNUTLS_E_SUCCESS)
00129 {
00130
00131 connection->state = MHD_CONNECTION_INIT;
00132 return MHD_YES;
00133 }
00134 if ( (ret == GNUTLS_E_AGAIN) ||
00135 (ret == GNUTLS_E_INTERRUPTED) )
00136 {
00137
00138 return MHD_YES;
00139 }
00140
00141 #if HAVE_MESSAGES
00142 MHD_DLOG (connection->daemon,
00143 "Error: received handshake message out of context\n");
00144 #endif
00145 MHD_tls_connection_close (connection,
00146 MHD_REQUEST_TERMINATED_WITH_ERROR);
00147 return MHD_NO;
00148 }
00149 return MHD_connection_handle_write (connection);
00150 }
00151
00152
00163 static int
00164 MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
00165 {
00166 unsigned int timeout;
00167
00168 #if DEBUG_STATES
00169 MHD_DLOG (connection->daemon, "%s: state: %s\n",
00170 __FUNCTION__, MHD_state_to_string (connection->state));
00171 #endif
00172 timeout = connection->daemon->connection_timeout;
00173 if ((connection->socket_fd != -1) && (timeout != 0)
00174 && (time (NULL) - timeout > connection->last_activity))
00175 {
00176 MHD_tls_connection_close (connection,
00177 MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
00178 return MHD_NO;
00179 }
00180 switch (connection->state)
00181 {
00182
00183 case MHD_TLS_CONNECTION_INIT:
00184 return MHD_YES;
00185
00186 case MHD_CONNECTION_CLOSED:
00187 if (connection->socket_fd != -1)
00188 MHD_tls_connection_close (connection,
00189 MHD_REQUEST_TERMINATED_COMPLETED_OK);
00190 return MHD_NO;
00191 default:
00192 if ( (0 != gnutls_record_check_pending (connection->tls_session)) &&
00193 (MHD_YES != MHD_tls_connection_handle_read (connection)) )
00194 return MHD_NO;
00195 return MHD_connection_handle_idle (connection);
00196 }
00197 return MHD_YES;
00198 }
00199
00200
00205 void
00206 MHD_set_https_callbacks (struct MHD_Connection *connection)
00207 {
00208 connection->read_handler = &MHD_tls_connection_handle_read;
00209 connection->write_handler = &MHD_tls_connection_handle_write;
00210 connection->idle_handler = &MHD_tls_connection_handle_idle;
00211 }
00212
00213