changed sockets and pipes used in httped to work in non-blocking mode
This commit is contained in:
parent
6137df4e86
commit
e8a241ed71
@ -92,7 +92,14 @@ enum qse_pio_flag_t
|
||||
/** return immediately from qse_pio_wait() if a child has not exited */
|
||||
QSE_PIO_WAITNOBLOCK = (1 << 23),
|
||||
/** do not wait again if waitpid has been interrupted */
|
||||
QSE_PIO_WAITNORETRY = (1 << 24)
|
||||
QSE_PIO_WAITNORETRY = (1 << 24),
|
||||
|
||||
/** put stdin to non-blocking mode (only on supported platforms) */
|
||||
QSE_PIO_INNOBLOCK = (1 << 25),
|
||||
/** put stdout to non-blocking mode (only on supported platforms)*/
|
||||
QSE_PIO_OUTNOBLOCK = (1 << 26),
|
||||
/** put stderr to non-blocking mode (only on supported platforms) */
|
||||
QSE_PIO_ERRNOBLOCK = (1 << 27)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -438,6 +438,26 @@ qse_mux_errnum_t qse_mux_geterrnum (qse_mux_t* mux)
|
||||
|
||||
int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt)
|
||||
{
|
||||
#if defined(USE_SELECT)
|
||||
/* nothing */
|
||||
#elif defined(USE_KQUEUE)
|
||||
struct kevent chlist[2];
|
||||
int count = 0;
|
||||
#elif defined(USE_EPOLL)
|
||||
struct epoll_event ev;
|
||||
#elif defined(__OS2__)
|
||||
/* nothing */
|
||||
#else
|
||||
/* nothing */
|
||||
#endif
|
||||
|
||||
/* sanity check */
|
||||
if (!(evt->mask & (QSE_MUX_IN | QSE_MUX_OUT)) || evt->hnd < 0)
|
||||
{
|
||||
mux->errnum = QSE_MUX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(USE_SELECT)
|
||||
|
||||
/* TODO: windows seems to return a pretty high file descriptors
|
||||
@ -482,9 +502,6 @@ int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt)
|
||||
return 0;
|
||||
|
||||
#elif defined(USE_KQUEUE)
|
||||
struct kevent chlist[2];
|
||||
int count = 0;
|
||||
|
||||
/* TODO: study if it is better to put 'evt' to the udata
|
||||
* field of chlist? */
|
||||
|
||||
@ -502,11 +519,7 @@ int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt)
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0 || evt->hnd < 0)
|
||||
{
|
||||
mux->errnum = QSE_MUX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
QSE_ASSERT (count > 0);
|
||||
|
||||
if (evt->hnd >= mux->me.ubound)
|
||||
{
|
||||
@ -550,17 +563,12 @@ int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt)
|
||||
return 0;
|
||||
|
||||
#elif defined(USE_EPOLL)
|
||||
struct epoll_event ev;
|
||||
|
||||
QSE_MEMSET (&ev, 0, QSE_SIZEOF(ev));
|
||||
if (evt->mask & QSE_MUX_IN) ev.events |= EPOLLIN;
|
||||
if (evt->mask & QSE_MUX_OUT) ev.events |= EPOLLOUT;
|
||||
|
||||
if (ev.events == 0 || evt->hnd < 0)
|
||||
{
|
||||
mux->errnum = QSE_MUX_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
QSE_ASSERT (ev.events != 0);
|
||||
|
||||
if (evt->hnd >= mux->me.ubound)
|
||||
{
|
||||
@ -937,13 +945,13 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout)
|
||||
if (mux->ee.ptr[i].events & EPOLLIN) xevt.mask |= QSE_MUX_IN;
|
||||
if (mux->ee.ptr[i].events & EPOLLOUT) xevt.mask |= QSE_MUX_OUT;
|
||||
|
||||
if (mux->ee.ptr[i].events & EPOLLHUP)
|
||||
if (mux->ee.ptr[i].events & (EPOLLHUP | EPOLLERR))
|
||||
{
|
||||
if (evt->mask & QSE_MUX_IN) xevt.mask |= QSE_MUX_IN;
|
||||
if (evt->mask & QSE_MUX_OUT) xevt.mask |= QSE_MUX_OUT;
|
||||
}
|
||||
|
||||
mux->evtfun (mux, &xevt);
|
||||
if (xevt.mask > 0) mux->evtfun (mux, &xevt);
|
||||
}
|
||||
|
||||
return nfds;
|
||||
|
@ -429,6 +429,22 @@ static int get_highest_fd (void)
|
||||
|
||||
#endif
|
||||
|
||||
static int set_pipe_nonblock (qse_pio_t* pio, qse_pio_hnd_t fd, int enabled)
|
||||
{
|
||||
#if defined(O_NONBLOCK)
|
||||
|
||||
int flag = QSE_FCNTL (fd, F_GETFL, 0);
|
||||
if (flag >= 0) flag = QSE_FCNTL (fd, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
|
||||
if (flag <= -1) pio->errnum = syserr_to_errnum (errno);
|
||||
return flag;
|
||||
|
||||
#else
|
||||
pio->errnum = QSE_PIO_ENOIMPL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int qse_pio_init (
|
||||
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd,
|
||||
qse_env_t* env, int flags)
|
||||
@ -1785,6 +1801,13 @@ create_process:
|
||||
|
||||
#endif
|
||||
|
||||
if (((flags & QSE_PIO_INNOBLOCK) && set_pipe_nonblock(pio, handle[1], 1) <= -1) ||
|
||||
((flags & QSE_PIO_OUTNOBLOCK) && set_pipe_nonblock(pio, handle[2], 1) <= -1) ||
|
||||
((flags & QSE_PIO_ERRNOBLOCK) && set_pipe_nobnlock(pio, handle[4], 1) <= -1))
|
||||
{
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* store back references */
|
||||
pio->pin[QSE_PIO_IN].self = pio;
|
||||
pio->pin[QSE_PIO_OUT].self = pio;
|
||||
@ -1795,6 +1818,7 @@ create_process:
|
||||
pio->pin[QSE_PIO_OUT].handle = handle[2];
|
||||
pio->pin[QSE_PIO_ERR].handle = handle[4];
|
||||
|
||||
|
||||
if (flags & QSE_PIO_TEXT)
|
||||
{
|
||||
int topt = 0;
|
||||
|
@ -25,6 +25,16 @@
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include <qse/cmn/path.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* nothing */
|
||||
#elif defined(__OS2__)
|
||||
/* nothing */
|
||||
#elif defined(__DOS__)
|
||||
/* nothing */
|
||||
#else
|
||||
# include "../cmn/syscall.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* TODO: remove this */
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
|
||||
# define snprintf _snprintf
|
||||
@ -104,6 +114,8 @@ struct cgi_client_req_hdr_ctx_t
|
||||
qse_env_t* env;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int cgi_capture_client_header (
|
||||
qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx)
|
||||
{
|
||||
@ -637,33 +649,14 @@ static void cgi_forward_client_input_to_script (
|
||||
/* normal forwarding */
|
||||
qse_ssize_t n;
|
||||
|
||||
if (writable) goto forward;
|
||||
|
||||
n = httpd->opt.scb.mux.writable (
|
||||
httpd, qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_IN), 0);
|
||||
if (n >= 1)
|
||||
{
|
||||
forward:
|
||||
/* writable */
|
||||
n = qse_pio_write (
|
||||
&cgi->pio, QSE_PIO_IN,
|
||||
QSE_MBS_PTR(cgi->reqfwdbuf),
|
||||
QSE_MBS_LEN(cgi->reqfwdbuf)
|
||||
);
|
||||
if (n > 0)
|
||||
{
|
||||
/* TODO: improve performance.. instead of copying the remaing part
|
||||
to the head all the time.. grow the buffer to a certain limit. */
|
||||
qse_mbs_del (cgi->reqfwdbuf, 0, n);
|
||||
if (QSE_MBS_LEN(cgi->reqfwdbuf) <= 0)
|
||||
{
|
||||
if (cgi->reqflags & CGI_REQ_GOTALL) goto done;
|
||||
else task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio write error - "));
|
||||
@ -690,6 +683,18 @@ to the head all the time.. grow the buffer to a certain limit. */
|
||||
task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||
}
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
/* TODO: improve performance.. instead of copying the remaing part
|
||||
to the head all the time.. grow the buffer to a certain limit. */
|
||||
qse_mbs_del (cgi->reqfwdbuf, 0, n);
|
||||
if (QSE_MBS_LEN(cgi->reqfwdbuf) <= 0)
|
||||
{
|
||||
if (cgi->reqflags & CGI_REQ_GOTALL) goto done;
|
||||
else task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cgi->reqflags & CGI_REQ_GOTALL)
|
||||
{
|
||||
@ -953,10 +958,18 @@ static QSE_INLINE qse_ssize_t cgi_read_script_output_to_buffer (
|
||||
&cgi->buf[cgi->buflen],
|
||||
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
||||
);
|
||||
if (n > 0) cgi->buflen += n;
|
||||
|
||||
if (n <= -1 && cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = -999;
|
||||
}
|
||||
else if (n > 0) cgi->buflen += n;
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -966,16 +979,25 @@ static QSE_INLINE qse_ssize_t cgi_write_script_output_to_client (
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
QSE_ASSERT (cgi->buflen > 0);
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, cgi->buf, cgi->buflen);
|
||||
if (n > 0)
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi write error to client - "));
|
||||
}
|
||||
else n = 0;
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
QSE_MEMCPY (&cgi->buf[0], &cgi->buf[n], cgi->buflen - n);
|
||||
cgi->buflen -= n;
|
||||
}
|
||||
|
||||
if (n <= -1 && cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi write error to client - "));
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -998,10 +1020,7 @@ static int task_main_cgi_5 (
|
||||
}
|
||||
}
|
||||
|
||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||
{
|
||||
if (cgi->buflen > 0)
|
||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ cgi->buflen > 0)
|
||||
{
|
||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1)
|
||||
{
|
||||
@ -1009,7 +1028,6 @@ static int task_main_cgi_5 (
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if forwarding didn't finish, something is not really right...
|
||||
* so long as the output from CGI is finished, no more forwarding
|
||||
@ -1042,9 +1060,21 @@ static int task_main_cgi_4_nph (
|
||||
{
|
||||
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
||||
{
|
||||
n = cgi_read_script_output_to_buffer (httpd, client, cgi);
|
||||
if (n <= -1) return -1; /* TODO: logging */
|
||||
if (n == 0)
|
||||
n = qse_pio_read (
|
||||
&cgi->pio, QSE_PIO_OUT,
|
||||
&cgi->buf[cgi->buflen],
|
||||
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* switch to the next phase */
|
||||
task->main = task_main_cgi_5;
|
||||
@ -1052,10 +1082,10 @@ static int task_main_cgi_4_nph (
|
||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
return 1;
|
||||
}
|
||||
else cgi->buflen += n;
|
||||
}
|
||||
|
||||
QSE_ASSERT (cgi->buflen > 0);
|
||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||
if (cgi->buflen > 0 && cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1109,12 +1139,15 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
count - extra
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
||||
return -1;
|
||||
}
|
||||
if (n == 0)
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* the cgi script closed the output */
|
||||
cgi->buf[cgi->buflen++] = QSE_MT('0');
|
||||
@ -1128,7 +1161,8 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* set the chunk length. if the length string is less
|
||||
* than 4 digits, the right side of the string is filled
|
||||
* with space letters. for example, the chunk length line
|
||||
@ -1159,13 +1193,26 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
||||
{
|
||||
n = cgi_read_script_output_to_buffer (httpd, client, cgi);
|
||||
if (n <= -1) return -1; /* TODO: logging */
|
||||
if (n == 0)
|
||||
n = qse_pio_read (
|
||||
&cgi->pio, QSE_PIO_OUT,
|
||||
&cgi->buf[cgi->buflen],
|
||||
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* switch to the next phase */
|
||||
task->main = task_main_cgi_5;
|
||||
@ -1173,7 +1220,8 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
cgi->script_output_received += n;
|
||||
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||
cgi->script_output_received > cgi->script_output_length)
|
||||
@ -1185,12 +1233,12 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the main loop invokes the task function only if the client
|
||||
* side is writable. it should be safe to write whenever
|
||||
* this task function is called. */
|
||||
QSE_ASSERT (cgi->buflen > 0);
|
||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||
if (cgi->buflen > 0 && cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1226,25 +1274,26 @@ printf ("task_main_cgi_3 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
|
||||
/* send the partial reponse received with the initial line and headers
|
||||
* so long as the client-side handle is writable... */
|
||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ cgi->res_left > 0)
|
||||
{
|
||||
count = MAX_SEND_SIZE;
|
||||
if (count >= cgi->res_left) count = cgi->res_left;
|
||||
count = cgi->res_left;
|
||||
if (count >= MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, cgi->res_ptr, count);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi initial write error to client - "));
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
cgi->res_ptr += n;
|
||||
cgi->res_left -= n;
|
||||
}
|
||||
|
||||
if (cgi->res_left <= 0)
|
||||
{
|
||||
@ -1270,7 +1319,7 @@ printf ("task_main_cgi_3 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 1; /* more work to do */
|
||||
@ -1319,13 +1368,16 @@ printf ("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||
{
|
||||
/* can't return internal server error any more... */
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
||||
goto oops;
|
||||
}
|
||||
if (n == 0)
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* end of output from cgi before it has seen a header.
|
||||
* the cgi script must be crooked. */
|
||||
@ -1333,8 +1385,13 @@ printf ("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
log_cgi_script_error (cgi, QSE_MT("cgi premature eof - "));
|
||||
goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi->buflen += n;
|
||||
}
|
||||
|
||||
if (cgi->buflen > 0)
|
||||
{
|
||||
if (qse_htrd_feed (cgi->script_htrd, cgi->buf, cgi->buflen) <= -1)
|
||||
{
|
||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
@ -1343,6 +1400,7 @@ printf ("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
}
|
||||
|
||||
cgi->buflen = 0;
|
||||
}
|
||||
|
||||
if (QSE_MBS_LEN(cgi->res) > 0)
|
||||
{
|
||||
@ -1410,7 +1468,11 @@ static int task_main_cgi (
|
||||
if (cgi->res == QSE_NULL) goto oops;
|
||||
}
|
||||
|
||||
pio_options = QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_MBSCMD;
|
||||
/* <<WARNING>>
|
||||
* QSE_PIO_INNOBLOCK and QSE_PIO_OUTNONBLOCK are not supported
|
||||
* on non-unix/linux platforms. so the CGI task can only be
|
||||
* used on unix/linux platforms */
|
||||
pio_options = QSE_PIO_READOUT | QSE_PIO_WRITEIN | QSE_PIO_MBSCMD | QSE_PIO_INNOBLOCK | QSE_PIO_OUTNOBLOCK;
|
||||
if (httpd->opt.trait & QSE_HTTPD_CGIERRTONUL)
|
||||
pio_options |= QSE_PIO_ERRTONUL;
|
||||
else
|
||||
@ -1446,6 +1508,7 @@ static int task_main_cgi (
|
||||
|
||||
goto oops;
|
||||
}
|
||||
|
||||
cgi->pio_inited = 1;
|
||||
|
||||
/* set the trigger that the main loop can use this
|
||||
|
@ -93,12 +93,19 @@ static int task_main_getfseg (
|
||||
count = MAX_SEND_SIZE;
|
||||
if (count >= ctx->left) count = ctx->left;
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.sendfile (
|
||||
httpd, client, ctx->handle, &ctx->offset, count);
|
||||
if (n <= -1)
|
||||
{
|
||||
/* HANDLE EGAIN specially??? */
|
||||
return -1; /* TODO: any logging */
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
/* TODO: logging */
|
||||
return -1;
|
||||
}
|
||||
|
||||
goto more_work;
|
||||
}
|
||||
|
||||
if (n == 0 && count > 0)
|
||||
@ -114,6 +121,7 @@ static int task_main_getfseg (
|
||||
ctx->left -= n;
|
||||
if (ctx->left <= 0) return 0;
|
||||
|
||||
more_work:
|
||||
return 1; /* more work to do */
|
||||
}
|
||||
|
||||
|
@ -658,8 +658,7 @@ static qse_htrd_recbs_t proxy_peer_htrd_cbs =
|
||||
proxy_htrd_handle_peer_output
|
||||
};
|
||||
|
||||
static void proxy_forward_client_input_to_peer (
|
||||
qse_httpd_t* httpd, qse_httpd_task_t* task, int writable)
|
||||
static void proxy_forward_client_input_to_peer (qse_httpd_t* httpd, qse_httpd_task_t* task)
|
||||
{
|
||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||
|
||||
@ -680,41 +679,21 @@ static void proxy_forward_client_input_to_peer (
|
||||
/* normal forwarding */
|
||||
qse_ssize_t n;
|
||||
|
||||
if (writable) goto forward;
|
||||
|
||||
n = httpd->opt.scb.mux.writable (httpd, proxy->peer.handle, 0);
|
||||
#if 0
|
||||
if (n == 0) qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@NOT WRITABLE\n"));
|
||||
#endif
|
||||
if (n >= 1)
|
||||
{
|
||||
forward:
|
||||
/* writable */
|
||||
#if 0
|
||||
qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@@WRITING[%.*hs]\n"),
|
||||
(int)QSE_MBS_LEN(proxy->reqfwdbuf),
|
||||
QSE_MBS_PTR(proxy->reqfwdbuf));
|
||||
#endif
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.peer.send (
|
||||
httpd, &proxy->peer,
|
||||
QSE_MBS_PTR(proxy->reqfwdbuf),
|
||||
QSE_MBS_LEN(proxy->reqfwdbuf)
|
||||
);
|
||||
|
||||
/* TODO: improve performance.. instead of copying the remaing part
|
||||
to the head all the time.. grow the buffer to a certain limit. */
|
||||
if (n > 0)
|
||||
{
|
||||
qse_mbs_del (proxy->reqfwdbuf, 0, n);
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
||||
{
|
||||
if (proxy->req == QSE_NULL) goto done;
|
||||
else task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy send-to-peer error - ");
|
||||
@ -732,6 +711,18 @@ to the head all the time.. grow the buffer to a certain limit. */
|
||||
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
||||
}
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
/* TODO: improve performance.. instead of copying the remaing part
|
||||
to the head all the time.. grow the buffer to a certain limit. */
|
||||
qse_mbs_del (proxy->reqfwdbuf, 0, n);
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
||||
{
|
||||
if (proxy->req == QSE_NULL) goto done;
|
||||
else task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (proxy->req == QSE_NULL)
|
||||
{
|
||||
@ -1038,6 +1029,7 @@ printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||
{
|
||||
/* if the client side is readable */
|
||||
@ -1048,23 +1040,30 @@ printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
/* if the peer side is writable while the client side is not readable*/
|
||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||
}
|
||||
#endif
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
|
||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||
{
|
||||
if (proxy->buflen > 0)
|
||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->buflen > 0)
|
||||
{
|
||||
/* wrote to the client socket as long as there's something to
|
||||
* write. it's safe to do so as the socket is non-blocking.
|
||||
* i commented out the check in the 'if' condition above */
|
||||
|
||||
/* TODO: check if proxy outputs more than content-length if it is set... */
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, proxy->buf, proxy->buflen);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
/* can't return internal server error any more... */
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
QSE_MEMCPY (&proxy->buf[0], &proxy->buf[n], proxy->buflen - n);
|
||||
proxy->buflen -= n;
|
||||
}
|
||||
@ -1087,6 +1086,8 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||
#endif
|
||||
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
/*
|
||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||
{
|
||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||
@ -1095,15 +1096,14 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
{
|
||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||
if ((task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE) &&
|
||||
proxy->buflen < QSE_SIZEOF(proxy->buf))
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
if (proxy->buflen < QSE_SIZEOF(proxy->buf))
|
||||
{
|
||||
/* reading from the peer */
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.peer.recv (
|
||||
httpd, &proxy->peer,
|
||||
@ -1113,11 +1113,16 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
if (n <= -1)
|
||||
{
|
||||
/* can't return internal server error any more... */
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy recv-from-peer error - ");
|
||||
return -1;
|
||||
}
|
||||
if (n == 0)
|
||||
|
||||
/* carry on as if recv was't called at all */
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/* peer closed connection */
|
||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||
@ -1152,7 +1157,8 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
proxy->buflen += n;
|
||||
proxy->peer_output_received += n;
|
||||
|
||||
@ -1177,22 +1183,34 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proxy->buflen)
|
||||
{
|
||||
/* the main loop invokes the task function only if the client
|
||||
* side is writable. it should be safe to write whenever
|
||||
* this task function is called. */
|
||||
* this task function is called. even if it's not writable,
|
||||
* it should still be ok as the client socket is non-blocking. */
|
||||
qse_ssize_t n;
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, proxy->buf, proxy->buflen);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
/* can't return internal server error any more... */
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
QSE_MEMCPY (&proxy->buf[0], &proxy->buf[n], proxy->buflen - n);
|
||||
proxy->buflen -= n;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1212,6 +1230,8 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||
#endif
|
||||
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
/*
|
||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||
{
|
||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||
@ -1220,34 +1240,41 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
||||
{
|
||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) &&*/ proxy->res_pending > 0)
|
||||
{
|
||||
/* the client socket is non-blocking. so attempt to send
|
||||
* so long as there's something to send regardless of writability
|
||||
* of the client socket. see the check commented out in the 'if'
|
||||
* condition above.*/
|
||||
|
||||
qse_ssize_t n;
|
||||
qse_size_t count;
|
||||
|
||||
count = proxy->res_pending;
|
||||
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (
|
||||
httpd, client,
|
||||
&QSE_MBS_CHAR(proxy->res,proxy->res_consumed),
|
||||
count
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
||||
proxy->res_consumed += n;
|
||||
proxy->res_pending -= n;
|
||||
}
|
||||
|
||||
if (proxy->res_pending <= 0)
|
||||
{
|
||||
@ -1276,6 +1303,7 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1; /* more work to do */
|
||||
}
|
||||
@ -1291,6 +1319,8 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||
#endif
|
||||
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
#if 0
|
||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||
{
|
||||
/* client is readable */
|
||||
@ -1301,19 +1331,19 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
/* client is not readable but peer is writable */
|
||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||
{
|
||||
if (proxy->res_pending > 0)
|
||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->res_pending > 0)
|
||||
{
|
||||
/* the 'if' condition becomes true only if '100 Continue'
|
||||
* is received without an actual reply in a previous call to
|
||||
* qse_htrd_feed() below. Since the actual reply is not
|
||||
* received yet, i just want to read more while realying
|
||||
* '100 Continue' to the client. this task handler is called
|
||||
* only if the client side handle is writable. i can safely
|
||||
* write to the client without a check. */
|
||||
* qse_htrd_feed() far below. Since the actual reply is not
|
||||
* received yet, i just want to read more while relaying
|
||||
* '100 Continue' to the client.
|
||||
*
|
||||
* attempt to write to the client regardless of writability of
|
||||
* the cleint socket as it is non-blocking. see the check commented
|
||||
* in the 'if' condition above. */
|
||||
|
||||
qse_ssize_t n;
|
||||
qse_size_t count;
|
||||
@ -1324,18 +1354,23 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
count = proxy->res_pending;
|
||||
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (
|
||||
httpd, client,
|
||||
QSE_MBS_CPTR(proxy->res,proxy->res_consumed),
|
||||
count
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||
goto oops;
|
||||
}
|
||||
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
||||
proxy->res_consumed += n;
|
||||
proxy->res_pending -= n;
|
||||
@ -1366,17 +1401,20 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
QSE_SIZEOF(proxy->buf) - proxy->buflen
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy recv-from-peer error - ");
|
||||
goto oops;
|
||||
}
|
||||
if (n == 0)
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
if (!(proxy->resflags & PROXY_RES_RECEIVED_RESHDR))
|
||||
{
|
||||
/* end of output from peer before it has seen a header.
|
||||
* the proxy peer must be crooked. */
|
||||
* the proxy peer must be bad. */
|
||||
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
log_proxy_error (proxy, "proxy premature eof - ");
|
||||
@ -1405,8 +1443,10 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
proxy->buflen += n;
|
||||
}
|
||||
|
||||
#if 0
|
||||
qse_printf (QSE_T("#####PROXY FEEDING %d [\n"), (int)proxy->buflen);
|
||||
@ -1416,7 +1456,8 @@ for (i = 0; i < proxy->buflen; i++) qse_printf (QSE_T("%hc"), proxy->buf[i]);
|
||||
}
|
||||
qse_printf (QSE_T("]\n"));
|
||||
#endif
|
||||
|
||||
if (proxy->buflen > 0)
|
||||
{
|
||||
if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1)
|
||||
{
|
||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||
@ -1425,6 +1466,7 @@ qse_printf (QSE_T("]\n"));
|
||||
}
|
||||
|
||||
proxy->buflen = 0;
|
||||
}
|
||||
|
||||
if (QSE_MBS_LEN(proxy->res) > 0)
|
||||
{
|
||||
@ -1530,7 +1572,7 @@ static int task_main_proxy_1 (
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||
{
|
||||
/* forward the initial part of the input to the peer */
|
||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||
{
|
||||
/* there are still more to forward in the buffer
|
||||
@ -1697,7 +1739,7 @@ static int task_main_proxy (
|
||||
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||
{
|
||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||
proxy_forward_client_input_to_peer (httpd, task);
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||
{
|
||||
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||
|
@ -135,6 +135,9 @@ static qse_httpd_errnum_t skerr_to_errnum (DWORD e)
|
||||
case WSAEINTR:
|
||||
return QSE_HTTPD_EINTR;
|
||||
|
||||
case WASEWOULDBLOCK:
|
||||
return QSE_HTTPD_EAGAIN;
|
||||
|
||||
case WSAECONNREFUSED:
|
||||
case WSAENETUNREACH:
|
||||
case WSAEHOSTUNREACH:
|
||||
@ -180,6 +183,9 @@ static qse_httpd_errnum_t skerr_to_errnum (int e)
|
||||
case SOCEPIPE:
|
||||
return QSE_HTTPD_EPIPE;
|
||||
|
||||
case SOCEAGAIN:
|
||||
return QSE_HTTPD_EAGAIN;
|
||||
|
||||
case SOCECONNREFUSED:
|
||||
case SOCENETUNREACH:
|
||||
case SOCEHOSTUNREACH:
|
||||
@ -229,6 +235,9 @@ static qse_httpd_errnum_t skerr_to_errnum (int e)
|
||||
return QSE_HTTPD_EPIPE;
|
||||
|
||||
case EAGAIN:
|
||||
#if defined(EWEOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
return QSE_HTTPD_EAGAIN;
|
||||
|
||||
#if defined(ECONNREFUSED) || defined(ENETUNREACH) || defined(EHOSTUNREACH) || defined(EHOSTDOWN)
|
||||
@ -640,13 +649,86 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd)
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#if defined(_WIN32)
|
||||
typedef SOCKET sock_t;
|
||||
# define SOCK_INIT INVALID_SOCKET
|
||||
#else
|
||||
typedef int sock_t;
|
||||
# define SOCK_INIT -1
|
||||
#endif
|
||||
#if !defined(HAVE_SOCKLEN_T)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
static QSE_INLINE int is_valid_socket (sock_t fd)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return fd != INVALID_SOCKET;
|
||||
#else
|
||||
return fd >= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static QSE_INLINE void close_socket (sock_t fd)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (fd);
|
||||
#elif defined(__OS2__)
|
||||
soclose (fd);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
QSE_CLOSE (fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int set_socket_nonblock (qse_httpd_t* httpd, sock_t fd, int enabled)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (ioctlsocket (fd, FIONBIO, &enabled) == SOCKET_ERROR)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
if (ioctl (fd, FIONBIO, (char*)&enabled, sizeof(enabled)) <= -1)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#elif defined(O_NONBLOCK)
|
||||
|
||||
int flag = fcntl (fd, F_GETFL);
|
||||
if (flag >= 0) flag = fcntl (fd, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
|
||||
if (flag <= -1)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
{
|
||||
#if defined(__DOS__)
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
||||
return -1;
|
||||
#else
|
||||
int fd = -1, flag;
|
||||
sock_t fd = SOCK_INIT, flag;
|
||||
qse_skad_t addr;
|
||||
int addrsize;
|
||||
|
||||
@ -658,7 +740,11 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
}
|
||||
|
||||
fd = socket (qse_skadfamily(&addr), SOCK_STREAM, IPPROTO_TCP);
|
||||
if (fd <= -1) goto oops;
|
||||
if (!is_valid_socket(fd))
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
flag = fcntl (fd, F_GETFD);
|
||||
@ -720,6 +806,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
|
||||
{
|
||||
/* TODO: logging ... */
|
||||
qse_httpd_seterrnum (httpd, ((len <= 0)? QSE_HTTPD_EINVAL: SKERR_TO_ERRNUM()));
|
||||
goto oops;
|
||||
}
|
||||
#endif
|
||||
@ -735,50 +822,44 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
{
|
||||
int on = 1;
|
||||
setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
||||
if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1) goto oops;
|
||||
if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
else goto oops;
|
||||
#else
|
||||
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (listen (fd, 10) <= -1) goto oops;
|
||||
if (listen (fd, 10) <= -1)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(O_NONBLOCK)
|
||||
flag = fcntl (fd, F_GETFL);
|
||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
||||
#endif
|
||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||
|
||||
server->handle.i = fd;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
#if defined(_WIN32)
|
||||
if (fd != INVALID_SOCKET) closesocket (fd);
|
||||
#elif defined(__OS2__)
|
||||
if (fd >= 0) soclose (fd);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
if (fd >= 0) QSE_CLOSE (fd);
|
||||
#endif
|
||||
if (is_valid_socket(fd)) close_socket (fd);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void server_close (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (server->handle.i);
|
||||
#elif defined(__OS2__)
|
||||
soclose (server->handle.i);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
QSE_CLOSE (server->handle.i);
|
||||
#endif
|
||||
close_socket (server->handle.i);
|
||||
}
|
||||
|
||||
static int server_accept (
|
||||
@ -790,29 +871,25 @@ static int server_accept (
|
||||
|
||||
#else
|
||||
qse_skad_t addr;
|
||||
|
||||
#if defined(HAVE_SOCKLEN_T)
|
||||
socklen_t addrlen;
|
||||
#else
|
||||
int addrlen;
|
||||
#endif
|
||||
int fd, flag;
|
||||
sock_t fd = SOCK_INIT;
|
||||
int flag;
|
||||
|
||||
addrlen = QSE_SIZEOF(addr);
|
||||
fd = accept (server->handle.i, (struct sockaddr*)&addr, &addrlen);
|
||||
if (fd <= -1)
|
||||
if (!is_valid_socket(fd))
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
return -1;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* TODO: implement maximum number of client per server??? */
|
||||
if (fd >= FD_SETSIZE)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
||||
/*TODO: qse_httpd_seterrnum (httpd, QSE_HTTPD_EXXXXX);*/
|
||||
QSE_CLOSE (fd);
|
||||
return -1;
|
||||
goto oops;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -821,10 +898,7 @@ qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
||||
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
#if defined(O_NONBLOCK)
|
||||
flag = fcntl (fd, F_GETFL);
|
||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
||||
#endif
|
||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||
|
||||
if (qse_skadtonwad (&addr, &client->remote_addr) <= -1)
|
||||
{
|
||||
@ -867,6 +941,10 @@ qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
||||
|
||||
client->handle.i = fd;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (is_valid_socket(fd)) close_socket (fd);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -885,17 +963,14 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
qse_skad_t connaddr, bindaddr;
|
||||
int connaddrsize, bindaddrsize;
|
||||
int connected = 1;
|
||||
sock_t fd = SOCK_INIT;
|
||||
#if defined(_WIN32)
|
||||
SOCKET fd = -1;
|
||||
unsigned long cmd;
|
||||
#elif defined(__OS2__)
|
||||
int fd = -1;
|
||||
int cmd;
|
||||
#elif defined(__DOS__)
|
||||
int fd = -1;
|
||||
int flag;
|
||||
#else
|
||||
int fd = -1;
|
||||
int flag;
|
||||
#endif
|
||||
|
||||
@ -908,7 +983,11 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
}
|
||||
|
||||
fd = socket (qse_skadfamily(&connaddr), SOCK_STREAM, IPPROTO_TCP);
|
||||
if (fd <= -1) goto oops;
|
||||
if (!is_valid_socket(fd))
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(IP_TRANSPARENT)
|
||||
flag = 1;
|
||||
@ -921,72 +1000,58 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
/* TODO: some logging for this failure though */
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
cmd = 1;
|
||||
if (ioctlsocket(fd, FIONBIO, &cmd) == SOCKET_ERROR) goto oops;
|
||||
|
||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) <= -1)
|
||||
{
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK) goto oops;
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
cmd = 0;
|
||||
if (ioctlsocket(fd, FIONBIO, &cmd) == SOCKET_ERROR) goto oops;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
cmd = 1;
|
||||
if (ioctl(fd, FIONBIO, (char*)&cmd, QSE_SIZEOF(cmd)) == -1) goto oops;
|
||||
|
||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) == -1)
|
||||
{
|
||||
if (sock_errno() != SOCEINPROGRESS) goto oops;
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
cmd = 0;
|
||||
if (ioctl(fd, FIONBIO, (char*)&cmd, QSE_SIZEOF(cmd)) == -1) goto oops;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
/* TODO: */
|
||||
|
||||
#else
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
flag = fcntl (fd, F_GETFD);
|
||||
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
flag = fcntl (fd, F_GETFL);
|
||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) <= -1)
|
||||
{
|
||||
if (errno != EINPROGRESS) goto oops;
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
/* restore flags */
|
||||
if (fcntl (fd, F_SETFL, flag) <= -1) goto oops;
|
||||
#elif defined(__OS2__)
|
||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) == -1)
|
||||
{
|
||||
if (sock_errno() != SOCEINPROGRESS)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
#elif defined(__DOS__)
|
||||
|
||||
/* TODO: */
|
||||
|
||||
#else
|
||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) <= -1)
|
||||
{
|
||||
if (errno != EINPROGRESS)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*if (set_socket_nonblock (httpd, fd, 0) <= -1) goto oops;*/
|
||||
|
||||
peer->handle.i = fd;
|
||||
return connected;
|
||||
|
||||
oops:
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
#if defined(_WIN32)
|
||||
if (fd != INVALID_SOCKET) closesocket (fd);
|
||||
#elif defined(__OS2__)
|
||||
if (fd >= 0) soclose (fd);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
if (fd >= 0) QSE_CLOSE (fd);
|
||||
#endif
|
||||
if (is_valid_socket(fd)) close_socket (fd);
|
||||
return -1;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@ -995,15 +1060,7 @@ oops:
|
||||
|
||||
static void peer_close (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (peer->handle.i);
|
||||
#elif defined(__OS2__)
|
||||
soclose (peer->handle.i);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
QSE_CLOSE (peer->handle.i);
|
||||
#endif
|
||||
close_socket (peer->handle.i);
|
||||
}
|
||||
|
||||
static int peer_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
@ -1057,11 +1114,7 @@ static int peer_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||
|
||||
#else
|
||||
|
||||
#if defined(HAVE_SOCKLEN_T)
|
||||
socklen_t len;
|
||||
#else
|
||||
int len;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
len = QSE_SIZEOF(ret);
|
||||
@ -1747,26 +1800,22 @@ static int dir_read (qse_httpd_t* httpd, qse_ubi_t handle, qse_httpd_dirent_t* d
|
||||
# define SHUT_RDWR 2
|
||||
#endif
|
||||
|
||||
static void client_close (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||
static void client_close (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||
{
|
||||
|
||||
#if defined(_WIN32)
|
||||
shutdown (client->handle.i, SHUT_RDWR);
|
||||
closesocket (client->handle.i);
|
||||
#elif defined(__OS2__)
|
||||
shutdown (client->handle.i, SHUT_RDWR);
|
||||
soclose (client->handle.i);
|
||||
#elif defined(__DOS__)
|
||||
/* TODO: */
|
||||
#else
|
||||
shutdown (client->handle.i, SHUT_RDWR);
|
||||
QSE_CLOSE (client->handle.i);
|
||||
#endif
|
||||
close_socket (client->handle.i);
|
||||
}
|
||||
|
||||
static void client_shutdown (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||
static void client_shutdown (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
shutdown (client->handle.i, SHUT_RDWR);
|
||||
@ -2201,7 +2250,8 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
||||
return -1;
|
||||
#else
|
||||
int fd = -1, flag;
|
||||
sock_t fd = SOCK_INIT;
|
||||
int flag;
|
||||
qse_nwad_t nwad;
|
||||
dns_ctx_t* dc;
|
||||
httpd_xtn_t* httpd_xtn;
|
||||
@ -2276,7 +2326,11 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
}
|
||||
|
||||
fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd <= -1) goto oops;
|
||||
if (!is_valid_socket(fd))
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
flag = fcntl (fd, F_GETFD);
|
||||
@ -2293,22 +2347,14 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag));
|
||||
#endif
|
||||
|
||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||
|
||||
dns->handle.i = fd;
|
||||
dns->ctx = dc;
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (fd >= 0)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
closesocket (fd);
|
||||
#elif defined(__OS2__)
|
||||
soclose (fd);
|
||||
#else
|
||||
QSE_CLOSE (fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (is_valid_socket(fd)) close_socket (fd);
|
||||
if (dc) qse_httpd_freemem (httpd, dc);
|
||||
return -1;
|
||||
|
||||
@ -2447,7 +2493,7 @@ static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||
|
||||
qse_skad_t fromaddr;
|
||||
socklen_t fromlen; /* TODO: change type */
|
||||
socklen_t fromlen;
|
||||
|
||||
qse_uint8_t buf[DNS_MAX_MSG_LEN];
|
||||
qse_ssize_t len;
|
||||
@ -2614,16 +2660,13 @@ static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t
|
||||
qse_size_t name_len;
|
||||
dns_ans_t* ans;
|
||||
|
||||
printf ("finding answer in cache...\n");
|
||||
ans = dns_get_answer_from_cache (dc, name);
|
||||
if (ans)
|
||||
{
|
||||
printf ("found answer in cache...\n");
|
||||
resol (httpd, name, ((ans->nwad.type == QSE_NWAD_NX)? QSE_NULL: &ans->nwad), ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf ("found XXXXX in cache...\n");
|
||||
seq = dc->seq;
|
||||
seq = (seq + 1) % QSE_COUNTOF(dc->reqs);
|
||||
dc->seq = seq;
|
||||
|
@ -90,13 +90,19 @@ static int task_main_format (
|
||||
count = MAX_SEND_SIZE;
|
||||
if (count >= ctx->left) count = ctx->left;
|
||||
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, ctx->ptr, count);
|
||||
if (n <= -1) return -1;
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN) return -1;
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
ctx->left -= n;
|
||||
if (ctx->left <= 0) return 0;
|
||||
|
||||
ctx->ptr += n;
|
||||
}
|
||||
|
||||
return 1; /* more work to do */
|
||||
}
|
||||
|
||||
|
@ -53,13 +53,18 @@ static int task_main_text (
|
||||
if (count >= ctx->left) count = ctx->left;
|
||||
|
||||
/* TODO: do i need to add code to skip this send if count is 0? */
|
||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||
n = httpd->opt.scb.client.send (httpd, client, ctx->ptr, count);
|
||||
if (n <= -1) return -1;
|
||||
|
||||
if (n <= -1)
|
||||
{
|
||||
if (httpd->errnum != QSE_HTTPD_EAGAIN) return -1;
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
ctx->left -= n;
|
||||
if (ctx->left <= 0) return 0;
|
||||
|
||||
ctx->ptr += n;
|
||||
}
|
||||
return 1; /* more work to do */
|
||||
}
|
||||
|
||||
|
@ -921,7 +921,7 @@ static int update_mux_for_current_task (qse_httpd_t* httpd, qse_httpd_client_t*
|
||||
{
|
||||
/* active to inactive */
|
||||
|
||||
printf ("ACTIVE TO INACTIVE....\n");
|
||||
/*printf ("ACTIVE TO INACTIVE....\n");*/
|
||||
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||
{
|
||||
if (client->status & CLIENT_TASK_TRIGGER_RW_IN_MUX(i))
|
||||
@ -942,21 +942,21 @@ printf ("ACTIVE TO INACTIVE....\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf ("INACTIVE TO ACTIVE....\n");
|
||||
/*printf ("INACTIVE TO ACTIVE....\n");*/
|
||||
/* inactive to active . go on*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if (task->trigger.flags & QSE_HTTPD_TASK_TRIGGER_INACTIVE)
|
||||
{
|
||||
printf ("INACTIVE TO INACTIVE....\n");
|
||||
/*printf ("INACTIVE TO INACTIVE....\n");*/
|
||||
/* inactive to inactive.
|
||||
* save the trigger as the trigger handle and masks could change */
|
||||
client->trigger = task->trigger;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf ("ACTIVE TO ACTIVE....\n");
|
||||
/*printf ("ACTIVE TO ACTIVE....\n");*/
|
||||
/* active to active. go on */
|
||||
}
|
||||
|
||||
@ -1183,13 +1183,23 @@ static int invoke_client_task (
|
||||
{
|
||||
if (mask & QSE_HTTPD_MUX_READ)
|
||||
{
|
||||
QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_READ);
|
||||
/*QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_READ);*/
|
||||
/* the assertion above may be false if a task for the same
|
||||
* trigger set was called earlier by a qse_mux_poll() call.
|
||||
* and the task has changed some masks.
|
||||
*
|
||||
* for instance, you put handle A and B in to a trigger.
|
||||
* if the task is triggered for A but the task may change
|
||||
* the mask for B. the task may get executed for B by
|
||||
* the same qse_mux_poll() call.
|
||||
*/
|
||||
|
||||
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_READABLE;
|
||||
trigger_fired = 1;
|
||||
}
|
||||
if (mask & QSE_HTTPD_MUX_WRITE)
|
||||
{
|
||||
QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE);
|
||||
/*QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE);*/
|
||||
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_WRITABLE;
|
||||
trigger_fired = 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user