fixed a bug in ssl handling
This commit is contained in:
parent
2179c2a88b
commit
99f1b5453b
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user