mirror of
https://github.com/lammertb/libhttp.git
synced 2026-01-27 08:02:47 +03:00
Moved close_connection to own file
This commit is contained in:
1
Makefile
1
Makefile
@@ -44,6 +44,7 @@ BUILD_DIRS = $(BUILD_DIR) $(BUILD_DIR)/src $(BUILD_DIR)/resources
|
||||
LIB_SOURCES = src/libhttp.c \
|
||||
src/httplib_accept_new_connection.c \
|
||||
src/httplib_check_feature.c \
|
||||
src/httplib_close_connection.c \
|
||||
src/httplib_connect_client.c \
|
||||
src/httplib_connect_websocket_client.c \
|
||||
src/httplib_consume_socket.c \
|
||||
|
||||
113
src/httplib_close_connection.c
Normal file
113
src/httplib_close_connection.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Lammert Bies
|
||||
* Copyright (c) 2013-2016 the Civetweb developers
|
||||
* Copyright (c) 2004-2013 Sergey Lyubka
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "libhttp-private.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void XX_httplib_close_connection( struct mg_connection *conn );
|
||||
*
|
||||
* The function XX_httplib_close_connection() is the internal function which
|
||||
* does the heavy lifting to close a connection.
|
||||
*/
|
||||
|
||||
void XX_httplib_close_connection( struct mg_connection *conn ) {
|
||||
|
||||
if ( conn == NULL || conn->ctx == NULL ) return;
|
||||
|
||||
/* call the connection_close callback if assigned */
|
||||
if ((conn->ctx->callbacks.connection_close != NULL) && (conn->ctx->context_type == 1)) {
|
||||
conn->ctx->callbacks.connection_close(conn);
|
||||
}
|
||||
|
||||
mg_lock_connection( conn );
|
||||
|
||||
conn->must_close = 1;
|
||||
|
||||
#ifndef NO_SSL
|
||||
if (conn->ssl != NULL) {
|
||||
/* Run SSL_shutdown twice to ensure completly close SSL connection
|
||||
*/
|
||||
SSL_shutdown(conn->ssl);
|
||||
SSL_free(conn->ssl);
|
||||
/* Avoid CRYPTO_cleanup_all_ex_data(); See discussion:
|
||||
* https://wiki.openssl.org/index.php/Talk:Library_Initialization */
|
||||
ERR_remove_state(0);
|
||||
conn->ssl = NULL;
|
||||
}
|
||||
#endif
|
||||
if ( conn->client.sock != INVALID_SOCKET ) {
|
||||
|
||||
XX_httplib_close_socket_gracefully( conn );
|
||||
conn->client.sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
mg_unlock_connection( conn );
|
||||
|
||||
} /* XX_httplib_close_connection */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void mg_close_connection( struct mg_connection *conn );
|
||||
*
|
||||
* The function mg_close_connection() closes the connection passed as a
|
||||
* parameter to this function. The function does not return a success or
|
||||
* failure value.
|
||||
*/
|
||||
|
||||
void mg_close_connection( struct mg_connection *conn ) {
|
||||
|
||||
struct mg_context *client_ctx = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if ( conn == NULL ) return;
|
||||
|
||||
if ( conn->ctx->context_type == 2 ) {
|
||||
|
||||
client_ctx = conn->ctx;
|
||||
/* client context: loops must end */
|
||||
conn->ctx->stop_flag = 1;
|
||||
}
|
||||
|
||||
#ifndef NO_SSL
|
||||
if (conn->client_ssl_ctx != NULL) SSL_CTX_free((SSL_CTX *)conn->client_ssl_ctx);
|
||||
#endif
|
||||
XX_httplib_close_connection(conn);
|
||||
if (client_ctx != NULL) {
|
||||
/* join worker thread and free context */
|
||||
for (i = 0; i < client_ctx->cfg_worker_threads; i++) {
|
||||
if (client_ctx->workerthreadids[i] != 0) XX_httplib_join_thread(client_ctx->workerthreadids[i]);
|
||||
}
|
||||
|
||||
XX_httplib_free(client_ctx->workerthreadids);
|
||||
XX_httplib_free(client_ctx);
|
||||
pthread_mutex_destroy(&conn->mutex);
|
||||
XX_httplib_free(conn);
|
||||
}
|
||||
|
||||
} /* mg_close_connection */
|
||||
@@ -614,36 +614,36 @@ struct ssl_func {
|
||||
#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
|
||||
|
||||
|
||||
#define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr)
|
||||
#define CRYPTO_num_locks (*(int (*)(void))XX_httplib_crypto_sw[0].ptr)
|
||||
#define CRYPTO_set_locking_callback \
|
||||
(*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr)
|
||||
(*(void (*)(void (*)(int, int, const char *, int)))XX_httplib_crypto_sw[1].ptr)
|
||||
#define CRYPTO_set_id_callback \
|
||||
(*(void (*)(unsigned long (*)(void)))crypto_sw[2].ptr)
|
||||
#define ERR_get_error (*(unsigned long (*)(void))crypto_sw[3].ptr)
|
||||
#define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[4].ptr)
|
||||
#define ERR_remove_state (*(void (*)(unsigned long))crypto_sw[5].ptr)
|
||||
#define ERR_free_strings (*(void (*)(void))crypto_sw[6].ptr)
|
||||
#define ENGINE_cleanup (*(void (*)(void))crypto_sw[7].ptr)
|
||||
#define CONF_modules_unload (*(void (*)(int))crypto_sw[8].ptr)
|
||||
#define CRYPTO_cleanup_all_ex_data (*(void (*)(void))crypto_sw[9].ptr)
|
||||
#define EVP_cleanup (*(void (*)(void))crypto_sw[10].ptr)
|
||||
#define X509_free (*(void (*)(X509 *))crypto_sw[11].ptr)
|
||||
#define X509_get_subject_name (*(X509_NAME * (*)(X509 *))crypto_sw[12].ptr)
|
||||
#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))crypto_sw[13].ptr)
|
||||
(*(void (*)(unsigned long (*)(void)))XX_httplib_crypto_sw[2].ptr)
|
||||
#define ERR_get_error (*(unsigned long (*)(void))XX_httplib_crypto_sw[3].ptr)
|
||||
#define ERR_error_string (*(char *(*)(unsigned long, char *))XX_httplib_crypto_sw[4].ptr)
|
||||
#define ERR_remove_state (*(void (*)(unsigned long))XX_httplib_crypto_sw[5].ptr)
|
||||
#define ERR_free_strings (*(void (*)(void))XX_httplib_crypto_sw[6].ptr)
|
||||
#define ENGINE_cleanup (*(void (*)(void))XX_httplib_crypto_sw[7].ptr)
|
||||
#define CONF_modules_unload (*(void (*)(int))XX_httplib_crypto_sw[8].ptr)
|
||||
#define CRYPTO_cleanup_all_ex_data (*(void (*)(void))XX_httplib_crypto_sw[9].ptr)
|
||||
#define EVP_cleanup (*(void (*)(void))XX_httplib_crypto_sw[10].ptr)
|
||||
#define X509_free (*(void (*)(X509 *))XX_httplib_crypto_sw[11].ptr)
|
||||
#define X509_get_subject_name (*(X509_NAME * (*)(X509 *))XX_httplib_crypto_sw[12].ptr)
|
||||
#define X509_get_issuer_name (*(X509_NAME * (*)(X509 *))XX_httplib_crypto_sw[13].ptr)
|
||||
#define X509_NAME_oneline \
|
||||
(*(char *(*)(X509_NAME *, char *, int))crypto_sw[14].ptr)
|
||||
#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))crypto_sw[15].ptr)
|
||||
(*(char *(*)(X509_NAME *, char *, int))XX_httplib_crypto_sw[14].ptr)
|
||||
#define X509_get_serialNumber (*(ASN1_INTEGER * (*)(X509 *))XX_httplib_crypto_sw[15].ptr)
|
||||
#define i2c_ASN1_INTEGER \
|
||||
(*(int (*)(ASN1_INTEGER *, unsigned char **))crypto_sw[16].ptr)
|
||||
(*(int (*)(ASN1_INTEGER *, unsigned char **))XX_httplib_crypto_sw[16].ptr)
|
||||
#define EVP_get_digestbyname \
|
||||
(*(const EVP_MD *(*)(const char *))crypto_sw[17].ptr)
|
||||
(*(const EVP_MD *(*)(const char *))XX_httplib_crypto_sw[17].ptr)
|
||||
#define ASN1_digest \
|
||||
(*(int (*)(int (*)(), \
|
||||
const EVP_MD *, \
|
||||
char *, \
|
||||
unsigned char *, \
|
||||
unsigned int *))crypto_sw[18].ptr)
|
||||
#define i2d_X509 (*(int (*)(X509 *, unsigned char **))crypto_sw[19].ptr)
|
||||
unsigned int *))XX_httplib_crypto_sw[18].ptr)
|
||||
#define i2d_X509 (*(int (*)(X509 *, unsigned char **))XX_httplib_crypto_sw[19].ptr)
|
||||
|
||||
#endif /* NO_SSL_DL */
|
||||
#endif /* NO_SSL */
|
||||
@@ -819,6 +819,7 @@ int XX_httplib_atomic_inc( volatile int *addr );
|
||||
int XX_httplib_check_acl( struct mg_context *ctx, uint32_t remote_ip );
|
||||
void XX_httplib_close_all_listening_sockets( struct mg_context *ctx );
|
||||
void XX_httplib_close_connection( struct mg_connection *conn );
|
||||
void XX_httplib_close_socket_gracefully( struct mg_connection *conn );
|
||||
int XX_httplib_connect_socket( struct mg_context *ctx, const char *host, int port, int use_ssl, char *ebuf, size_t ebuf_len, SOCKET *sock, union usa *sa );
|
||||
int XX_httplib_consume_socket( struct mg_context *ctx, struct socket *sp, int thread_index );
|
||||
void XX_httplib_set_close_on_exec( SOCKET sock, struct mg_connection *conn );
|
||||
@@ -894,6 +895,7 @@ void * XX_httplib_malloc( size_t a );
|
||||
|
||||
extern const struct uriprot_tp XX_httplib_abs_uri_protocols[];
|
||||
extern struct mg_option XX_httplib_config_options[];
|
||||
extern struct ssl_func XX_httplib_crypto_sw[];
|
||||
extern struct ssl_func XX_httplib_ssl_sw[];
|
||||
extern int XX_httplib_sTlsInit;
|
||||
extern pthread_key_t XX_httplib_sTlsKey;
|
||||
|
||||
@@ -517,7 +517,7 @@ struct ssl_func XX_httplib_ssl_sw[] = {{"SSL_free", NULL},
|
||||
|
||||
/* Similar array as XX_httplib_ssl_sw. These functions could be located in different
|
||||
* lib. */
|
||||
static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
|
||||
struct ssl_func XX_httplib_crypto_sw[] = {{"CRYPTO_num_locks", NULL},
|
||||
{"CRYPTO_set_locking_callback", NULL},
|
||||
{"CRYPTO_set_id_callback", NULL},
|
||||
{"ERR_get_error", NULL},
|
||||
@@ -8716,7 +8716,7 @@ static int initialize_ssl(struct mg_context *ctx) {
|
||||
|
||||
#if !defined(NO_SSL_DL)
|
||||
if (!cryptolib_dll_handle) {
|
||||
cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
|
||||
cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, XX_httplib_crypto_sw);
|
||||
if (!cryptolib_dll_handle) return 0;
|
||||
}
|
||||
#endif /* NO_SSL_DL */
|
||||
@@ -9052,7 +9052,7 @@ int XX_httplib_set_tcp_nodelay( SOCKET sock, int nodelay_on ) {
|
||||
} /* XX_httplib_set_tcp_nodelay */
|
||||
|
||||
|
||||
static void close_socket_gracefully(struct mg_connection *conn) {
|
||||
void XX_httplib_close_socket_gracefully( struct mg_connection *conn ) {
|
||||
|
||||
#if defined(_WIN32)
|
||||
char buf[MG_BUF_LEN];
|
||||
@@ -9103,76 +9103,5 @@ static void close_socket_gracefully(struct mg_connection *conn) {
|
||||
/* Now we know that our FIN is ACK-ed, safe to close */
|
||||
closesocket(conn->client.sock);
|
||||
conn->client.sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
void XX_httplib_close_connection( struct mg_connection *conn ) {
|
||||
|
||||
if (!conn || !conn->ctx) return;
|
||||
|
||||
/* call the connection_close callback if assigned */
|
||||
if ((conn->ctx->callbacks.connection_close != NULL)
|
||||
&& (conn->ctx->context_type == 1)) {
|
||||
conn->ctx->callbacks.connection_close(conn);
|
||||
}
|
||||
|
||||
mg_lock_connection(conn);
|
||||
|
||||
conn->must_close = 1;
|
||||
|
||||
#ifndef NO_SSL
|
||||
if (conn->ssl != NULL) {
|
||||
/* Run SSL_shutdown twice to ensure completly close SSL connection
|
||||
*/
|
||||
SSL_shutdown(conn->ssl);
|
||||
SSL_free(conn->ssl);
|
||||
/* Avoid CRYPTO_cleanup_all_ex_data(); See discussion:
|
||||
* https://wiki.openssl.org/index.php/Talk:Library_Initialization */
|
||||
ERR_remove_state(0);
|
||||
conn->ssl = NULL;
|
||||
}
|
||||
#endif
|
||||
if (conn->client.sock != INVALID_SOCKET) {
|
||||
close_socket_gracefully(conn);
|
||||
conn->client.sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
mg_unlock_connection(conn);
|
||||
|
||||
} /* XX_httplib_close_connection */
|
||||
|
||||
|
||||
void mg_close_connection(struct mg_connection *conn) {
|
||||
|
||||
struct mg_context *client_ctx = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (conn == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (conn->ctx->context_type == 2) {
|
||||
client_ctx = conn->ctx;
|
||||
/* client context: loops must end */
|
||||
conn->ctx->stop_flag = 1;
|
||||
}
|
||||
|
||||
#ifndef NO_SSL
|
||||
if (conn->client_ssl_ctx != NULL) {
|
||||
SSL_CTX_free((SSL_CTX *)conn->client_ssl_ctx);
|
||||
}
|
||||
#endif
|
||||
XX_httplib_close_connection(conn);
|
||||
if (client_ctx != NULL) {
|
||||
/* join worker thread and free context */
|
||||
for (i = 0; i < client_ctx->cfg_worker_threads; i++) {
|
||||
if (client_ctx->workerthreadids[i] != 0) {
|
||||
XX_httplib_join_thread(client_ctx->workerthreadids[i]);
|
||||
}
|
||||
}
|
||||
XX_httplib_free(client_ctx->workerthreadids);
|
||||
XX_httplib_free(client_ctx);
|
||||
pthread_mutex_destroy(&conn->mutex);
|
||||
XX_httplib_free(conn);
|
||||
}
|
||||
}
|
||||
} /* XX_httplib_close_socket_gracefully */
|
||||
|
||||
Reference in New Issue
Block a user