improved dns and proxy handling in httpd
This commit is contained in:
parent
5703aaa8a5
commit
1231b3b941
@ -1912,7 +1912,7 @@ static int httpd_main (int argc, qse_char_t* argv[])
|
|||||||
setup_signal_handlers ();
|
setup_signal_handlers ();
|
||||||
|
|
||||||
qse_httpd_getopt (httpd, QSE_HTTPD_TRAIT, &trait);
|
qse_httpd_getopt (httpd, QSE_HTTPD_TRAIT, &trait);
|
||||||
trait |= QSE_HTTPD_CGIERRTONUL | QSE_HTTPD_LOGACT;
|
trait |= QSE_HTTPD_CGIERRTONUL | QSE_HTTPD_LOGACT | QSE_HTTPD_DNSNOAAAA;
|
||||||
qse_httpd_setopt (httpd, QSE_HTTPD_TRAIT, &trait);
|
qse_httpd_setopt (httpd, QSE_HTTPD_TRAIT, &trait);
|
||||||
|
|
||||||
tmout.sec = 10;
|
tmout.sec = 10;
|
||||||
@ -1929,7 +1929,7 @@ static int httpd_main (int argc, qse_char_t* argv[])
|
|||||||
if (g_debug) rcb.logact = logact_httpd; /* i don't remember old logging handler */
|
if (g_debug) rcb.logact = logact_httpd; /* i don't remember old logging handler */
|
||||||
qse_httpd_setopt (httpd, QSE_HTTPD_RCB, &rcb);
|
qse_httpd_setopt (httpd, QSE_HTTPD_RCB, &rcb);
|
||||||
|
|
||||||
ret = qse_httpd_loopstd (httpd);
|
ret = qse_httpd_loopstd (httpd, QSE_NULL);
|
||||||
|
|
||||||
restore_signal_handlers ();
|
restore_signal_handlers ();
|
||||||
g_httpd = QSE_NULL;
|
g_httpd = QSE_NULL;
|
||||||
|
@ -110,6 +110,9 @@ QSE_EXPORT void qse_setnwadport (
|
|||||||
qse_uint16_t port
|
qse_uint16_t port
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT qse_uint16_t qse_getnwadport (
|
||||||
|
qse_nwad_t* nwad
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_mbstonwad (
|
QSE_EXPORT int qse_mbstonwad (
|
||||||
const qse_mchar_t* mbs,
|
const qse_mchar_t* mbs,
|
||||||
|
@ -251,7 +251,8 @@ QSE_EXPORT qse_ssize_t qse_sio_getmbsn (
|
|||||||
* The qse_sio_getwcs() function reads at most @a size - 1 characters
|
* The qse_sio_getwcs() function reads at most @a size - 1 characters
|
||||||
* from the stream @a sio into the buffer @a buf. If a new line or EOF
|
* from the stream @a sio into the buffer @a buf. If a new line or EOF
|
||||||
* is encountered, it stops reading from the stream. It null-terminates
|
* is encountered, it stops reading from the stream. It null-terminates
|
||||||
* the buffer if @a size is greater than 0. */
|
* the buffer if @a size is greater than 0.
|
||||||
|
*/
|
||||||
QSE_EXPORT qse_ssize_t qse_sio_getwcs (
|
QSE_EXPORT qse_ssize_t qse_sio_getwcs (
|
||||||
qse_sio_t* sio,
|
qse_sio_t* sio,
|
||||||
qse_wchar_t* buf,
|
qse_wchar_t* buf,
|
||||||
|
@ -56,6 +56,7 @@ enum qse_httpd_errnum_t
|
|||||||
QSE_HTTPD_ENOBUF, /* no buffer available */
|
QSE_HTTPD_ENOBUF, /* no buffer available */
|
||||||
QSE_HTTPD_EDISCON, /* client disconnnected */
|
QSE_HTTPD_EDISCON, /* client disconnnected */
|
||||||
QSE_HTTPD_EBADREQ, /* bad request */
|
QSE_HTTPD_EBADREQ, /* bad request */
|
||||||
|
QSE_HTTPD_ENODNS, /* dns service not activated */
|
||||||
QSE_HTTPD_ETASK
|
QSE_HTTPD_ETASK
|
||||||
};
|
};
|
||||||
typedef enum qse_httpd_errnum_t qse_httpd_errnum_t;
|
typedef enum qse_httpd_errnum_t qse_httpd_errnum_t;
|
||||||
@ -77,7 +78,9 @@ enum qse_httpd_trait_t
|
|||||||
QSE_HTTPD_CGINOCLOEXEC = (1 << 2),
|
QSE_HTTPD_CGINOCLOEXEC = (1 << 2),
|
||||||
QSE_HTTPD_CGINOCHUNKED = (1 << 3),
|
QSE_HTTPD_CGINOCHUNKED = (1 << 3),
|
||||||
QSE_HTTPD_PROXYNOVIA = (1 << 4),
|
QSE_HTTPD_PROXYNOVIA = (1 << 4),
|
||||||
QSE_HTTPD_LOGACT = (1 << 5)
|
QSE_HTTPD_LOGACT = (1 << 5),
|
||||||
|
QSE_HTTPD_DNSNOA = (1 << 6),
|
||||||
|
QSE_HTTPD_DNSNOAAAA = (1 << 7),
|
||||||
};
|
};
|
||||||
typedef enum qse_httpd_trait_t qse_httpd_trait_t;
|
typedef enum qse_httpd_trait_t qse_httpd_trait_t;
|
||||||
|
|
||||||
@ -358,9 +361,7 @@ enum qse_httpd_task_trigger_mask_t
|
|||||||
typedef struct qse_httpd_task_trigger_t qse_httpd_task_trigger_t;
|
typedef struct qse_httpd_task_trigger_t qse_httpd_task_trigger_t;
|
||||||
struct qse_httpd_task_trigger_t
|
struct qse_httpd_task_trigger_t
|
||||||
{
|
{
|
||||||
|
|
||||||
int flags; /**< [IN] bitwise-ORed of #qse_httpd_task_trigger_flag_t enumerators*/
|
int flags; /**< [IN] bitwise-ORed of #qse_httpd_task_trigger_flag_t enumerators*/
|
||||||
|
|
||||||
int cmask; /* client mask - QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
int cmask; /* client mask - QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <qse/http/httpd.h>
|
#include <qse/http/httpd.h>
|
||||||
|
|
||||||
|
|
||||||
typedef int (*qse_httpd_serverstd_makersrc_t) (
|
typedef int (*qse_httpd_serverstd_makersrc_t) (
|
||||||
qse_httpd_t* httpd,
|
qse_httpd_t* httpd,
|
||||||
qse_httpd_client_t* client,
|
qse_httpd_client_t* client,
|
||||||
@ -196,7 +195,8 @@ QSE_EXPORT void* qse_httpd_getserverstdxtn (
|
|||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_httpd_loopstd (
|
QSE_EXPORT int qse_httpd_loopstd (
|
||||||
qse_httpd_t* httpd
|
qse_httpd_t* httpd,
|
||||||
|
const qse_nwad_t* dnsnwad
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#ifdef MINIMIZE_PLATFORM_DEPENDENCY
|
#ifdef MINIMIZE_PLATFORM_DEPENDENCY
|
||||||
# define QSE_MEMCPY(dst,src,len) qse_memcpy(dst,src,len)
|
# define QSE_MEMCPY(dst,src,len) qse_memcpy(dst,src,len)
|
||||||
|
# define QSE_MEMMOVE(dst,src,len) qse_memmove(dst,src,len)
|
||||||
# define QSE_MEMCMP(p1,p2,len) qse_memcmp(p1,p2,len)
|
# define QSE_MEMCMP(p1,p2,len) qse_memcmp(p1,p2,len)
|
||||||
# define QSE_MEMSET(dst,val,len) qse_memset(dst,val,len)
|
# define QSE_MEMSET(dst,val,len) qse_memset(dst,val,len)
|
||||||
# define QSE_MEMBYTE(s,val,len) qse_membyte(s,val,len)
|
# define QSE_MEMBYTE(s,val,len) qse_membyte(s,val,len)
|
||||||
@ -34,6 +35,7 @@
|
|||||||
#else
|
#else
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# define QSE_MEMCPY(dst,src,len) memcpy(dst,src,len)
|
# define QSE_MEMCPY(dst,src,len) memcpy(dst,src,len)
|
||||||
|
# define QSE_MEMMOVE(dst,src,len) memmove(dst,src,len)
|
||||||
# define QSE_MEMCMP(p1,p2,len) memcmp(p1,p2,len)
|
# define QSE_MEMCMP(p1,p2,len) memcmp(p1,p2,len)
|
||||||
# define QSE_MEMSET(dst,val,len) memset(dst,val,len)
|
# define QSE_MEMSET(dst,val,len) memset(dst,val,len)
|
||||||
# define QSE_MEMBYTE(s,val,len) memchr(s,val,len)
|
# define QSE_MEMBYTE(s,val,len) memchr(s,val,len)
|
||||||
|
@ -61,11 +61,26 @@ void qse_setnwadport (qse_nwad_t* nwad, qse_uint16_t port)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_NWAD_IN6:
|
case QSE_NWAD_IN6:
|
||||||
nwad->u.in4.port = port;
|
nwad->u.in6.port = port;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qse_uint16_t qse_getnwadport (qse_nwad_t* nwad)
|
||||||
|
{
|
||||||
|
switch (nwad->type)
|
||||||
|
{
|
||||||
|
case QSE_NWAD_IN4:
|
||||||
|
return nwad->u.in4.port;
|
||||||
|
|
||||||
|
case QSE_NWAD_IN6:
|
||||||
|
return nwad->u.in6.port;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
|
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
|
||||||
{
|
{
|
||||||
return qse_mbsntonwad (str, qse_mbslen(str), nwad);
|
return qse_mbsntonwad (str, qse_mbslen(str), nwad);
|
||||||
|
@ -200,7 +200,7 @@ qse_size_t qse_mbstrm (qse_mchar_t* str)
|
|||||||
{
|
{
|
||||||
e[1] = QSE_MT('\0');
|
e[1] = QSE_MT('\0');
|
||||||
if (str != s)
|
if (str != s)
|
||||||
QSE_MEMCPY (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
QSE_MEMMOVE (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
||||||
return e - s + 1;
|
return e - s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ qse_size_t qse_mbsxtrm (qse_mchar_t* str, qse_size_t len)
|
|||||||
/* do not insert a terminating null */
|
/* do not insert a terminating null */
|
||||||
/*e[1] = QSE_MT('\0');*/
|
/*e[1] = QSE_MT('\0');*/
|
||||||
if (str != s)
|
if (str != s)
|
||||||
QSE_MEMCPY (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
QSE_MEMMOVE (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
||||||
return e - s + 1;
|
return e - s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ qse_size_t qse_wcstrm (qse_wchar_t* str)
|
|||||||
{
|
{
|
||||||
e[1] = QSE_MT('\0');
|
e[1] = QSE_MT('\0');
|
||||||
if (str != s)
|
if (str != s)
|
||||||
QSE_MEMCPY (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
QSE_MEMMOVE (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
||||||
return e - s + 1;
|
return e - s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ qse_size_t qse_wcsxtrm (qse_wchar_t* str, qse_size_t len)
|
|||||||
/* do not insert a terminating null */
|
/* do not insert a terminating null */
|
||||||
/*e[1] = QSE_MT('\0');*/
|
/*e[1] = QSE_MT('\0');*/
|
||||||
if (str != s)
|
if (str != s)
|
||||||
QSE_MEMCPY (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
QSE_MEMMOVE (str, s, (e - s + 2) * QSE_SIZEOF(*str));
|
||||||
return e - s + 1;
|
return e - s + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,9 +789,8 @@ static int task_init_proxy (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*proxy->peer_port = 443;*/
|
if (proxy->flags & PROXY_RAW) proxy->peer_port = QSE_HTTPD_DEFAULT_SECURE_PORT;
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
|
else proxy->peer_port = QSE_HTTPD_DEFAULT_PORT;
|
||||||
goto oops;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <qse/cmn/mux.h>
|
#include <qse/cmn/mux.h>
|
||||||
#include <qse/cmn/dir.h>
|
#include <qse/cmn/dir.h>
|
||||||
#include <qse/cmn/fio.h>
|
#include <qse/cmn/fio.h>
|
||||||
|
#include <qse/cmn/sio.h>
|
||||||
|
|
||||||
#define STAT_REG 1
|
#define STAT_REG 1
|
||||||
#define STAT_DIR 2
|
#define STAT_DIR 2
|
||||||
@ -96,10 +97,6 @@
|
|||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_PORT 80
|
|
||||||
#define DEFAULT_SECURE_PORT 443
|
|
||||||
|
|
||||||
typedef struct server_xtn_t server_xtn_t;
|
typedef struct server_xtn_t server_xtn_t;
|
||||||
struct server_xtn_t
|
struct server_xtn_t
|
||||||
{
|
{
|
||||||
@ -536,6 +533,7 @@ struct httpd_xtn_t
|
|||||||
SSL_CTX* ssl_ctx;
|
SSL_CTX* ssl_ctx;
|
||||||
#endif
|
#endif
|
||||||
qse_httpd_ecb_t ecb;
|
qse_httpd_ecb_t ecb;
|
||||||
|
qse_nwad_t dnsnwad;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(HAVE_SSL)
|
#if defined(HAVE_SSL)
|
||||||
@ -1979,8 +1977,8 @@ struct dns_ctx_t
|
|||||||
|
|
||||||
struct dns_req_t
|
struct dns_req_t
|
||||||
{
|
{
|
||||||
#define DNS_REQ_A_ERROR (1 << 0)
|
#define DNS_REQ_A_NX (1 << 0)
|
||||||
#define DNS_REQ_AAAA_ERROR (1 << 1)
|
#define DNS_REQ_AAAA_NX (1 << 1)
|
||||||
int flags;
|
int flags;
|
||||||
qse_uint16_t seqa, seqaaaa;
|
qse_uint16_t seqa, seqaaaa;
|
||||||
|
|
||||||
@ -2186,22 +2184,73 @@ static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
|||||||
int fd = -1, flag;
|
int fd = -1, flag;
|
||||||
qse_nwad_t nwad;
|
qse_nwad_t nwad;
|
||||||
dns_ctx_t* dc;
|
dns_ctx_t* dc;
|
||||||
|
httpd_xtn_t* httpd_xtn;
|
||||||
|
|
||||||
|
httpd_xtn = qse_httpd_getxtn (httpd);
|
||||||
|
|
||||||
dc = (dns_ctx_t*) qse_httpd_callocmem (httpd, QSE_SIZEOF(dns_ctx_t));
|
dc = (dns_ctx_t*) qse_httpd_callocmem (httpd, QSE_SIZEOF(dns_ctx_t));
|
||||||
if (dc == NULL) goto oops;
|
if (dc == NULL) goto oops;
|
||||||
|
|
||||||
/* TODO: get this from configuration??? or /etc/resolv.conf */
|
/* TODO: add static cache entries from /etc/hosts */
|
||||||
if (qse_mbstonwad ("8.8.8.8:53", &nwad) <= -1)
|
|
||||||
|
nwad = httpd_xtn->dnsnwad;
|
||||||
|
if (nwad.type == QSE_NWAD_NX)
|
||||||
|
{
|
||||||
|
qse_sio_t* sio;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
/* TODO: */
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
/* TODO: */
|
||||||
|
#else
|
||||||
|
/* TODO: read /etc/resolv.conf???? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sio = qse_sio_open (qse_httpd_getmmgr(httpd), 0, QSE_T("/etc/resolv.conf"), QSE_SIO_READ);
|
||||||
|
if (sio)
|
||||||
|
{
|
||||||
|
qse_mchar_t buf[128];
|
||||||
|
qse_ssize_t len;
|
||||||
|
qse_mcstr_t tok;
|
||||||
|
qse_mchar_t* ptr;
|
||||||
|
qse_mchar_t* end;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
len = qse_sio_getmbsn (sio, buf, QSE_COUNTOF(buf));
|
||||||
|
if (len <= 0) break;
|
||||||
|
|
||||||
|
end = buf + len;
|
||||||
|
ptr = buf;
|
||||||
|
|
||||||
|
ptr = qse_mbsxtok (ptr, end - ptr, QSE_MT(" \t"), &tok);
|
||||||
|
if (ptr && qse_mbsxcmp (tok.ptr, tok.len, QSE_MT("nameserver")) == 0)
|
||||||
|
{
|
||||||
|
ptr = qse_mbsxtok (ptr, end - ptr, QSE_MT(" \t"), &tok);
|
||||||
|
if (qse_mbsntonwad (tok.ptr, tok.len, &nwad) >= 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qse_sio_close (sio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qse_getnwadport(&nwad) == 0)
|
||||||
|
qse_setnwadport (&nwad, qse_hton16(QSE_HTTPD_DEFAULT_DNS_PORT));
|
||||||
|
|
||||||
|
dc->skadlen = qse_nwadtoskad (&nwad, &dc->skad);
|
||||||
|
if (dc->skadlen <= -1)
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->skadlen = qse_nwadtoskad (&nwad, &dc->skad);
|
if (httpd->opt.trait & QSE_HTTPD_LOGACT)
|
||||||
if (dc->skadlen <= -1)
|
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
qse_httpd_act_t msg;
|
||||||
return -1;
|
qse_size_t pos;
|
||||||
|
msg.code = QSE_HTTPD_CATCH_MDBGMSG;
|
||||||
|
pos = qse_mbsxcpy (msg.u.mdbgmsg, QSE_COUNTOF(msg.u.mdbgmsg), "nameserver set to ");
|
||||||
|
qse_nwadtombs (&nwad, &msg.u.mdbgmsg[pos], QSE_COUNTOF(msg.u.mdbgmsg) - pos, QSE_NWADTOMBS_ALL);
|
||||||
|
httpd->opt.rcb.logact (httpd, &msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP);
|
fd = socket (qse_skadfamily(&dc->skad), SOCK_DGRAM, IPPROTO_UDP);
|
||||||
@ -2274,6 +2323,7 @@ printf ("RECV....\n");
|
|||||||
len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen);
|
len = recvfrom (dns->handle.i, buf, QSE_SIZEOF(buf), 0, (struct sockaddr*)&fromaddr, &fromlen);
|
||||||
|
|
||||||
/* TODO: check if fromaddr matches the dc->skad... */
|
/* TODO: check if fromaddr matches the dc->skad... */
|
||||||
|
/* TODO: dns caching .... */
|
||||||
|
|
||||||
if (len >= QSE_SIZEOF(*hdr))
|
if (len >= QSE_SIZEOF(*hdr))
|
||||||
{
|
{
|
||||||
@ -2303,13 +2353,11 @@ printf ("finding match req...\n");
|
|||||||
|
|
||||||
reclen = dnlen + QSE_SIZEOF(dns_qdtrail_t);
|
reclen = dnlen + QSE_SIZEOF(dns_qdtrail_t);
|
||||||
if (pllen < reclen) goto done;
|
if (pllen < reclen) goto done;
|
||||||
printf ("1111111111111111111111\n");
|
|
||||||
if (!req)
|
if (!req)
|
||||||
{
|
{
|
||||||
dns_qdtrail_t* qdtrail = (dns_qdtrail_t*)(plptr + dnlen);
|
dns_qdtrail_t* qdtrail = (dns_qdtrail_t*)(plptr + dnlen);
|
||||||
for (preq = QSE_NULL, req = dc->reqs[xid]; req; preq = req, req = req->next)
|
for (preq = QSE_NULL, req = dc->reqs[xid]; req; preq = req, req = req->next)
|
||||||
{
|
{
|
||||||
printf ("checking req... %d %d\n",(int)req->dnlen, (int)dnlen);
|
|
||||||
if (req->dnlen == dnlen &&
|
if (req->dnlen == dnlen &&
|
||||||
QSE_MEMCMP (req->dn, plptr, req->dnlen) == 0 &&
|
QSE_MEMCMP (req->dn, plptr, req->dnlen) == 0 &&
|
||||||
qdtrail->qclass == qse_hton16(DNS_QCLASS_IN) &&
|
qdtrail->qclass == qse_hton16(DNS_QCLASS_IN) &&
|
||||||
@ -2399,10 +2447,10 @@ printf ("invoking resoll with ipv6 \n");
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (id == req->seqa) req->flags |= DNS_REQ_A_ERROR;
|
if (id == req->seqa) req->flags |= DNS_REQ_A_NX;
|
||||||
else if (id == req->seqaaaa) req->flags |= DNS_REQ_AAAA_ERROR;
|
else if (id == req->seqaaaa) req->flags |= DNS_REQ_AAAA_NX;
|
||||||
|
|
||||||
if ((req->flags & (DNS_REQ_A_ERROR | DNS_REQ_AAAA_ERROR)) == (DNS_REQ_A_ERROR | DNS_REQ_AAAA_ERROR))
|
if ((req->flags & (DNS_REQ_A_NX | DNS_REQ_AAAA_NX)) == (DNS_REQ_A_NX | DNS_REQ_AAAA_NX))
|
||||||
{
|
{
|
||||||
req->resol (httpd, req->name, QSE_NULL, req->ctx);
|
req->resol (httpd, req->name, QSE_NULL, req->ctx);
|
||||||
|
|
||||||
@ -2457,8 +2505,16 @@ static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t
|
|||||||
req->resol = resol;
|
req->resol = resol;
|
||||||
req->ctx = ctx;
|
req->ctx = ctx;
|
||||||
|
|
||||||
|
if (!(httpd->opt.trait & QSE_HTTPD_DNSNOA))
|
||||||
req->qalen = init_dns_query (req->qa, QSE_SIZEOF(req->qa), name, DNS_QTYPE_A, req->seqa);
|
req->qalen = init_dns_query (req->qa, QSE_SIZEOF(req->qa), name, DNS_QTYPE_A, req->seqa);
|
||||||
|
else
|
||||||
|
req->flags |= DNS_REQ_A_NX;
|
||||||
|
|
||||||
|
if (!(httpd->opt.trait & QSE_HTTPD_DNSNOAAAA))
|
||||||
req->qaaaalen = init_dns_query (req->qaaaa, QSE_SIZEOF(req->qaaaa), name, DNS_QTYPE_AAAA, req->seqaaaa);
|
req->qaaaalen = init_dns_query (req->qaaaa, QSE_SIZEOF(req->qaaaa), name, DNS_QTYPE_AAAA, req->seqaaaa);
|
||||||
|
else
|
||||||
|
req->flags |= DNS_REQ_AAAA_NX;
|
||||||
|
|
||||||
if (req->qalen <= -1 || req->qaaaalen <= -1)
|
if (req->qalen <= -1 || req->qaaaalen <= -1)
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
|
||||||
@ -2466,9 +2522,8 @@ static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("SENDING......\n");
|
if ((req->qalen > 0 && sendto (dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen) ||
|
||||||
if (sendto (dns->handle.i, req->qa, req->qalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qalen ||
|
(req->qaaaalen > 0 && sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen))
|
||||||
sendto (dns->handle.i, req->qaaaa, req->qaaaalen, 0, (struct sockaddr*)&dc->skad, dc->skadlen) != req->qaaaalen)
|
|
||||||
{
|
{
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
qse_httpd_freemem (httpd, req);
|
qse_httpd_freemem (httpd, req);
|
||||||
@ -2514,6 +2569,17 @@ static int process_request (
|
|||||||
* non-peek mode as well */
|
* non-peek mode as well */
|
||||||
if (peek) qse_perdechttpstr (qse_htre_getqpath(req), qse_htre_getqpath(req));
|
if (peek) qse_perdechttpstr (qse_htre_getqpath(req), qse_htre_getqpath(req));
|
||||||
|
|
||||||
|
|
||||||
|
if (peek && (httpd->opt.trait & QSE_HTTPD_LOGACT))
|
||||||
|
{
|
||||||
|
/* TODO: improve logging */
|
||||||
|
qse_httpd_act_t msg;
|
||||||
|
msg.code = QSE_HTTPD_CATCH_MDBGMSG;
|
||||||
|
qse_mbsxfmt (msg.u.mdbgmsg, QSE_COUNTOF(msg.u.mdbgmsg),
|
||||||
|
QSE_MT("%s %s"), qse_htre_getqmethodname(req), qse_htre_getqpath(req));
|
||||||
|
httpd->opt.rcb.logact (httpd, &msg);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("================================\n"));
|
qse_printf (QSE_T("================================\n"));
|
||||||
qse_printf (QSE_T("[%lu] %hs REQUEST ==> [%hs] version[%d.%d %hs] method[%hs]\n"),
|
qse_printf (QSE_T("[%lu] %hs REQUEST ==> [%hs] version[%d.%d %hs] method[%hs]\n"),
|
||||||
@ -2564,6 +2630,8 @@ if (qse_htre_getcontentlen(req) > 0)
|
|||||||
*
|
*
|
||||||
* NOTE: CONNECT is implemented to ignore many headers like
|
* NOTE: CONNECT is implemented to ignore many headers like
|
||||||
* 'Expect: 100-continue' and 'Connection: keep-alive'. */
|
* 'Expect: 100-continue' and 'Connection: keep-alive'. */
|
||||||
|
|
||||||
|
/* TODO: CHECK if CONNECT is allowed ... */
|
||||||
qse_httpd_discardcontent (httpd, req);
|
qse_httpd_discardcontent (httpd, req);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2626,7 +2694,8 @@ if (qse_htre_getcontentlen(req) > 0)
|
|||||||
{
|
{
|
||||||
printf ("SWITCHING HTRD TO DUMMY.... %s\n", qse_htre_getqpath(req));
|
printf ("SWITCHING HTRD TO DUMMY.... %s\n", qse_htre_getqpath(req));
|
||||||
/* Switch the http read to a dummy mode so that the subsqeuent
|
/* Switch the http read to a dummy mode so that the subsqeuent
|
||||||
* input is just treaet as connects to the request just completed */
|
* input(request) is just treated as data to the request just
|
||||||
|
* completed */
|
||||||
qse_htrd_setoption (client->htrd, qse_htrd_getoption(client->htrd) | QSE_HTRD_DUMMY);
|
qse_htrd_setoption (client->htrd, qse_htrd_getoption(client->htrd) | QSE_HTRD_DUMMY);
|
||||||
|
|
||||||
if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
||||||
@ -3091,6 +3160,7 @@ static int make_resource (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* make the source binding type the same as destination */
|
/* make the source binding type the same as destination */
|
||||||
|
/* no default port for raw proxying */
|
||||||
target->u.proxy.src.nwad.type = target->u.proxy.dst.nwad.type;
|
target->u.proxy.src.nwad.type = target->u.proxy.dst.nwad.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3099,6 +3169,50 @@ static int make_resource (
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* htrd compacts double slashes to a single slash.
|
||||||
|
* so inspect if the query path begins with http:/ instead of http:// */
|
||||||
|
/*if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http://"), 7) == 0)*/
|
||||||
|
if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http:/"), 6) == 0)
|
||||||
|
{
|
||||||
|
/* TODO: check if proxying is allowed.... */
|
||||||
|
qse_mchar_t* host, * slash;
|
||||||
|
|
||||||
|
/*host = tmp.qpath + 6;*/
|
||||||
|
host = tmp.qpath + 6;
|
||||||
|
slash = qse_mbschr (host, QSE_MT('/'));
|
||||||
|
|
||||||
|
if (slash && slash - host > 0)
|
||||||
|
{
|
||||||
|
target->type = QSE_HTTPD_RSRC_PROXY;
|
||||||
|
target->u.proxy.flags = 0;
|
||||||
|
|
||||||
|
if (qse_mbsntonwad (host, slash - host, &target->u.proxy.dst.nwad) <= -1)
|
||||||
|
{
|
||||||
|
/* TODO: refrain from manipulating the request like this */
|
||||||
|
QSE_MEMMOVE (host - 1, host, slash - host);
|
||||||
|
slash[-1] = QSE_MT('\0');
|
||||||
|
|
||||||
|
target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_DST_STR;
|
||||||
|
target->u.proxy.dst.str = host - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* make the source binding type the same as destination */
|
||||||
|
if (qse_getnwadport(&target->u.proxy.dst.nwad) == 0)
|
||||||
|
qse_setnwadport (&target->u.proxy.dst.nwad, qse_hton16(80));
|
||||||
|
target->u.proxy.src.nwad.type = target->u.proxy.dst.nwad.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: refrain from manipulating the request like this */
|
||||||
|
req->u.q.path = slash; /* TODO: use setqpath or something... */
|
||||||
|
|
||||||
|
/* mark that this request is going to be proxied. */
|
||||||
|
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_ROOT, &tmp.root) <= -1) return -1;
|
if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_ROOT, &tmp.root) <= -1) return -1;
|
||||||
switch (tmp.root.type)
|
switch (tmp.root.type)
|
||||||
{
|
{
|
||||||
@ -3556,8 +3670,8 @@ qse_httpd_server_t* qse_httpd_attachserverstdwithuri (
|
|||||||
}
|
}
|
||||||
else if (qse_strxcasecmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("https")) == 0)
|
else if (qse_strxcasecmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("https")) == 0)
|
||||||
{
|
{
|
||||||
server.flags |= QSE_HTTPD_SERVER_SECURE;
|
server.flags |= QSE_HTTPD_QSE_HTTPD_SERVER_SECURE;
|
||||||
default_port = DEFAULT_SECURE_PORT;
|
default_port = QSE_HTTPD_DEFAULT_SECURE_PORT;
|
||||||
}
|
}
|
||||||
else goto invalid;
|
else goto invalid;
|
||||||
|
|
||||||
@ -3662,7 +3776,14 @@ void* qse_httpd_getserverstdxtn (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
int qse_httpd_loopstd (qse_httpd_t* httpd)
|
int qse_httpd_loopstd (qse_httpd_t* httpd, const qse_nwad_t* dnsnwad)
|
||||||
{
|
{
|
||||||
|
httpd_xtn_t* httpd_xtn = qse_httpd_getxtn (httpd);
|
||||||
|
|
||||||
|
if (dnsnwad)
|
||||||
|
httpd_xtn->dnsnwad = *dnsnwad;
|
||||||
|
else
|
||||||
|
httpd_xtn->dnsnwad.type = QSE_NWAD_NX;
|
||||||
|
|
||||||
return qse_httpd_loop (httpd);
|
return qse_httpd_loop (httpd);
|
||||||
}
|
}
|
||||||
|
@ -1461,6 +1461,8 @@ int qse_httpd_loop (qse_httpd_t* httpd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: add timer and execute scheduled events here. */
|
||||||
|
|
||||||
purge_bad_clients (httpd);
|
purge_bad_clients (httpd);
|
||||||
purge_idle_clients (httpd);
|
purge_idle_clients (httpd);
|
||||||
|
|
||||||
@ -1600,10 +1602,13 @@ int qse_httpd_resolname (qse_httpd_t* httpd, const qse_mchar_t* name, qse_httpd_
|
|||||||
|
|
||||||
/* not found in the cache */
|
/* not found in the cache */
|
||||||
printf ("dns_send.........................\n");
|
printf ("dns_send.........................\n");
|
||||||
return httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, ctx);
|
if (!httpd->dnsactive)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENODNS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* resol (httpd, QSE_NULL, ctx);
|
return httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, ctx);
|
||||||
return 0;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
int qse_httpd_activatetasktrigger (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
#include <qse/http/httpd.h>
|
#include <qse/http/httpd.h>
|
||||||
|
|
||||||
|
#define QSE_HTTPD_DEFAULT_PORT 80
|
||||||
|
#define QSE_HTTPD_DEFAULT_SECURE_PORT 443
|
||||||
|
#define QSE_HTTPD_DEFAULT_DNS_PORT 53
|
||||||
struct qse_httpd_t
|
struct qse_httpd_t
|
||||||
{
|
{
|
||||||
qse_mmgr_t* mmgr;
|
qse_mmgr_t* mmgr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user