fixed a bug in ssl handling
This commit is contained in:
		| @ -286,7 +286,6 @@ struct qse_httpd_client_t | |||||||
|  |  | ||||||
| 	/* == PRIVATE == */ | 	/* == PRIVATE == */ | ||||||
| 	qse_htrd_t*              htrd; | 	qse_htrd_t*              htrd; | ||||||
| 	int                      secure; |  | ||||||
| 	int                      status; | 	int                      status; | ||||||
| 	qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX]; | 	qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX]; | ||||||
| 	qse_ntime_t              last_active; | 	qse_ntime_t              last_active; | ||||||
|  | |||||||
| @ -379,10 +379,10 @@ qse_httpd_t* qse_httpd_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) | |||||||
| 	if (httpd == QSE_NULL) return QSE_NULL; | 	if (httpd == QSE_NULL) return QSE_NULL; | ||||||
|  |  | ||||||
| 	xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); | 	xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); | ||||||
|  | 	QSE_MEMSET (xtn, 0, xtnsize); | ||||||
|  |  | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 	xtn->ssl_ctx = QSE_NULL; | 	/*init_xtn_ssl (xtn, "http01.pem", "http01.key");*/ | ||||||
| 	init_xtn_ssl (xtn, "http01.pem", "http01.key"); |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	qse_httpd_pushecb (httpd, &std_ecb); | 	qse_httpd_pushecb (httpd, &std_ecb); | ||||||
| @ -396,12 +396,23 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd) | |||||||
|  |  | ||||||
| /* ------------------------------------------------------------------- */ | /* ------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| static int sockaddr_to_nwad ( | union sockaddr_t | ||||||
| 	const struct sockaddr_storage* addr, qse_nwad_t* nwad) | { | ||||||
|  | 	struct sockaddr_in in4; | ||||||
|  | #if defined(AF_INET6) | ||||||
|  | 	struct sockaddr_in6 in6; | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef union sockaddr_t sockaddr_t; | ||||||
|  |  | ||||||
|  | #define SOCKADDR_FAMILY(x) (((struct sockaddr_in*)(x))->sin_family) | ||||||
|  |  | ||||||
|  | static int sockaddr_to_nwad (const sockaddr_t* addr, qse_nwad_t* nwad) | ||||||
| { | { | ||||||
| 	int addrsize = -1; | 	int addrsize = -1; | ||||||
|  |  | ||||||
| 	switch (addr->ss_family) | 	switch (SOCKADDR_FAMILY(addr)) | ||||||
| 	{ | 	{ | ||||||
| 		case AF_INET: | 		case AF_INET: | ||||||
| 		{ | 		{ | ||||||
| @ -436,8 +447,7 @@ static int sockaddr_to_nwad ( | |||||||
| 	return addrsize; | 	return addrsize; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int nwad_to_sockaddr ( | static int nwad_to_sockaddr (const qse_nwad_t* nwad, sockaddr_t* addr) | ||||||
| 	const qse_nwad_t* nwad, struct sockaddr_storage* addr) |  | ||||||
| { | { | ||||||
| 	int addrsize = -1; | 	int addrsize = -1; | ||||||
|  |  | ||||||
| @ -483,9 +493,7 @@ static int nwad_to_sockaddr ( | |||||||
| static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | ||||||
| { | { | ||||||
| 	int fd = -1, flag; | 	int fd = -1, flag; | ||||||
| /* TODO: if AF_INET6 is not defined sockaddr_storage is not available... | 	sockaddr_t addr; | ||||||
|  * create your own union or somehting similar... */ |  | ||||||
| 	struct sockaddr_storage addr; |  | ||||||
| 	int addrsize; | 	int addrsize; | ||||||
|  |  | ||||||
| 	addrsize = nwad_to_sockaddr (&server->nwad, &addr); | 	addrsize = nwad_to_sockaddr (&server->nwad, &addr); | ||||||
| @ -495,7 +503,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fd = socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); | 	fd = socket (SOCKADDR_FAMILY(&addr), SOCK_STREAM, IPPROTO_TCP); | ||||||
| 	if (fd <= -1) goto oops; | 	if (fd <= -1) goto oops; | ||||||
|  |  | ||||||
| 	flag = fcntl (fd, F_GETFD); | 	flag = fcntl (fd, F_GETFD); | ||||||
| @ -518,7 +526,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) | |||||||
| 	if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1) | 	if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1) | ||||||
| 	{ | 	{ | ||||||
| #if defined(IPV6_V6ONLY) | #if defined(IPV6_V6ONLY) | ||||||
| 		if (errno == EADDRINUSE && addr.ss_family == AF_INET6) | 		if (errno == EADDRINUSE && SOCKADDR_FAMILY(&addr) == AF_INET6) | ||||||
| 		{ | 		{ | ||||||
| 			int on = 1; | 			int on = 1; | ||||||
| 			setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); | 			setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); | ||||||
| @ -552,7 +560,7 @@ static int server_accept ( | |||||||
| 	qse_httpd_t* httpd, | 	qse_httpd_t* httpd, | ||||||
| 	qse_httpd_server_t* server, qse_httpd_client_t* client) | 	qse_httpd_server_t* server, qse_httpd_client_t* client) | ||||||
| { | { | ||||||
| 	struct sockaddr_storage addr; | 	sockaddr_t addr; | ||||||
|  |  | ||||||
| #ifdef HAVE_SOCKLEN_T | #ifdef HAVE_SOCKLEN_T | ||||||
| 	socklen_t addrlen; | 	socklen_t addrlen; | ||||||
| @ -619,9 +627,7 @@ qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n")); | |||||||
| static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer) | static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer) | ||||||
| { | { | ||||||
| 	int fd = -1, flag; | 	int fd = -1, flag; | ||||||
| /* TODO: if AF_INET6 is not defined sockaddr_storage is not available... | 	sockaddr_t addr; | ||||||
|  * create your own union or somehting similar... */ |  | ||||||
| 	struct sockaddr_storage addr; |  | ||||||
| 	int addrsize; | 	int addrsize; | ||||||
| 	int connected = 1; | 	int connected = 1; | ||||||
|  |  | ||||||
| @ -632,7 +638,7 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fd = socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); | 	fd = socket (SOCKADDR_FAMILY(&addr), SOCK_STREAM, IPPROTO_TCP); | ||||||
| 	if (fd <= -1) goto oops; | 	if (fd <= -1) goto oops; | ||||||
|  |  | ||||||
| 	flag = fcntl (fd, F_GETFD); | 	flag = fcntl (fd, F_GETFD); | ||||||
| @ -1093,7 +1099,7 @@ static qse_ssize_t client_recv ( | |||||||
| 	qse_httpd_t* httpd, qse_httpd_client_t* client, | 	qse_httpd_t* httpd, qse_httpd_client_t* client, | ||||||
| 	qse_mchar_t* buf, qse_size_t bufsize) | 	qse_mchar_t* buf, qse_size_t bufsize) | ||||||
| { | { | ||||||
| 	if (client->secure) | 	if (client->status & CLIENT_SECURE) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 		int ret = SSL_read (client->handle2.ptr, buf, bufsize); | 		int ret = SSL_read (client->handle2.ptr, buf, bufsize); | ||||||
| @ -1121,7 +1127,7 @@ static qse_ssize_t client_send ( | |||||||
| 	qse_httpd_t* httpd, qse_httpd_client_t* client, | 	qse_httpd_t* httpd, qse_httpd_client_t* client, | ||||||
| 	const qse_mchar_t* buf, qse_size_t bufsize) | 	const qse_mchar_t* buf, qse_size_t bufsize) | ||||||
| { | { | ||||||
| 	if (client->secure) | 	if (client->status & CLIENT_SECURE) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 		int ret = SSL_write (client->handle2.ptr, buf, bufsize); | 		int ret = SSL_write (client->handle2.ptr, buf, bufsize); | ||||||
| @ -1149,7 +1155,7 @@ static qse_ssize_t client_sendfile ( | |||||||
| 	qse_httpd_t* httpd, qse_httpd_client_t* client, | 	qse_httpd_t* httpd, qse_httpd_client_t* client, | ||||||
| 	qse_ubi_t handle, qse_foff_t* offset, qse_size_t count) | 	qse_ubi_t handle, qse_foff_t* offset, qse_size_t count) | ||||||
| { | { | ||||||
| 	if (client->secure) | 	if (client->status & CLIENT_SECURE) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 		return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count); | 		return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count); | ||||||
| @ -1167,23 +1173,27 @@ static int client_accepted (qse_httpd_t* httpd, qse_httpd_client_t* client) | |||||||
| { | { | ||||||
| 	httpd_xtn_t* xtn = (httpd_xtn_t*) qse_httpd_getxtn (httpd); | 	httpd_xtn_t* xtn = (httpd_xtn_t*) qse_httpd_getxtn (httpd); | ||||||
|  |  | ||||||
| 	if (client->secure) | 	if (client->status & CLIENT_SECURE) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 		int ret; | 		int ret; | ||||||
| 		SSL* ssl; | 		SSL* ssl; | ||||||
|  |  | ||||||
|  | 		if (!xtn->ssl_ctx) | ||||||
|  | 		{ | ||||||
|  | 			/* delayed initialization of ssl */ | ||||||
|  | 			if (init_xtn_ssl (xtn, "http01.pem", "http01.key") <= -1)  | ||||||
|  | 			{ | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 		QSE_ASSERT (xtn->ssl_ctx != QSE_NULL); | ||||||
|  |  | ||||||
| 		if (client->handle2.ptr) | 		if (client->handle2.ptr) | ||||||
| 		{ | 		{ | ||||||
| 			ssl = client->handle2.ptr; | 			ssl = client->handle2.ptr; | ||||||
| 		} | 		} | ||||||
| 		else if (!xtn->ssl_ctx) |  | ||||||
| 		{ |  | ||||||
| 			/* no ssl */ |  | ||||||
| qse_printf (QSE_T("NO SSL\n")); |  | ||||||
| qse_fflush (QSE_STDOUT); |  | ||||||
| 			return -1; |  | ||||||
| 		} |  | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			ssl = SSL_new (xtn->ssl_ctx); | 			ssl = SSL_new (xtn->ssl_ctx); | ||||||
| @ -1224,7 +1234,7 @@ qse_fflush (QSE_STDOUT); | |||||||
|  |  | ||||||
| static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client) | static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client) | ||||||
| { | { | ||||||
| 	if (client->secure) | 	if (client->status & CLIENT_SECURE) | ||||||
| 	{ | 	{ | ||||||
| #if defined(HAVE_SSL) | #if defined(HAVE_SSL) | ||||||
| 		if (client->handle2.ptr) | 		if (client->handle2.ptr) | ||||||
|  | |||||||
| @ -42,17 +42,6 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (httpd) | |||||||
| #define DEFAULT_PORT        80 | #define DEFAULT_PORT        80 | ||||||
| #define DEFAULT_SECURE_PORT 443 | #define DEFAULT_SECURE_PORT 443 | ||||||
|  |  | ||||||
| /* client->status */ |  | ||||||
| #define CLIENT_BAD                    (1 << 0) |  | ||||||
| #define CLIENT_READY                  (1 << 1) |  | ||||||
| #define CLIENT_SECURE                 (1 << 2) |  | ||||||
| #define CLIENT_MUTE                   (1 << 3) |  | ||||||
| #define CLIENT_MUTE_DELETED           (1 << 4) |  | ||||||
| #define CLIENT_HANDLE_READ_IN_MUX     (1 << 5) |  | ||||||
| #define CLIENT_HANDLE_WRITE_IN_MUX    (1 << 6) |  | ||||||
| #define CLIENT_HANDLE_IN_MUX          (CLIENT_HANDLE_READ_IN_MUX|CLIENT_HANDLE_WRITE_IN_MUX) |  | ||||||
| #define CLIENT_TASK_TRIGGER_IN_MUX(i) (1 << ((i) + 7)) |  | ||||||
|  |  | ||||||
| static void free_server_list ( | static void free_server_list ( | ||||||
| 	qse_httpd_t* httpd, qse_httpd_server_t* server); | 	qse_httpd_t* httpd, qse_httpd_server_t* server); | ||||||
| static int perform_client_task ( | static int perform_client_task ( | ||||||
| @ -316,10 +305,11 @@ static qse_httpd_client_t* new_client ( | |||||||
|  |  | ||||||
| 	qse_htrd_setoption (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH); | 	qse_htrd_setoption (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH); | ||||||
|  |  | ||||||
|  | 	client->status = tmpl->status; | ||||||
|  |  | ||||||
| 	if (httpd->scb->client.accepted == QSE_NULL)  | 	if (httpd->scb->client.accepted == QSE_NULL)  | ||||||
| 		client->status |= CLIENT_READY; | 		client->status |= CLIENT_READY; | ||||||
|  |  | ||||||
| 	client->status = tmpl->status; |  | ||||||
| 	client->handle = tmpl->handle; | 	client->handle = tmpl->handle; | ||||||
| 	client->handle2 = tmpl->handle2; | 	client->handle2 = tmpl->handle2; | ||||||
| 	client->remote_addr = tmpl->remote_addr; | 	client->remote_addr = tmpl->remote_addr; | ||||||
|  | |||||||
| @ -69,6 +69,18 @@ struct qse_httpd_t | |||||||
|  |  | ||||||
| #define MAX_SEND_SIZE 4096 | #define MAX_SEND_SIZE 4096 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* client->status */ | ||||||
|  | #define CLIENT_BAD                    (1 << 0) | ||||||
|  | #define CLIENT_READY                  (1 << 1) | ||||||
|  | #define CLIENT_SECURE                 (1 << 2) | ||||||
|  | #define CLIENT_MUTE                   (1 << 3) | ||||||
|  | #define CLIENT_MUTE_DELETED           (1 << 4) | ||||||
|  | #define CLIENT_HANDLE_READ_IN_MUX     (1 << 5) | ||||||
|  | #define CLIENT_HANDLE_WRITE_IN_MUX    (1 << 6) | ||||||
|  | #define CLIENT_HANDLE_IN_MUX          (CLIENT_HANDLE_READ_IN_MUX|CLIENT_HANDLE_WRITE_IN_MUX) | ||||||
|  | #define CLIENT_TASK_TRIGGER_IN_MUX(i) (1 << ((i) + 7)) | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user