improved dns and proxy handling in httpd

This commit is contained in:
hyung-hwan 2014-07-23 16:07:43 +00:00
parent 5703aaa8a5
commit 1231b3b941
13 changed files with 200 additions and 50 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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
{ {

View File

@ -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

View File

@ -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)

View File

@ -48,7 +48,7 @@ int qse_nwadequal (const qse_nwad_t* x, const qse_nwad_t* y)
void qse_clearnwad (qse_nwad_t* nwad, qse_nwad_type_t type) void qse_clearnwad (qse_nwad_t* nwad, qse_nwad_type_t type)
{ {
QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad)); QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad));
nwad->type = type; nwad->type = type;
} }
@ -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);

View File

@ -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;
} }

View File

@ -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

View File

@ -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;
req->qalen = init_dns_query (req->qa, QSE_SIZEOF(req->qa), name, DNS_QTYPE_A, req->seqa); if (!(httpd->opt.trait & QSE_HTTPD_DNSNOA))
req->qaaaalen = init_dns_query (req->qaaaa, QSE_SIZEOF(req->qaaaa), name, DNS_QTYPE_AAAA, req->seqaaaa); 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);
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);
} }

View File

@ -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)

View File

@ -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;