changed sockets and pipes used in httped to work in non-blocking mode
This commit is contained in:
parent
6137df4e86
commit
e8a241ed71
@ -39,7 +39,7 @@ enum qse_pio_flag_t
|
|||||||
{
|
{
|
||||||
/** enable text based I/O. */
|
/** enable text based I/O. */
|
||||||
QSE_PIO_TEXT = (1 << 0),
|
QSE_PIO_TEXT = (1 << 0),
|
||||||
QSE_PIO_IGNOREMBWCERR = (1 << 1),
|
QSE_PIO_IGNOREMBWCERR = (1 << 1),
|
||||||
QSE_PIO_NOAUTOFLUSH = (1 << 2),
|
QSE_PIO_NOAUTOFLUSH = (1 << 2),
|
||||||
|
|
||||||
/** execute the command via a system shell
|
/** execute the command via a system shell
|
||||||
@ -92,7 +92,14 @@ enum qse_pio_flag_t
|
|||||||
/** return immediately from qse_pio_wait() if a child has not exited */
|
/** return immediately from qse_pio_wait() if a child has not exited */
|
||||||
QSE_PIO_WAITNOBLOCK = (1 << 23),
|
QSE_PIO_WAITNOBLOCK = (1 << 23),
|
||||||
/** do not wait again if waitpid has been interrupted */
|
/** 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)
|
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)
|
#if defined(USE_SELECT)
|
||||||
|
|
||||||
/* TODO: windows seems to return a pretty high file descriptors
|
/* 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;
|
return 0;
|
||||||
|
|
||||||
#elif defined(USE_KQUEUE)
|
#elif defined(USE_KQUEUE)
|
||||||
struct kevent chlist[2];
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
/* TODO: study if it is better to put 'evt' to the udata
|
/* TODO: study if it is better to put 'evt' to the udata
|
||||||
* field of chlist? */
|
* field of chlist? */
|
||||||
|
|
||||||
@ -502,11 +519,7 @@ int qse_mux_insert (qse_mux_t* mux, const qse_mux_evt_t* evt)
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0 || evt->hnd < 0)
|
QSE_ASSERT (count > 0);
|
||||||
{
|
|
||||||
mux->errnum = QSE_MUX_EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evt->hnd >= mux->me.ubound)
|
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;
|
return 0;
|
||||||
|
|
||||||
#elif defined(USE_EPOLL)
|
#elif defined(USE_EPOLL)
|
||||||
struct epoll_event ev;
|
|
||||||
|
|
||||||
QSE_MEMSET (&ev, 0, QSE_SIZEOF(ev));
|
QSE_MEMSET (&ev, 0, QSE_SIZEOF(ev));
|
||||||
if (evt->mask & QSE_MUX_IN) ev.events |= EPOLLIN;
|
if (evt->mask & QSE_MUX_IN) ev.events |= EPOLLIN;
|
||||||
if (evt->mask & QSE_MUX_OUT) ev.events |= EPOLLOUT;
|
if (evt->mask & QSE_MUX_OUT) ev.events |= EPOLLOUT;
|
||||||
|
|
||||||
if (ev.events == 0 || evt->hnd < 0)
|
QSE_ASSERT (ev.events != 0);
|
||||||
{
|
|
||||||
mux->errnum = QSE_MUX_EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evt->hnd >= mux->me.ubound)
|
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 & EPOLLIN) xevt.mask |= QSE_MUX_IN;
|
||||||
if (mux->ee.ptr[i].events & EPOLLOUT) xevt.mask |= QSE_MUX_OUT;
|
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_IN) xevt.mask |= QSE_MUX_IN;
|
||||||
if (evt->mask & QSE_MUX_OUT) xevt.mask |= QSE_MUX_OUT;
|
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;
|
return nfds;
|
||||||
|
@ -429,6 +429,22 @@ static int get_highest_fd (void)
|
|||||||
|
|
||||||
#endif
|
#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 (
|
int qse_pio_init (
|
||||||
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd,
|
qse_pio_t* pio, qse_mmgr_t* mmgr, const qse_char_t* cmd,
|
||||||
qse_env_t* env, int flags)
|
qse_env_t* env, int flags)
|
||||||
@ -1785,6 +1801,13 @@ create_process:
|
|||||||
|
|
||||||
#endif
|
#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 */
|
/* store back references */
|
||||||
pio->pin[QSE_PIO_IN].self = pio;
|
pio->pin[QSE_PIO_IN].self = pio;
|
||||||
pio->pin[QSE_PIO_OUT].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_OUT].handle = handle[2];
|
||||||
pio->pin[QSE_PIO_ERR].handle = handle[4];
|
pio->pin[QSE_PIO_ERR].handle = handle[4];
|
||||||
|
|
||||||
|
|
||||||
if (flags & QSE_PIO_TEXT)
|
if (flags & QSE_PIO_TEXT)
|
||||||
{
|
{
|
||||||
int topt = 0;
|
int topt = 0;
|
||||||
@ -1882,17 +1906,17 @@ oops:
|
|||||||
}
|
}
|
||||||
for (i = minidx; i < maxidx; i++)
|
for (i = minidx; i < maxidx; i++)
|
||||||
{
|
{
|
||||||
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
||||||
}
|
}
|
||||||
#elif defined(QSE_SYSCALL0) && defined(SYS_vfork)
|
#elif defined(QSE_SYSCALL0) && defined(SYS_vfork)
|
||||||
for (i = minidx; i < maxidx; i++)
|
for (i = minidx; i < maxidx; i++)
|
||||||
{
|
{
|
||||||
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (i = minidx; i < maxidx; i++)
|
for (i = minidx; i < maxidx; i++)
|
||||||
{
|
{
|
||||||
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
if (handle[i] != QSE_PIO_HND_NIL) QSE_CLOSE (handle[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -25,6 +25,16 @@
|
|||||||
#include <qse/cmn/fmt.h>
|
#include <qse/cmn/fmt.h>
|
||||||
#include <qse/cmn/path.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 */
|
#include <stdio.h> /* TODO: remove this */
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
|
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
@ -104,6 +114,8 @@ struct cgi_client_req_hdr_ctx_t
|
|||||||
qse_env_t* env;
|
qse_env_t* env;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int cgi_capture_client_header (
|
static int cgi_capture_client_header (
|
||||||
qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx)
|
qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx)
|
||||||
{
|
{
|
||||||
@ -637,57 +649,50 @@ static void cgi_forward_client_input_to_script (
|
|||||||
/* normal forwarding */
|
/* normal forwarding */
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
if (writable) goto forward;
|
n = qse_pio_write (
|
||||||
|
&cgi->pio, QSE_PIO_IN,
|
||||||
n = httpd->opt.scb.mux.writable (
|
QSE_MBS_PTR(cgi->reqfwdbuf),
|
||||||
httpd, qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_IN), 0);
|
QSE_MBS_LEN(cgi->reqfwdbuf)
|
||||||
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 (n <= -1)
|
||||||
{
|
{
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi pio write error - "));
|
|
||||||
|
|
||||||
cgi->reqflags |= CGI_REQ_FWDERR;
|
|
||||||
qse_mbs_clear (cgi->reqfwdbuf);
|
|
||||||
|
|
||||||
if (!(cgi->reqflags & CGI_REQ_GOTALL))
|
|
||||||
{
|
{
|
||||||
QSE_ASSERT (cgi->req);
|
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
qse_htre_discardcontent (cgi->req);
|
log_cgi_script_error (cgi, QSE_MT("cgi pio write error - "));
|
||||||
|
|
||||||
/* NOTE:
|
cgi->reqflags |= CGI_REQ_FWDERR;
|
||||||
* this qse_htre_discardcontent() invokes
|
qse_mbs_clear (cgi->reqfwdbuf);
|
||||||
* cgi_snatch_client_input()
|
|
||||||
* which sets cgi->req to QSE_NULL
|
if (!(cgi->reqflags & CGI_REQ_GOTALL))
|
||||||
* and toggles on CGI_REQ_GOTALL. */
|
{
|
||||||
QSE_ASSERT (!cgi->req);
|
QSE_ASSERT (cgi->req);
|
||||||
QSE_ASSERT (cgi->reqflags & CGI_REQ_GOTALL);
|
qse_htre_discardcontent (cgi->req);
|
||||||
|
|
||||||
|
/* NOTE:
|
||||||
|
* this qse_htre_discardcontent() invokes
|
||||||
|
* cgi_snatch_client_input()
|
||||||
|
* which sets cgi->req to QSE_NULL
|
||||||
|
* and toggles on CGI_REQ_GOTALL. */
|
||||||
|
QSE_ASSERT (!cgi->req);
|
||||||
|
QSE_ASSERT (cgi->reqflags & CGI_REQ_GOTALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark the end of input to the child explicitly. */
|
||||||
|
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
||||||
|
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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark the end of input to the child explicitly. */
|
|
||||||
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
|
||||||
task->trigger.v[1].mask = 0; /* pipe output to child */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,10 +958,18 @@ static QSE_INLINE qse_ssize_t cgi_read_script_output_to_buffer (
|
|||||||
&cgi->buf[cgi->buflen],
|
&cgi->buf[cgi->buflen],
|
||||||
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
QSE_SIZEOF(cgi->buf) - cgi->buflen
|
||||||
);
|
);
|
||||||
if (n > 0) cgi->buflen += n;
|
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 <= -1 && cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
n = -999;
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
}
|
||||||
|
else if (n > 0) cgi->buflen += n;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -966,16 +979,25 @@ static QSE_INLINE qse_ssize_t cgi_write_script_output_to_client (
|
|||||||
{
|
{
|
||||||
qse_ssize_t n;
|
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);
|
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);
|
QSE_MEMCPY (&cgi->buf[0], &cgi->buf[n], cgi->buflen - 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;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,16 +1020,12 @@ static int task_main_cgi_5 (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ cgi->buflen > 0)
|
||||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
|
||||||
{
|
{
|
||||||
if (cgi->buflen > 0)
|
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1)
|
||||||
{
|
{
|
||||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1)
|
/* can't return internal server error any more... */
|
||||||
{
|
return -1;
|
||||||
/* can't return internal server error any more... */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,9 +1060,21 @@ static int task_main_cgi_4_nph (
|
|||||||
{
|
{
|
||||||
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
||||||
{
|
{
|
||||||
n = cgi_read_script_output_to_buffer (httpd, client, cgi);
|
n = qse_pio_read (
|
||||||
if (n <= -1) return -1; /* TODO: logging */
|
&cgi->pio, QSE_PIO_OUT,
|
||||||
if (n == 0)
|
&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 */
|
/* switch to the next phase */
|
||||||
task->main = task_main_cgi_5;
|
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;
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else cgi->buflen += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_ASSERT (cgi->buflen > 0);
|
if (cgi->buflen > 0 && cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1110,11 +1140,14 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
);
|
);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (qse_pio_geterrnum(&cgi->pio) != QSE_PIO_EAGAIN)
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi pio read error - "));
|
{
|
||||||
return -1;
|
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 */
|
/* the cgi script closed the output */
|
||||||
cgi->buf[cgi->buflen++] = QSE_MT('0');
|
cgi->buf[cgi->buflen++] = QSE_MT('0');
|
||||||
@ -1128,34 +1161,36 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
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
|
|
||||||
* for the length 10 will be "A \r\n". */
|
|
||||||
cgi->buflen += qse_fmtuintmaxtombs (
|
|
||||||
&cgi->buf[cgi->buflen], CHLEN_RESERVE - 2 + 1,
|
|
||||||
n, 16 | QSE_FMTUINTMAXTOMBS_UPPERCASE | QSE_FMTUINTMAXTOMBS_FILLRIGHT,
|
|
||||||
-1, QSE_MT(' '), QSE_NULL
|
|
||||||
);
|
|
||||||
cgi->buf[cgi->buflen++] = QSE_MT('\r');
|
|
||||||
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
|
||||||
|
|
||||||
cgi->buflen += n; /* +n for the data read above */
|
|
||||||
|
|
||||||
/* set the trailing CR & LF for a chunk */
|
|
||||||
cgi->buf[cgi->buflen++] = QSE_MT('\r');
|
|
||||||
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
|
||||||
|
|
||||||
cgi->script_output_received += n;
|
|
||||||
|
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
|
||||||
cgi->script_output_received > cgi->script_output_length)
|
|
||||||
{
|
{
|
||||||
/* cgi returning too much data... something is wrong in CGI */
|
/* set the chunk length. if the length string is less
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
* than 4 digits, the right side of the string is filled
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi redundant output - "));
|
* with space letters. for example, the chunk length line
|
||||||
return -1;
|
* for the length 10 will be "A \r\n". */
|
||||||
|
cgi->buflen += qse_fmtuintmaxtombs (
|
||||||
|
&cgi->buf[cgi->buflen], CHLEN_RESERVE - 2 + 1,
|
||||||
|
n, 16 | QSE_FMTUINTMAXTOMBS_UPPERCASE | QSE_FMTUINTMAXTOMBS_FILLRIGHT,
|
||||||
|
-1, QSE_MT(' '), QSE_NULL
|
||||||
|
);
|
||||||
|
cgi->buf[cgi->buflen++] = QSE_MT('\r');
|
||||||
|
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
||||||
|
|
||||||
|
cgi->buflen += n; /* +n for the data read above */
|
||||||
|
|
||||||
|
/* set the trailing CR & LF for a chunk */
|
||||||
|
cgi->buf[cgi->buflen++] = QSE_MT('\r');
|
||||||
|
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
||||||
|
|
||||||
|
cgi->script_output_received += n;
|
||||||
|
|
||||||
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
|
cgi->script_output_received > cgi->script_output_length)
|
||||||
|
{
|
||||||
|
/* cgi returning too much data... something is wrong in CGI */
|
||||||
|
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
|
log_cgi_script_error (cgi, QSE_MT("cgi redundant output - "));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1163,9 +1198,21 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
{
|
{
|
||||||
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
||||||
{
|
{
|
||||||
n = cgi_read_script_output_to_buffer (httpd, client, cgi);
|
n = qse_pio_read (
|
||||||
if (n <= -1) return -1; /* TODO: logging */
|
&cgi->pio, QSE_PIO_OUT,
|
||||||
if (n == 0)
|
&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 */
|
/* switch to the next phase */
|
||||||
task->main = task_main_cgi_5;
|
task->main = task_main_cgi_5;
|
||||||
@ -1173,15 +1220,17 @@ printf ("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
cgi->script_output_received += n;
|
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
|
||||||
cgi->script_output_received > cgi->script_output_length)
|
|
||||||
{
|
{
|
||||||
/* cgi returning too much data... something is wrong in CGI */
|
cgi->script_output_received += n;
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi redundant output - "));
|
cgi->script_output_received > cgi->script_output_length)
|
||||||
return -1;
|
{
|
||||||
|
/* cgi returning too much data... something is wrong in CGI */
|
||||||
|
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
|
log_cgi_script_error (cgi, QSE_MT("cgi redundant output - "));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1189,8 +1238,7 @@ 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
|
/* the main loop invokes the task function only if the client
|
||||||
* side is writable. it should be safe to write whenever
|
* side is writable. it should be safe to write whenever
|
||||||
* this task function is called. */
|
* this task function is called. */
|
||||||
QSE_ASSERT (cgi->buflen > 0);
|
if (cgi->buflen > 0 && cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
||||||
if (cgi_write_script_output_to_client (httpd, client, cgi) <= -1) return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1226,51 +1274,52 @@ 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
|
/* send the partial reponse received with the initial line and headers
|
||||||
* so long as the client-side handle is writable... */
|
* so long as the client-side handle is writable... */
|
||||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ cgi->res_left > 0)
|
||||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
|
||||||
{
|
{
|
||||||
count = MAX_SEND_SIZE;
|
count = cgi->res_left;
|
||||||
if (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)
|
||||||
{
|
{
|
||||||
n = httpd->opt.scb.client.send (httpd, client, cgi->res_ptr, count);
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
if (n <= -1)
|
|
||||||
{
|
{
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi initial write error to client - "));
|
log_cgi_script_error (cgi, QSE_MT("cgi initial write error to client - "));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (n > 0)
|
||||||
|
{
|
||||||
cgi->res_ptr += n;
|
cgi->res_ptr += n;
|
||||||
cgi->res_left -= n;
|
cgi->res_left -= n;
|
||||||
}
|
|
||||||
|
|
||||||
if (cgi->res_left <= 0)
|
if (cgi->res_left <= 0)
|
||||||
{
|
|
||||||
qse_mbs_clear (cgi->res);
|
|
||||||
|
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
|
||||||
cgi->script_output_received >= cgi->script_output_length)
|
|
||||||
{
|
{
|
||||||
/* if a cgi script specified the content length
|
qse_mbs_clear (cgi->res);
|
||||||
* and it has emitted as much as the length,
|
|
||||||
* i don't wait for the script to finish.
|
|
||||||
* one potential side-effect is that the script
|
|
||||||
* can be killed prematurely if it wants to do
|
|
||||||
* something extra after having done so.
|
|
||||||
* however, a CGI script shouln't do that... */
|
|
||||||
task->main = task_main_cgi_5;
|
|
||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task->main = task_main_cgi_4;
|
|
||||||
task->trigger.cmask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
|
cgi->script_output_received >= cgi->script_output_length)
|
||||||
|
{
|
||||||
|
/* if a cgi script specified the content length
|
||||||
|
* and it has emitted as much as the length,
|
||||||
|
* i don't wait for the script to finish.
|
||||||
|
* one potential side-effect is that the script
|
||||||
|
* can be killed prematurely if it wants to do
|
||||||
|
* something extra after having done so.
|
||||||
|
* however, a CGI script shouln't do that... */
|
||||||
|
task->main = task_main_cgi_5;
|
||||||
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
task->main = task_main_cgi_4;
|
||||||
|
task->trigger.cmask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* more work to do */
|
return 1; /* more work to do */
|
||||||
@ -1320,12 +1369,15 @@ printf ("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
);
|
);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
/* can't return internal server error any more... */
|
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 - "));
|
/* can't return internal server error any more... */
|
||||||
goto oops;
|
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.
|
/* end of output from cgi before it has seen a header.
|
||||||
* the cgi script must be crooked. */
|
* the cgi script must be crooked. */
|
||||||
@ -1333,16 +1385,22 @@ 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 - "));
|
log_cgi_script_error (cgi, QSE_MT("cgi premature eof - "));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
cgi->buflen += n;
|
else
|
||||||
|
|
||||||
if (qse_htrd_feed (cgi->script_htrd, cgi->buf, cgi->buflen) <= -1)
|
|
||||||
{
|
{
|
||||||
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
cgi->buflen += n;
|
||||||
log_cgi_script_error (cgi, QSE_MT("cgi feed error - "));
|
|
||||||
goto oops;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cgi->buflen = 0;
|
if (cgi->buflen > 0)
|
||||||
|
{
|
||||||
|
if (qse_htrd_feed (cgi->script_htrd, cgi->buf, cgi->buflen) <= -1)
|
||||||
|
{
|
||||||
|
if (cgi->httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
|
log_cgi_script_error (cgi, QSE_MT("cgi feed error - "));
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
cgi->buflen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (QSE_MBS_LEN(cgi->res) > 0)
|
if (QSE_MBS_LEN(cgi->res) > 0)
|
||||||
{
|
{
|
||||||
@ -1410,7 +1468,11 @@ static int task_main_cgi (
|
|||||||
if (cgi->res == QSE_NULL) goto oops;
|
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)
|
if (httpd->opt.trait & QSE_HTTPD_CGIERRTONUL)
|
||||||
pio_options |= QSE_PIO_ERRTONUL;
|
pio_options |= QSE_PIO_ERRTONUL;
|
||||||
else
|
else
|
||||||
@ -1446,6 +1508,7 @@ static int task_main_cgi (
|
|||||||
|
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgi->pio_inited = 1;
|
cgi->pio_inited = 1;
|
||||||
|
|
||||||
/* set the trigger that the main loop can use this
|
/* set the trigger that the main loop can use this
|
||||||
|
@ -93,12 +93,19 @@ static int task_main_getfseg (
|
|||||||
count = MAX_SEND_SIZE;
|
count = MAX_SEND_SIZE;
|
||||||
if (count >= ctx->left) count = ctx->left;
|
if (count >= ctx->left) count = ctx->left;
|
||||||
|
|
||||||
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
n = httpd->opt.scb.client.sendfile (
|
n = httpd->opt.scb.client.sendfile (
|
||||||
httpd, client, ctx->handle, &ctx->offset, count);
|
httpd, client, ctx->handle, &ctx->offset, count);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
/* HANDLE EGAIN specially??? */
|
/* 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)
|
if (n == 0 && count > 0)
|
||||||
@ -114,6 +121,7 @@ static int task_main_getfseg (
|
|||||||
ctx->left -= n;
|
ctx->left -= n;
|
||||||
if (ctx->left <= 0) return 0;
|
if (ctx->left <= 0) return 0;
|
||||||
|
|
||||||
|
more_work:
|
||||||
return 1; /* more work to do */
|
return 1; /* more work to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,8 +658,7 @@ static qse_htrd_recbs_t proxy_peer_htrd_cbs =
|
|||||||
proxy_htrd_handle_peer_output
|
proxy_htrd_handle_peer_output
|
||||||
};
|
};
|
||||||
|
|
||||||
static void proxy_forward_client_input_to_peer (
|
static void proxy_forward_client_input_to_peer (qse_httpd_t* httpd, qse_httpd_task_t* task)
|
||||||
qse_httpd_t* httpd, qse_httpd_task_t* task, int writable)
|
|
||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
@ -680,56 +679,48 @@ static void proxy_forward_client_input_to_peer (
|
|||||||
/* normal forwarding */
|
/* normal forwarding */
|
||||||
qse_ssize_t n;
|
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
|
#if 0
|
||||||
qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@@WRITING[%.*hs]\n"),
|
qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@@WRITING[%.*hs]\n"),
|
||||||
(int)QSE_MBS_LEN(proxy->reqfwdbuf),
|
(int)QSE_MBS_LEN(proxy->reqfwdbuf),
|
||||||
QSE_MBS_PTR(proxy->reqfwdbuf));
|
QSE_MBS_PTR(proxy->reqfwdbuf));
|
||||||
#endif
|
#endif
|
||||||
n = httpd->opt.scb.peer.send (
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
httpd, &proxy->peer,
|
n = httpd->opt.scb.peer.send (
|
||||||
QSE_MBS_PTR(proxy->reqfwdbuf),
|
httpd, &proxy->peer,
|
||||||
QSE_MBS_LEN(proxy->reqfwdbuf)
|
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 (n <= -1)
|
||||||
{
|
{
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
log_proxy_error (proxy, "proxy send-to-peer error - ");
|
|
||||||
|
|
||||||
proxy->reqflags |= PROXY_REQ_FWDERR;
|
|
||||||
qse_mbs_clear (proxy->reqfwdbuf);
|
|
||||||
if (proxy->req)
|
|
||||||
{
|
{
|
||||||
qse_htre_discardcontent (proxy->req);
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
/* NOTE: proxy->req may be set to QSE_NULL
|
log_proxy_error (proxy, "proxy send-to-peer error - ");
|
||||||
* in proxy_snatch_client_input() triggered by
|
|
||||||
* qse_htre_discardcontent() */
|
|
||||||
}
|
|
||||||
|
|
||||||
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
proxy->reqflags |= PROXY_REQ_FWDERR;
|
||||||
|
qse_mbs_clear (proxy->reqfwdbuf);
|
||||||
|
if (proxy->req)
|
||||||
|
{
|
||||||
|
qse_htre_discardcontent (proxy->req);
|
||||||
|
/* NOTE: proxy->req may be set to QSE_NULL
|
||||||
|
* in proxy_snatch_client_input() triggered by
|
||||||
|
* qse_htre_discardcontent() */
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
/* if the client side is 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*/
|
/* if the peer side is writable while the client side is not readable*/
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
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) ||*/
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->buflen > 0)
|
||||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
|
||||||
{
|
{
|
||||||
if (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.
|
||||||
/* TODO: check if proxy outputs more than content-length if it is set... */
|
* i commented out the check in the 'if' condition above */
|
||||||
|
|
||||||
n = httpd->opt.scb.client.send (httpd, client, proxy->buf, proxy->buflen);
|
/* TODO: check if proxy outputs more than content-length if it is set... */
|
||||||
if (n <= -1)
|
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... */
|
/* can't return internal server error any more... */
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (n > 0)
|
||||||
|
{
|
||||||
QSE_MEMCPY (&proxy->buf[0], &proxy->buf[n], proxy->buflen - n);
|
QSE_MEMCPY (&proxy->buf[0], &proxy->buf[n], proxy->buflen - 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);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
|
/*
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
@ -1095,64 +1096,69 @@ 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);
|
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;
|
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,
|
||||||
|
&proxy->buf[proxy->buflen],
|
||||||
|
QSE_SIZEOF(proxy->buf) - proxy->buflen
|
||||||
|
);
|
||||||
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
/* reading from the peer */
|
/* can't return internal server error any more... */
|
||||||
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
|
||||||
n = httpd->opt.scb.peer.recv (
|
|
||||||
httpd, &proxy->peer,
|
|
||||||
&proxy->buf[proxy->buflen],
|
|
||||||
QSE_SIZEOF(proxy->buf) - proxy->buflen
|
|
||||||
);
|
|
||||||
if (n <= -1)
|
|
||||||
{
|
{
|
||||||
/* can't return internal server error any more... */
|
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_proxy_error (proxy, "proxy recv-from-peer error - ");
|
log_proxy_error (proxy, "proxy recv-from-peer error - ");
|
||||||
return -1;
|
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)
|
||||||
{
|
{
|
||||||
/* peer closed connection */
|
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
||||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
|
||||||
|
if (proxy->peer_output_received < proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
|
log_proxy_error (proxy, "proxy premature eof - ");
|
||||||
if (proxy->peer_output_received < proxy->peer_output_length)
|
return -1;
|
||||||
{
|
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
|
||||||
log_proxy_error (proxy, "proxy premature eof - ");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task->main = task_main_proxy_5;
|
|
||||||
|
|
||||||
/* nothing to read from peer. set the mask to 0 */
|
|
||||||
task->trigger.v[0].mask = 0;
|
|
||||||
|
|
||||||
/* arrange to be called if the client side is writable */
|
|
||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
|
||||||
|
|
||||||
if (proxy->flags & PROXY_RAW)
|
|
||||||
{
|
|
||||||
/* peer connection has been closed.
|
|
||||||
* so no more forwarding from the client to the peer
|
|
||||||
* is possible. get rid of the content callback on the
|
|
||||||
* client side. */
|
|
||||||
qse_htre_unsetconcb (proxy->req);
|
|
||||||
proxy->req = QSE_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task->main = task_main_proxy_5;
|
||||||
|
|
||||||
|
/* nothing to read from peer. set the mask to 0 */
|
||||||
|
task->trigger.v[0].mask = 0;
|
||||||
|
|
||||||
|
/* arrange to be called if the client side is writable */
|
||||||
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
|
||||||
|
if (proxy->flags & PROXY_RAW)
|
||||||
|
{
|
||||||
|
/* peer connection has been closed.
|
||||||
|
* so no more forwarding from the client to the peer
|
||||||
|
* is possible. get rid of the content callback on the
|
||||||
|
* client side. */
|
||||||
|
qse_htre_unsetconcb (proxy->req);
|
||||||
|
proxy->req = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
proxy->buflen += n;
|
proxy->buflen += n;
|
||||||
proxy->peer_output_received += n;
|
proxy->peer_output_received += n;
|
||||||
|
|
||||||
@ -1177,21 +1183,33 @@ 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
|
/* the main loop invokes the task function only if the client
|
||||||
* side is writable. it should be safe to write whenever
|
* 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);
|
n = httpd->opt.scb.client.send (httpd, client, proxy->buf, proxy->buflen);
|
||||||
if (n <= -1)
|
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 send-to-client error - ");
|
/* can't return internal server error any more... */
|
||||||
return -1;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_MEMCPY (&proxy->buf[0], &proxy->buf[n], proxy->buflen - n);
|
|
||||||
proxy->buflen -= n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
|
/*
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
@ -1220,60 +1240,68 @@ 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);
|
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) &&*/ proxy->res_pending > 0)
|
||||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
|
||||||
{
|
{
|
||||||
|
/* 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_ssize_t n;
|
||||||
qse_size_t count;
|
qse_size_t count;
|
||||||
|
|
||||||
count = proxy->res_pending;
|
count = proxy->res_pending;
|
||||||
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
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)
|
||||||
{
|
{
|
||||||
n = httpd->opt.scb.client.send (
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
httpd, client,
|
|
||||||
&QSE_MBS_CHAR(proxy->res,proxy->res_consumed),
|
|
||||||
count
|
|
||||||
);
|
|
||||||
if (n <= -1)
|
|
||||||
{
|
{
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (n > 0)
|
||||||
|
{
|
||||||
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
||||||
proxy->res_consumed += n;
|
proxy->res_consumed += n;
|
||||||
proxy->res_pending -= n;
|
proxy->res_pending -= n;
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy->res_pending <= 0)
|
if (proxy->res_pending <= 0)
|
||||||
{
|
|
||||||
/* all data received from the peer so far(including those injected)
|
|
||||||
* have been sent back to the client-side */
|
|
||||||
|
|
||||||
qse_mbs_clear (proxy->res);
|
|
||||||
proxy->res_consumed = 0;
|
|
||||||
|
|
||||||
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
|
||||||
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
|
||||||
{
|
{
|
||||||
/* received all contents */
|
/* all data received from the peer so far(including those injected)
|
||||||
task->main = task_main_proxy_5;
|
* have been sent back to the client-side */
|
||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
|
||||||
|
qse_mbs_clear (proxy->res);
|
||||||
|
proxy->res_consumed = 0;
|
||||||
|
|
||||||
|
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
||||||
|
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
||||||
|
{
|
||||||
|
/* received all contents */
|
||||||
|
task->main = task_main_proxy_5;
|
||||||
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* there are still more to read from the peer.
|
||||||
|
* arrange to read the remaining contents from the peer */
|
||||||
|
task->main = task_main_proxy_4;
|
||||||
|
/* nothing to write in proxy->res. so clear WRITE from the
|
||||||
|
* client side */
|
||||||
|
task->trigger.cmask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* there are still more to read from the peer.
|
|
||||||
* arrange to read the remaining contents from the peer */
|
|
||||||
task->main = task_main_proxy_4;
|
|
||||||
/* nothing to write in proxy->res. so clear WRITE from the
|
|
||||||
* client side */
|
|
||||||
task->trigger.cmask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
|
#if 0
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
/* client is readable */
|
/* client is readable */
|
||||||
@ -1301,41 +1331,46 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
/* client is not readable but peer is writable */
|
/* client is not readable but peer is writable */
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (/*!(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||*/
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->res_pending > 0)
|
||||||
(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
|
||||||
{
|
{
|
||||||
if (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() 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;
|
||||||
|
|
||||||
|
QSE_ASSERT ((proxy->resflags & PROXY_RES_AWAIT_RESHDR) ||
|
||||||
|
(proxy->resflags & PROXY_RES_CLIENT_CHUNK));
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
/* the 'if' condition becomes true only if '100 Continue'
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
* 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_ssize_t n;
|
|
||||||
qse_size_t count;
|
|
||||||
|
|
||||||
QSE_ASSERT ((proxy->resflags & PROXY_RES_AWAIT_RESHDR) ||
|
|
||||||
(proxy->resflags & PROXY_RES_CLIENT_CHUNK));
|
|
||||||
|
|
||||||
count = proxy->res_pending;
|
|
||||||
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
|
||||||
|
|
||||||
n = httpd->opt.scb.client.send (
|
|
||||||
httpd, client,
|
|
||||||
QSE_MBS_CPTR(proxy->res,proxy->res_consumed),
|
|
||||||
count
|
|
||||||
);
|
|
||||||
if (n <= -1)
|
|
||||||
{
|
{
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_proxy_error (proxy, "proxy send-to-client error - ");
|
log_proxy_error (proxy, "proxy send-to-client error - ");
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (n > 0)
|
||||||
|
{
|
||||||
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
proxy->resflags |= PROXY_RES_EVER_SENTBACK;
|
||||||
proxy->res_consumed += n;
|
proxy->res_consumed += n;
|
||||||
proxy->res_pending -= n;
|
proxy->res_pending -= n;
|
||||||
@ -1367,16 +1402,19 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
);
|
);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (httpd->errnum != QSE_HTTPD_EAGAIN)
|
||||||
log_proxy_error (proxy, "proxy recv-from-peer error - ");
|
{
|
||||||
goto oops;
|
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))
|
if (!(proxy->resflags & PROXY_RES_RECEIVED_RESHDR))
|
||||||
{
|
{
|
||||||
/* end of output from peer before it has seen a header.
|
/* 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)
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
log_proxy_error (proxy, "proxy premature eof - ");
|
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;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
proxy->buflen += n;
|
{
|
||||||
|
proxy->buflen += n;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("#####PROXY FEEDING %d [\n"), (int)proxy->buflen);
|
qse_printf (QSE_T("#####PROXY FEEDING %d [\n"), (int)proxy->buflen);
|
||||||
@ -1416,15 +1456,17 @@ for (i = 0; i < proxy->buflen; i++) qse_printf (QSE_T("%hc"), proxy->buf[i]);
|
|||||||
}
|
}
|
||||||
qse_printf (QSE_T("]\n"));
|
qse_printf (QSE_T("]\n"));
|
||||||
#endif
|
#endif
|
||||||
|
if (proxy->buflen > 0)
|
||||||
if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1)
|
|
||||||
{
|
{
|
||||||
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1)
|
||||||
log_proxy_error (proxy, "proxy feed error - ");
|
{
|
||||||
goto oops;
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
}
|
log_proxy_error (proxy, "proxy feed error - ");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
proxy->buflen = 0;
|
proxy->buflen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (QSE_MBS_LEN(proxy->res) > 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)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||||
{
|
{
|
||||||
/* forward the initial part of the input to the peer */
|
/* 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)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||||
{
|
{
|
||||||
/* there are still more to forward in the buffer
|
/* 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)
|
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)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||||
{
|
{
|
||||||
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
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:
|
case WSAEINTR:
|
||||||
return QSE_HTTPD_EINTR;
|
return QSE_HTTPD_EINTR;
|
||||||
|
|
||||||
|
case WASEWOULDBLOCK:
|
||||||
|
return QSE_HTTPD_EAGAIN;
|
||||||
|
|
||||||
case WSAECONNREFUSED:
|
case WSAECONNREFUSED:
|
||||||
case WSAENETUNREACH:
|
case WSAENETUNREACH:
|
||||||
case WSAEHOSTUNREACH:
|
case WSAEHOSTUNREACH:
|
||||||
@ -180,6 +183,9 @@ static qse_httpd_errnum_t skerr_to_errnum (int e)
|
|||||||
case SOCEPIPE:
|
case SOCEPIPE:
|
||||||
return QSE_HTTPD_EPIPE;
|
return QSE_HTTPD_EPIPE;
|
||||||
|
|
||||||
|
case SOCEAGAIN:
|
||||||
|
return QSE_HTTPD_EAGAIN;
|
||||||
|
|
||||||
case SOCECONNREFUSED:
|
case SOCECONNREFUSED:
|
||||||
case SOCENETUNREACH:
|
case SOCENETUNREACH:
|
||||||
case SOCEHOSTUNREACH:
|
case SOCEHOSTUNREACH:
|
||||||
@ -229,6 +235,9 @@ static qse_httpd_errnum_t skerr_to_errnum (int e)
|
|||||||
return QSE_HTTPD_EPIPE;
|
return QSE_HTTPD_EPIPE;
|
||||||
|
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
|
#if defined(EWEOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
#endif
|
||||||
return QSE_HTTPD_EAGAIN;
|
return QSE_HTTPD_EAGAIN;
|
||||||
|
|
||||||
#if defined(ECONNREFUSED) || defined(ENETUNREACH) || defined(EHOSTUNREACH) || defined(EHOSTDOWN)
|
#if defined(ECONNREFUSED) || defined(ENETUNREACH) || defined(EHOSTUNREACH) || defined(EHOSTDOWN)
|
||||||
@ -259,68 +268,68 @@ static qse_httpd_errnum_t skerr_to_errnum (int e)
|
|||||||
|
|
||||||
static qse_httpd_errnum_t muxerr_to_errnum (qse_mux_errnum_t e)
|
static qse_httpd_errnum_t muxerr_to_errnum (qse_mux_errnum_t e)
|
||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case QSE_MUX_ENOMEM:
|
case QSE_MUX_ENOMEM:
|
||||||
return QSE_HTTPD_ENOMEM;
|
return QSE_HTTPD_ENOMEM;
|
||||||
|
|
||||||
case QSE_MUX_EINVAL:
|
case QSE_MUX_EINVAL:
|
||||||
return QSE_HTTPD_EINVAL;
|
return QSE_HTTPD_EINVAL;
|
||||||
|
|
||||||
case QSE_MUX_EACCES:
|
case QSE_MUX_EACCES:
|
||||||
return QSE_HTTPD_EACCES;
|
return QSE_HTTPD_EACCES;
|
||||||
|
|
||||||
case QSE_MUX_ENOENT:
|
case QSE_MUX_ENOENT:
|
||||||
return QSE_HTTPD_ENOENT;
|
return QSE_HTTPD_ENOENT;
|
||||||
|
|
||||||
case QSE_MUX_EEXIST:
|
case QSE_MUX_EEXIST:
|
||||||
return QSE_HTTPD_EEXIST;
|
return QSE_HTTPD_EEXIST;
|
||||||
|
|
||||||
case QSE_MUX_EINTR:
|
case QSE_MUX_EINTR:
|
||||||
return QSE_HTTPD_EINTR;
|
return QSE_HTTPD_EINTR;
|
||||||
|
|
||||||
case QSE_MUX_EPIPE:
|
case QSE_MUX_EPIPE:
|
||||||
return QSE_HTTPD_EPIPE;
|
return QSE_HTTPD_EPIPE;
|
||||||
|
|
||||||
case QSE_MUX_EAGAIN:
|
case QSE_MUX_EAGAIN:
|
||||||
return QSE_HTTPD_EAGAIN;
|
return QSE_HTTPD_EAGAIN;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QSE_HTTPD_ESYSERR;
|
return QSE_HTTPD_ESYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_httpd_errnum_t fioerr_to_errnum (qse_fio_errnum_t e)
|
static qse_httpd_errnum_t fioerr_to_errnum (qse_fio_errnum_t e)
|
||||||
{
|
{
|
||||||
switch (e)
|
switch (e)
|
||||||
{
|
{
|
||||||
case QSE_FIO_ENOMEM:
|
case QSE_FIO_ENOMEM:
|
||||||
return QSE_HTTPD_ENOMEM;
|
return QSE_HTTPD_ENOMEM;
|
||||||
|
|
||||||
case QSE_FIO_EINVAL:
|
case QSE_FIO_EINVAL:
|
||||||
return QSE_HTTPD_EINVAL;
|
return QSE_HTTPD_EINVAL;
|
||||||
|
|
||||||
case QSE_FIO_EACCES:
|
case QSE_FIO_EACCES:
|
||||||
return QSE_HTTPD_EACCES;
|
return QSE_HTTPD_EACCES;
|
||||||
|
|
||||||
case QSE_FIO_ENOENT:
|
case QSE_FIO_ENOENT:
|
||||||
return QSE_HTTPD_ENOENT;
|
return QSE_HTTPD_ENOENT;
|
||||||
|
|
||||||
case QSE_FIO_EEXIST:
|
case QSE_FIO_EEXIST:
|
||||||
return QSE_HTTPD_EEXIST;
|
return QSE_HTTPD_EEXIST;
|
||||||
|
|
||||||
case QSE_FIO_EINTR:
|
case QSE_FIO_EINTR:
|
||||||
return QSE_HTTPD_EINTR;
|
return QSE_HTTPD_EINTR;
|
||||||
|
|
||||||
case QSE_FIO_EPIPE:
|
case QSE_FIO_EPIPE:
|
||||||
return QSE_HTTPD_EPIPE;
|
return QSE_HTTPD_EPIPE;
|
||||||
|
|
||||||
case QSE_FIO_EAGAIN:
|
case QSE_FIO_EAGAIN:
|
||||||
return QSE_HTTPD_EAGAIN;
|
return QSE_HTTPD_EAGAIN;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QSE_HTTPD_ESYSERR;
|
return QSE_HTTPD_ESYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static qse_httpd_errnum_t direrr_to_errnum (qse_dir_errnum_t e)
|
static qse_httpd_errnum_t direrr_to_errnum (qse_dir_errnum_t e)
|
||||||
@ -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)
|
static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||||
{
|
{
|
||||||
#if defined(__DOS__)
|
#if defined(__DOS__)
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
int fd = -1, flag;
|
sock_t fd = SOCK_INIT, flag;
|
||||||
qse_skad_t addr;
|
qse_skad_t addr;
|
||||||
int addrsize;
|
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);
|
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)
|
#if defined(FD_CLOEXEC)
|
||||||
flag = fcntl (fd, F_GETFD);
|
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)
|
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: logging ... */
|
/* TODO: logging ... */
|
||||||
|
qse_httpd_seterrnum (httpd, ((len <= 0)? QSE_HTTPD_EINVAL: SKERR_TO_ERRNUM()));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -735,50 +822,44 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
|||||||
{
|
{
|
||||||
int on = 1;
|
int on = 1;
|
||||||
setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
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
|
#else
|
||||||
|
|
||||||
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
goto oops;
|
goto oops;
|
||||||
#endif
|
#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)
|
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||||
flag = fcntl (fd, F_GETFL);
|
|
||||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
server->handle.i = fd;
|
server->handle.i = fd;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
if (is_valid_socket(fd)) close_socket (fd);
|
||||||
#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
|
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_close (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
static void server_close (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
close_socket (server->handle.i);
|
||||||
closesocket (server->handle.i);
|
|
||||||
#elif defined(__OS2__)
|
|
||||||
soclose (server->handle.i);
|
|
||||||
#elif defined(__DOS__)
|
|
||||||
/* TODO: */
|
|
||||||
#else
|
|
||||||
QSE_CLOSE (server->handle.i);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int server_accept (
|
static int server_accept (
|
||||||
@ -790,29 +871,25 @@ static int server_accept (
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
qse_skad_t addr;
|
qse_skad_t addr;
|
||||||
|
|
||||||
#if defined(HAVE_SOCKLEN_T)
|
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
#else
|
sock_t fd = SOCK_INIT;
|
||||||
int addrlen;
|
int flag;
|
||||||
#endif
|
|
||||||
int fd, flag;
|
|
||||||
|
|
||||||
addrlen = QSE_SIZEOF(addr);
|
addrlen = QSE_SIZEOF(addr);
|
||||||
fd = accept (server->handle.i, (struct sockaddr*)&addr, &addrlen);
|
fd = accept (server->handle.i, (struct sockaddr*)&addr, &addrlen);
|
||||||
if (fd <= -1)
|
if (!is_valid_socket(fd))
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/* TODO: implement maximum number of client per server??? */
|
||||||
if (fd >= FD_SETSIZE)
|
if (fd >= FD_SETSIZE)
|
||||||
{
|
{
|
||||||
qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
||||||
/*TODO: qse_httpd_seterrnum (httpd, QSE_HTTPD_EXXXXX);*/
|
/*TODO: qse_httpd_seterrnum (httpd, QSE_HTTPD_EXXXXX);*/
|
||||||
QSE_CLOSE (fd);
|
goto oops;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(O_NONBLOCK)
|
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||||
flag = fcntl (fd, F_GETFL);
|
|
||||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (qse_skadtonwad (&addr, &client->remote_addr) <= -1)
|
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;
|
client->handle.i = fd;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (is_valid_socket(fd)) close_socket (fd);
|
||||||
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,17 +963,14 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
|||||||
qse_skad_t connaddr, bindaddr;
|
qse_skad_t connaddr, bindaddr;
|
||||||
int connaddrsize, bindaddrsize;
|
int connaddrsize, bindaddrsize;
|
||||||
int connected = 1;
|
int connected = 1;
|
||||||
|
sock_t fd = SOCK_INIT;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
SOCKET fd = -1;
|
|
||||||
unsigned long cmd;
|
unsigned long cmd;
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
int fd = -1;
|
|
||||||
int cmd;
|
int cmd;
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
int fd = -1;
|
|
||||||
int flag;
|
int flag;
|
||||||
#else
|
#else
|
||||||
int fd = -1;
|
|
||||||
int flag;
|
int flag;
|
||||||
#endif
|
#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);
|
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)
|
#if defined(IP_TRANSPARENT)
|
||||||
flag = 1;
|
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 */
|
/* 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)
|
#if defined(FD_CLOEXEC)
|
||||||
flag = fcntl (fd, F_GETFD);
|
flag = fcntl (fd, F_GETFD);
|
||||||
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flag = fcntl (fd, F_GETFL);
|
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||||
if (flag >= 0) fcntl (fd, F_SETFL, flag | O_NONBLOCK);
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
if (connect (fd, (struct sockaddr*)&connaddr, connaddrsize) <= -1)
|
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;
|
connected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore flags */
|
#elif defined(__OS2__)
|
||||||
if (fcntl (fd, F_SETFL, flag) <= -1) goto oops;
|
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
|
#endif
|
||||||
|
|
||||||
|
/*if (set_socket_nonblock (httpd, fd, 0) <= -1) goto oops;*/
|
||||||
|
|
||||||
peer->handle.i = fd;
|
peer->handle.i = fd;
|
||||||
return connected;
|
return connected;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
#if defined(_WIN32)
|
if (is_valid_socket(fd)) close_socket (fd);
|
||||||
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
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
@ -995,15 +1060,7 @@ oops:
|
|||||||
|
|
||||||
static void peer_close (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
static void peer_close (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
close_socket (peer->handle.i);
|
||||||
closesocket (peer->handle.i);
|
|
||||||
#elif defined(__OS2__)
|
|
||||||
soclose (peer->handle.i);
|
|
||||||
#elif defined(__DOS__)
|
|
||||||
/* TODO: */
|
|
||||||
#else
|
|
||||||
QSE_CLOSE (peer->handle.i);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int peer_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
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
|
#else
|
||||||
|
|
||||||
#if defined(HAVE_SOCKLEN_T)
|
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
#else
|
|
||||||
int len;
|
|
||||||
#endif
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
len = QSE_SIZEOF(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
|
# define SHUT_RDWR 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void client_close (
|
static void client_close (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
shutdown (client->handle.i, SHUT_RDWR);
|
shutdown (client->handle.i, SHUT_RDWR);
|
||||||
closesocket (client->handle.i);
|
|
||||||
#elif defined(__OS2__)
|
#elif defined(__OS2__)
|
||||||
shutdown (client->handle.i, SHUT_RDWR);
|
shutdown (client->handle.i, SHUT_RDWR);
|
||||||
soclose (client->handle.i);
|
|
||||||
#elif defined(__DOS__)
|
#elif defined(__DOS__)
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
#else
|
#else
|
||||||
shutdown (client->handle.i, SHUT_RDWR);
|
shutdown (client->handle.i, SHUT_RDWR);
|
||||||
QSE_CLOSE (client->handle.i);
|
|
||||||
#endif
|
#endif
|
||||||
|
close_socket (client->handle.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_shutdown (
|
static void client_shutdown (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client)
|
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
shutdown (client->handle.i, SHUT_RDWR);
|
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);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
int fd = -1, flag;
|
sock_t fd = SOCK_INIT;
|
||||||
|
int flag;
|
||||||
qse_nwad_t nwad;
|
qse_nwad_t nwad;
|
||||||
dns_ctx_t* dc;
|
dns_ctx_t* dc;
|
||||||
httpd_xtn_t* httpd_xtn;
|
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);
|
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)
|
#if defined(FD_CLOEXEC)
|
||||||
flag = fcntl (fd, F_GETFD);
|
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));
|
setsockopt (fd, SOL_SOCKET, SO_REUSEPORT, (void*)&flag, QSE_SIZEOF(flag));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
||||||
|
|
||||||
dns->handle.i = fd;
|
dns->handle.i = fd;
|
||||||
dns->ctx = dc;
|
dns->ctx = dc;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (fd >= 0)
|
if (is_valid_socket(fd)) close_socket (fd);
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
closesocket (fd);
|
|
||||||
#elif defined(__OS2__)
|
|
||||||
soclose (fd);
|
|
||||||
#else
|
|
||||||
QSE_CLOSE (fd);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dc) qse_httpd_freemem (httpd, dc);
|
if (dc) qse_httpd_freemem (httpd, dc);
|
||||||
return -1;
|
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;
|
dns_ctx_t* dc = (dns_ctx_t*)dns->ctx;
|
||||||
|
|
||||||
qse_skad_t fromaddr;
|
qse_skad_t fromaddr;
|
||||||
socklen_t fromlen; /* TODO: change type */
|
socklen_t fromlen;
|
||||||
|
|
||||||
qse_uint8_t buf[DNS_MAX_MSG_LEN];
|
qse_uint8_t buf[DNS_MAX_MSG_LEN];
|
||||||
qse_ssize_t 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;
|
qse_size_t name_len;
|
||||||
dns_ans_t* ans;
|
dns_ans_t* ans;
|
||||||
|
|
||||||
printf ("finding answer in cache...\n");
|
|
||||||
ans = dns_get_answer_from_cache (dc, name);
|
ans = dns_get_answer_from_cache (dc, name);
|
||||||
if (ans)
|
if (ans)
|
||||||
{
|
{
|
||||||
printf ("found answer in cache...\n");
|
|
||||||
resol (httpd, name, ((ans->nwad.type == QSE_NWAD_NX)? QSE_NULL: &ans->nwad), ctx);
|
resol (httpd, name, ((ans->nwad.type == QSE_NWAD_NX)? QSE_NULL: &ans->nwad), ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("found XXXXX in cache...\n");
|
|
||||||
seq = dc->seq;
|
seq = dc->seq;
|
||||||
seq = (seq + 1) % QSE_COUNTOF(dc->reqs);
|
seq = (seq + 1) % QSE_COUNTOF(dc->reqs);
|
||||||
dc->seq = seq;
|
dc->seq = seq;
|
||||||
|
@ -90,13 +90,19 @@ static int task_main_format (
|
|||||||
count = MAX_SEND_SIZE;
|
count = MAX_SEND_SIZE;
|
||||||
if (count >= ctx->left) count = ctx->left;
|
if (count >= ctx->left) count = ctx->left;
|
||||||
|
|
||||||
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
n = httpd->opt.scb.client.send (httpd, client, ctx->ptr, count);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->left -= n;
|
|
||||||
if (ctx->left <= 0) return 0;
|
|
||||||
|
|
||||||
ctx->ptr += n;
|
|
||||||
return 1; /* more work to do */
|
return 1; /* more work to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,13 +53,18 @@ static int task_main_text (
|
|||||||
if (count >= ctx->left) count = ctx->left;
|
if (count >= ctx->left) count = ctx->left;
|
||||||
|
|
||||||
/* TODO: do i need to add code to skip this send if count is 0? */
|
/* 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);
|
n = httpd->opt.scb.client.send (httpd, client, ctx->ptr, count);
|
||||||
if (n <= -1) return -1;
|
if (n <= -1)
|
||||||
|
{
|
||||||
ctx->left -= n;
|
if (httpd->errnum != QSE_HTTPD_EAGAIN) return -1;
|
||||||
if (ctx->left <= 0) return 0;
|
}
|
||||||
|
else if (n > 0)
|
||||||
ctx->ptr += n;
|
{
|
||||||
|
ctx->left -= n;
|
||||||
|
if (ctx->left <= 0) return 0;
|
||||||
|
ctx->ptr += n;
|
||||||
|
}
|
||||||
return 1; /* more work to do */
|
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 */
|
/* active to inactive */
|
||||||
|
|
||||||
printf ("ACTIVE TO INACTIVE....\n");
|
/*printf ("ACTIVE TO INACTIVE....\n");*/
|
||||||
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||||
{
|
{
|
||||||
if (client->status & CLIENT_TASK_TRIGGER_RW_IN_MUX(i))
|
if (client->status & CLIENT_TASK_TRIGGER_RW_IN_MUX(i))
|
||||||
@ -942,21 +942,21 @@ printf ("ACTIVE TO INACTIVE....\n");
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("INACTIVE TO ACTIVE....\n");
|
/*printf ("INACTIVE TO ACTIVE....\n");*/
|
||||||
/* inactive to active . go on*/
|
/* inactive to active . go on*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (task->trigger.flags & QSE_HTTPD_TASK_TRIGGER_INACTIVE)
|
if (task->trigger.flags & QSE_HTTPD_TASK_TRIGGER_INACTIVE)
|
||||||
{
|
{
|
||||||
printf ("INACTIVE TO INACTIVE....\n");
|
/*printf ("INACTIVE TO INACTIVE....\n");*/
|
||||||
/* inactive to inactive.
|
/* inactive to inactive.
|
||||||
* save the trigger as the trigger handle and masks could change */
|
* save the trigger as the trigger handle and masks could change */
|
||||||
client->trigger = task->trigger;
|
client->trigger = task->trigger;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("ACTIVE TO ACTIVE....\n");
|
/*printf ("ACTIVE TO ACTIVE....\n");*/
|
||||||
/* active to active. go on */
|
/* active to active. go on */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1183,13 +1183,23 @@ static int invoke_client_task (
|
|||||||
{
|
{
|
||||||
if (mask & QSE_HTTPD_MUX_READ)
|
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;
|
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_READABLE;
|
||||||
trigger_fired = 1;
|
trigger_fired = 1;
|
||||||
}
|
}
|
||||||
if (mask & QSE_HTTPD_MUX_WRITE)
|
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;
|
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_WRITABLE;
|
||||||
trigger_fired = 1;
|
trigger_fired = 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user