added some code for name resolution
This commit is contained in:
parent
a0e2a7067c
commit
4e0e403a73
@ -356,14 +356,14 @@ static int make_resource (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rsrc->type = QSE_HTTPD_RSRC_PROXY;
|
rsrc->type = QSE_HTTPD_RSRC_PROXY;
|
||||||
rsrc->u.proxy.raw = 0;
|
rsrc->u.proxy.flags = 0;
|
||||||
rsrc->u.proxy.dst = client->orgdst_addr;
|
rsrc->u.proxy.dst.nwad = client->orgdst_addr;
|
||||||
rsrc->u.proxy.src = client->remote_addr;
|
rsrc->u.proxy.src.nwad = client->remote_addr;
|
||||||
|
|
||||||
if (rsrc->u.proxy.src.type == QSE_NWAD_IN4)
|
if (rsrc->u.proxy.src.nwad.type == QSE_NWAD_IN4)
|
||||||
rsrc->u.proxy.src.u.in4.port = 0; /* reset the port to 0. */
|
rsrc->u.proxy.src.nwad.u.in4.port = 0; /* reset the port to 0. */
|
||||||
else if (rsrc->u.proxy.src.type == QSE_NWAD_IN6)
|
else if (rsrc->u.proxy.src.nwad.type == QSE_NWAD_IN6)
|
||||||
rsrc->u.proxy.src.u.in6.port = 0; /* reset the port to 0. */
|
rsrc->u.proxy.src.nwad.u.in6.port = 0; /* reset the port to 0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1727,6 +1727,7 @@ static void logact_httpd (qse_httpd_t* httpd, const qse_httpd_act_t* act)
|
|||||||
qse_nwadtostr (&act->u.client->orgdst_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOSTR_ALL);
|
qse_nwadtostr (&act->u.client->orgdst_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOSTR_ALL);
|
||||||
qse_nwadtostr (&act->u.client->remote_addr, tmp3, QSE_COUNTOF(tmp3), QSE_NWADTOSTR_ALL);
|
qse_nwadtostr (&act->u.client->remote_addr, tmp3, QSE_COUNTOF(tmp3), QSE_NWADTOSTR_ALL);
|
||||||
qse_printf (QSE_T("accepted client %s(%s) from %s\n"), tmp, tmp2, tmp3);
|
qse_printf (QSE_T("accepted client %s(%s) from %s\n"), tmp, tmp2, tmp3);
|
||||||
|
break;
|
||||||
|
|
||||||
case QSE_HTTPD_PURGE_CLIENT:
|
case QSE_HTTPD_PURGE_CLIENT:
|
||||||
qse_nwadtostr (&act->u.client->remote_addr, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL);
|
qse_nwadtostr (&act->u.client->remote_addr, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL);
|
||||||
|
@ -111,6 +111,10 @@ server {
|
|||||||
ssl-key-file = "/etc/qse/key.pem";
|
ssl-key-file = "/etc/qse/key.pem";
|
||||||
|
|
||||||
host "*" {
|
host "*" {
|
||||||
|
# place other locations before /
|
||||||
|
#location "/help" {
|
||||||
|
#}
|
||||||
|
|
||||||
location "/" {
|
location "/" {
|
||||||
# uncomment the followng block to override the default.
|
# uncomment the followng block to override the default.
|
||||||
#root = "/var/www";
|
#root = "/var/www";
|
||||||
@ -143,9 +147,6 @@ server {
|
|||||||
#}
|
#}
|
||||||
}
|
}
|
||||||
|
|
||||||
# other locations than / are not supported yet.
|
|
||||||
#location "/help" {
|
|
||||||
#}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# virtual hosts are not supported yet.
|
# virtual hosts are not supported yet.
|
||||||
|
@ -32,6 +32,7 @@ typedef struct qse_httpd_t qse_httpd_t;
|
|||||||
typedef struct qse_httpd_mate_t qse_httpd_mate_t;
|
typedef struct qse_httpd_mate_t qse_httpd_mate_t;
|
||||||
typedef struct qse_httpd_server_t qse_httpd_server_t;
|
typedef struct qse_httpd_server_t qse_httpd_server_t;
|
||||||
typedef struct qse_httpd_client_t qse_httpd_client_t;
|
typedef struct qse_httpd_client_t qse_httpd_client_t;
|
||||||
|
typedef struct qse_httpd_dns_t qse_httpd_dns_t;
|
||||||
|
|
||||||
enum qse_httpd_errnum_t
|
enum qse_httpd_errnum_t
|
||||||
{
|
{
|
||||||
@ -120,6 +121,12 @@ struct qse_httpd_dirent_t
|
|||||||
qse_httpd_stat_t stat;
|
qse_httpd_stat_t stat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*qse_httpd_resol_t) (
|
||||||
|
qse_httpd_t* httpd,
|
||||||
|
const qse_nwad_t* nwad,
|
||||||
|
void* ctx
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct qse_httpd_scb_t qse_httpd_scb_t;
|
typedef struct qse_httpd_scb_t qse_httpd_scb_t;
|
||||||
struct qse_httpd_scb_t
|
struct qse_httpd_scb_t
|
||||||
{
|
{
|
||||||
@ -235,6 +242,14 @@ struct qse_httpd_scb_t
|
|||||||
qse_httpd_t* httpd,
|
qse_httpd_t* httpd,
|
||||||
qse_httpd_client_t* client); /* optional */
|
qse_httpd_client_t* client); /* optional */
|
||||||
} client;
|
} client;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int (*open) (qse_httpd_t* httpd, qse_httpd_dns_t* dns);
|
||||||
|
void (*close) (qse_httpd_t* httpd, qse_httpd_dns_t* dns);
|
||||||
|
int (*recv) (qse_httpd_t* httpd, qse_httpd_dns_t* dns);
|
||||||
|
int (*send) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx);
|
||||||
|
} dns;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@ -322,6 +337,11 @@ typedef int (*qse_httpd_task_main_t) (
|
|||||||
qse_httpd_task_t* task
|
qse_httpd_task_t* task
|
||||||
);
|
);
|
||||||
|
|
||||||
|
enum qse_httpd_task_trigger_flag_t
|
||||||
|
{
|
||||||
|
QSE_HTTPD_TASK_TRIGGER_INACTIVE = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
enum qse_httpd_task_trigger_mask_t
|
enum qse_httpd_task_trigger_mask_t
|
||||||
{
|
{
|
||||||
QSE_HTTPD_TASK_TRIGGER_READ = (1 << 0),
|
QSE_HTTPD_TASK_TRIGGER_READ = (1 << 0),
|
||||||
@ -330,32 +350,37 @@ enum qse_httpd_task_trigger_mask_t
|
|||||||
QSE_HTTPD_TASK_TRIGGER_WRITABLE = (1 << 3)
|
QSE_HTTPD_TASK_TRIGGER_WRITABLE = (1 << 3)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define QSE_HTTPD_TASK_TRIGGER_MAX 3
|
||||||
|
|
||||||
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*/
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
int mask; /* QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
int mask; /* QSE_HTTPD_TASK_TRIGGER_READ | QSE_HTTPD_TASK_TRIGGER_WRITE */
|
||||||
qse_ubi_t handle;
|
qse_ubi_t handle;
|
||||||
|
} v[QSE_HTTPD_TASK_TRIGGER_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QSE_HTTPD_TASK_TRIGGER_MAX 3
|
|
||||||
|
|
||||||
struct qse_httpd_task_t
|
struct qse_httpd_task_t
|
||||||
{
|
{
|
||||||
/* you must not call another entask functions from within
|
/* you must not call another entask functions from within
|
||||||
* an initailizer. you can call entask functions from within
|
* an initailizer. you can call entask functions from within
|
||||||
* a finalizer and a main function. */
|
* a finalizer and a main function. */
|
||||||
|
|
||||||
qse_httpd_task_init_t init; /**< [IN] initializer */
|
qse_httpd_task_init_t init; /**< [IN] initializer */
|
||||||
qse_httpd_task_fini_t fini; /**< [IN] finalizer */
|
qse_httpd_task_fini_t fini; /**< [IN] finalizer */
|
||||||
qse_httpd_task_main_t main; /**< [IN] main task function */
|
qse_httpd_task_main_t main; /**< [IN] main task function */
|
||||||
qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX];
|
qse_httpd_task_trigger_t trigger;
|
||||||
void* ctx; /**< [IN OUT] user-defined data */
|
void* ctx; /**< [IN OUT] user-defined data */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum qse_httpd_mate_type_t
|
enum qse_httpd_mate_type_t
|
||||||
{
|
{
|
||||||
QSE_HTTPD_SERVER,
|
QSE_HTTPD_SERVER,
|
||||||
QSE_HTTPD_CLIENT
|
QSE_HTTPD_CLIENT,
|
||||||
|
QSE_HTTPD_DNS
|
||||||
};
|
};
|
||||||
typedef enum qse_httpd_mate_type_t qse_httpd_mate_type_t;
|
typedef enum qse_httpd_mate_type_t qse_httpd_mate_type_t;
|
||||||
|
|
||||||
@ -387,7 +412,7 @@ struct qse_httpd_client_t
|
|||||||
/* == PRIVATE == */
|
/* == PRIVATE == */
|
||||||
qse_htrd_t* htrd;
|
qse_htrd_t* htrd;
|
||||||
int status;
|
int status;
|
||||||
qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX];
|
qse_httpd_task_trigger_t trigger;
|
||||||
qse_ntime_t last_active;
|
qse_ntime_t last_active;
|
||||||
|
|
||||||
qse_httpd_client_t* prev;
|
qse_httpd_client_t* prev;
|
||||||
@ -441,6 +466,16 @@ struct qse_httpd_server_t
|
|||||||
qse_httpd_server_t* prev;
|
qse_httpd_server_t* prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct qse_httpd_dns_t
|
||||||
|
{
|
||||||
|
/* == PRIVATE == */
|
||||||
|
QSE_HTTPD_MATE_HDR;
|
||||||
|
|
||||||
|
/* == PUBLIC == */
|
||||||
|
qse_ubi_t handle;
|
||||||
|
void* ctx;
|
||||||
|
};
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -477,12 +512,25 @@ struct qse_httpd_rsrc_cgi_t
|
|||||||
int nph;
|
int nph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum qse_httpd_rsrc_proxy_flag_t
|
||||||
|
{
|
||||||
|
QSE_HTTPD_RSRC_PROXY_RAW = (1 << 0),
|
||||||
|
QSE_HTTPD_RSRC_PROXY_DST_STR = (1 << 1)
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t;
|
typedef struct qse_httpd_rsrc_proxy_t qse_httpd_rsrc_proxy_t;
|
||||||
struct qse_httpd_rsrc_proxy_t
|
struct qse_httpd_rsrc_proxy_t
|
||||||
{
|
{
|
||||||
qse_nwad_t dst; /* remote destination address to connect to */
|
int flags; /* bitwise-ORed of qse_httpd_rsrc_proxy_flag_t enumerators */
|
||||||
qse_nwad_t src; /* local binding address */
|
union
|
||||||
int raw; /* raw or normal */
|
{
|
||||||
|
qse_nwad_t nwad;
|
||||||
|
} src; /* local binding address */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
qse_nwad_t nwad;
|
||||||
|
const qse_mchar_t* str;
|
||||||
|
} dst; /* remote destination address to connect to */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t;
|
typedef struct qse_httpd_rsrc_dir_t qse_httpd_rsrc_dir_t;
|
||||||
@ -565,6 +613,7 @@ struct qse_httpd_ecb_t
|
|||||||
qse_httpd_ecb_t* next;
|
qse_httpd_ecb_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -901,6 +950,15 @@ QSE_EXPORT qse_mchar_t* qse_httpd_escapehtml (
|
|||||||
const qse_mchar_t* str
|
const qse_mchar_t* str
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_httpd_resolname (
|
||||||
|
qse_httpd_t* httpd,
|
||||||
|
const qse_mchar_t* name,
|
||||||
|
qse_httpd_resol_t resol,
|
||||||
|
void* ctx
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,7 +16,6 @@ libqsehttp_la_SOURCES = \
|
|||||||
httpd-dir.c \
|
httpd-dir.c \
|
||||||
httpd-file.c \
|
httpd-file.c \
|
||||||
httpd-proxy.c \
|
httpd-proxy.c \
|
||||||
httpd-resol.c \
|
|
||||||
httpd-std.c \
|
httpd-std.c \
|
||||||
httpd-task.c \
|
httpd-task.c \
|
||||||
httpd-text.c \
|
httpd-text.c \
|
||||||
|
@ -101,8 +101,7 @@ libqsehttp_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
|||||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||||
am_libqsehttp_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \
|
am_libqsehttp_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \
|
||||||
httpd-cgi.lo httpd-dir.lo httpd-file.lo httpd-proxy.lo \
|
httpd-cgi.lo httpd-dir.lo httpd-file.lo httpd-proxy.lo \
|
||||||
httpd-resol.lo httpd-std.lo httpd-task.lo httpd-text.lo \
|
httpd-std.lo httpd-task.lo httpd-text.lo upxd.lo
|
||||||
upxd.lo
|
|
||||||
libqsehttp_la_OBJECTS = $(am_libqsehttp_la_OBJECTS)
|
libqsehttp_la_OBJECTS = $(am_libqsehttp_la_OBJECTS)
|
||||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||||
@ -338,7 +337,6 @@ libqsehttp_la_SOURCES = \
|
|||||||
httpd-dir.c \
|
httpd-dir.c \
|
||||||
httpd-file.c \
|
httpd-file.c \
|
||||||
httpd-proxy.c \
|
httpd-proxy.c \
|
||||||
httpd-resol.c \
|
|
||||||
httpd-std.c \
|
httpd-std.c \
|
||||||
httpd-task.c \
|
httpd-task.c \
|
||||||
httpd-text.c \
|
httpd-text.c \
|
||||||
@ -428,7 +426,6 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-dir.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-dir.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-file.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-file.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-proxy.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-proxy.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-resol.Plo@am__quote@
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-std.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-std.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-task.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-task.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-text.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd-text.Plo@am__quote@
|
||||||
|
@ -561,16 +561,16 @@ else qse_printf (QSE_T("!!!CGI SNATCHING DONE\n"));
|
|||||||
|
|
||||||
/* since there is no more to read from the client side.
|
/* since there is no more to read from the client side.
|
||||||
* the relay trigger is not needed any more. */
|
* the relay trigger is not needed any more. */
|
||||||
task->trigger[2].mask = 0;
|
task->trigger.v[2].mask = 0;
|
||||||
|
|
||||||
if (QSE_MBS_LEN(cgi->reqfwdbuf) > 0 && cgi->pio_inited &&
|
if (QSE_MBS_LEN(cgi->reqfwdbuf) > 0 && cgi->pio_inited &&
|
||||||
!(task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITE))
|
!(task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITE))
|
||||||
{
|
{
|
||||||
/* there's nothing more to read from the client side.
|
/* there's nothing more to read from the client side.
|
||||||
* there's something to forward in the forwarding buffer.
|
* there's something to forward in the forwarding buffer.
|
||||||
* but no write trigger is set. add the write trigger
|
* but no write trigger is set. add the write trigger
|
||||||
* for task invocation. */
|
* for task invocation. */
|
||||||
task->trigger[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(cgi->reqflags & CGI_REQ_FWDERR))
|
else if (!(cgi->reqflags & CGI_REQ_FWDERR))
|
||||||
@ -606,7 +606,7 @@ else qse_printf (QSE_T("!!!CGI SNATCHING DONE\n"));
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* output pipe to child */
|
/* output pipe to child */
|
||||||
task->trigger[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("!!!CGI SNATCHED [%.*hs]\n"), len, ptr);
|
qse_printf (QSE_T("!!!CGI SNATCHED [%.*hs]\n"), len, ptr);
|
||||||
#endif
|
#endif
|
||||||
@ -666,7 +666,7 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
if (QSE_MBS_LEN(cgi->reqfwdbuf) <= 0)
|
if (QSE_MBS_LEN(cgi->reqfwdbuf) <= 0)
|
||||||
{
|
{
|
||||||
if (cgi->reqflags & CGI_REQ_GOTALL) goto done;
|
if (cgi->reqflags & CGI_REQ_GOTALL) goto done;
|
||||||
else task->trigger[1].mask = 0; /* pipe output to child */
|
else task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,7 +695,7 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
|
|
||||||
/* mark the end of input to the child explicitly. */
|
/* mark the end of input to the child explicitly. */
|
||||||
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
||||||
task->trigger[1].mask = 0; /* pipe output to child */
|
task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,8 +714,8 @@ qse_printf (QSE_T("FORWARD: @@@@@@@@NOTHING MORE TO WRITE TO CGI\n"));
|
|||||||
/* mark the end of input to the child explicitly. */
|
/* mark the end of input to the child explicitly. */
|
||||||
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
||||||
|
|
||||||
task->trigger[1].mask = 0; /* pipe output to child */
|
task->trigger.v[1].mask = 0; /* pipe output to child */
|
||||||
task->trigger[2].mask = 0; /* client-side */
|
task->trigger.v[2].mask = 0; /* client-side */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,17 +994,17 @@ static int task_main_cgi_5 (
|
|||||||
|
|
||||||
QSE_ASSERT (cgi->pio_inited);
|
QSE_ASSERT (cgi->pio_inited);
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 0);
|
cgi_forward_client_input_to_script (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 1);
|
cgi_forward_client_input_to_script (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
if (!(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
||||||
(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||||
{
|
{
|
||||||
if (cgi->buflen > 0)
|
if (cgi->buflen > 0)
|
||||||
{
|
{
|
||||||
@ -1031,16 +1031,16 @@ static int task_main_cgi_4_nph (
|
|||||||
|
|
||||||
QSE_ASSERT (cgi->nph);
|
QSE_ASSERT (cgi->nph);
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 0);
|
cgi_forward_client_input_to_script (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 1);
|
cgi_forward_client_input_to_script (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
if (cgi->buflen < QSE_SIZEOF(cgi->buf))
|
||||||
{
|
{
|
||||||
@ -1050,8 +1050,8 @@ static int task_main_cgi_4_nph (
|
|||||||
{
|
{
|
||||||
/* switch to the next phase */
|
/* switch to the next phase */
|
||||||
task->main = task_main_cgi_5;
|
task->main = task_main_cgi_5;
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1074,19 +1074,19 @@ static int task_main_cgi_4 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
qse_printf (QSE_T("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 0);
|
cgi_forward_client_input_to_script (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 1);
|
cgi_forward_client_input_to_script (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
if (cgi->resflags & CGI_RES_CLIENT_CHUNK)
|
if (cgi->resflags & CGI_RES_CLIENT_CHUNK)
|
||||||
{
|
{
|
||||||
@ -1123,8 +1123,8 @@ qse_printf (QSE_T("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d trigger
|
|||||||
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
cgi->buf[cgi->buflen++] = QSE_MT('\n');
|
||||||
|
|
||||||
task->main = task_main_cgi_5;
|
task->main = task_main_cgi_5;
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,8 +1168,8 @@ qse_printf (QSE_T("task_main_cgi_4 trigger[0].mask=%d trigger[1].mask=%d trigger
|
|||||||
{
|
{
|
||||||
/* switch to the next phase */
|
/* switch to the next phase */
|
||||||
task->main = task_main_cgi_5;
|
task->main = task_main_cgi_5;
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,21 +1209,21 @@ static int task_main_cgi_3 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("task_main_cgi_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
qse_printf (QSE_T("task_main_cgi_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 0);
|
cgi_forward_client_input_to_script (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 1);
|
cgi_forward_client_input_to_script (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
if (!(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
||||||
(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||||
{
|
{
|
||||||
count = MAX_SEND_SIZE;
|
count = MAX_SEND_SIZE;
|
||||||
if (count >= cgi->res_left) count = cgi->res_left;
|
if (count >= cgi->res_left) count = cgi->res_left;
|
||||||
@ -1257,12 +1257,12 @@ qse_printf (QSE_T("task_main_cgi_3 trigger[0].mask=%d trigger[1].mask=%d trigger
|
|||||||
* something extra after having done so.
|
* something extra after having done so.
|
||||||
* however, a CGI script shouln't do that... */
|
* however, a CGI script shouln't do that... */
|
||||||
task->main = task_main_cgi_5;
|
task->main = task_main_cgi_5;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
task->main = task_main_cgi_4;
|
task->main = task_main_cgi_4;
|
||||||
task->trigger[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1288,19 +1288,19 @@ static int task_main_cgi_2 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
qse_printf (QSE_T("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 0);
|
cgi_forward_client_input_to_script (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[1].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
cgi_forward_client_input_to_script (httpd, task, 1);
|
cgi_forward_client_input_to_script (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
n = qse_pio_read (
|
n = qse_pio_read (
|
||||||
&cgi->pio, QSE_PIO_OUT,
|
&cgi->pio, QSE_PIO_OUT,
|
||||||
@ -1351,7 +1351,7 @@ qse_printf (QSE_T("task_main_cgi_2 trigger[0].mask=%d trigger[1].mask=%d trigger
|
|||||||
qse_printf (QSE_T("TRAILING DATA=[%.*hs]\n"), (int)QSE_MBS_LEN(cgi->res), QSE_MBS_PTR(cgi->res));
|
qse_printf (QSE_T("TRAILING DATA=[%.*hs]\n"), (int)QSE_MBS_LEN(cgi->res), QSE_MBS_PTR(cgi->res));
|
||||||
#endif
|
#endif
|
||||||
task->main = task_main_cgi_3;
|
task->main = task_main_cgi_3;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,10 +1448,10 @@ static int task_main_cgi (
|
|||||||
* it the output from the child is available, this task
|
* it the output from the child is available, this task
|
||||||
* writes it back to the client. so add a trigger for
|
* writes it back to the client. so add a trigger for
|
||||||
* checking the data availability from the child process */
|
* checking the data availability from the child process */
|
||||||
task->trigger[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
task->trigger[0].handle = qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_OUT);
|
task->trigger.v[0].handle = qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_OUT);
|
||||||
task->trigger[1].handle = qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_IN);
|
task->trigger.v[1].handle = qse_pio_gethandleasubi (&cgi->pio, QSE_PIO_IN);
|
||||||
task->trigger[2].handle = client->handle;
|
task->trigger.v[2].handle = client->handle;
|
||||||
|
|
||||||
if (cgi->reqfwdbuf)
|
if (cgi->reqfwdbuf)
|
||||||
{
|
{
|
||||||
@ -1462,7 +1462,7 @@ static int task_main_cgi (
|
|||||||
{
|
{
|
||||||
/* there are still things to forward from the client-side.
|
/* there are still things to forward from the client-side.
|
||||||
* i can rely on this relay trigger for task invocation. */
|
* i can rely on this relay trigger for task invocation. */
|
||||||
task->trigger[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QSE_MBS_LEN(cgi->reqfwdbuf) > 0)
|
if (QSE_MBS_LEN(cgi->reqfwdbuf) > 0)
|
||||||
@ -1486,7 +1486,7 @@ static int task_main_cgi (
|
|||||||
* a trigger for invocation. ask the main loop to
|
* a trigger for invocation. ask the main loop to
|
||||||
* invoke this task so long as it is able to write
|
* invoke this task so long as it is able to write
|
||||||
* to the child process */
|
* to the child process */
|
||||||
task->trigger[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[1].mask = QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ static int putfile_snatch_client_input (
|
|||||||
|
|
||||||
/* since there is no more to read from the client side.
|
/* since there is no more to read from the client side.
|
||||||
* the trigger is not needed any more. */
|
* the trigger is not needed any more. */
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
}
|
}
|
||||||
else if (!(file->u.put.flags & PUTFILE_WRITE_FAILED))
|
else if (!(file->u.put.flags & PUTFILE_WRITE_FAILED))
|
||||||
{
|
{
|
||||||
@ -476,8 +476,8 @@ static int task_main_putfile_2 (
|
|||||||
* QSE_NULL when snatching is over in putfile_snatch_client_input().
|
* QSE_NULL when snatching is over in putfile_snatch_client_input().
|
||||||
* i set a trigger so that the task is executed
|
* i set a trigger so that the task is executed
|
||||||
* while there is input from the client side */
|
* while there is input from the client side */
|
||||||
task->trigger[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
task->trigger[0].handle = client->handle;
|
task->trigger.v[0].handle = client->handle;
|
||||||
return 1; /* trigger me when a client sends data */
|
return 1; /* trigger me when a client sends data */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,11 @@ struct task_proxy_arg_t
|
|||||||
typedef struct task_proxy_t task_proxy_t;
|
typedef struct task_proxy_t task_proxy_t;
|
||||||
struct task_proxy_t
|
struct task_proxy_t
|
||||||
{
|
{
|
||||||
int init_failed;
|
#define PROXY_INIT_FAILED (1 << 0)
|
||||||
|
#define PROXY_RAW (1 << 1)
|
||||||
|
#define PROXY_RESOL_PEER_NAME (1 << 2)
|
||||||
|
#define PROXY_UNKNOWN_PEER_NWAD (1 << 3)
|
||||||
|
int flags;
|
||||||
qse_httpd_t* httpd;
|
qse_httpd_t* httpd;
|
||||||
|
|
||||||
int method;
|
int method;
|
||||||
@ -44,6 +48,7 @@ struct task_proxy_t
|
|||||||
|
|
||||||
qse_htrd_t* peer_htrd;
|
qse_htrd_t* peer_htrd;
|
||||||
|
|
||||||
|
const qse_mchar_t* peer_name;
|
||||||
qse_httpd_peer_t peer;
|
qse_httpd_peer_t peer;
|
||||||
#define PROXY_PEER_OPEN (1 << 0)
|
#define PROXY_PEER_OPEN (1 << 0)
|
||||||
#define PROXY_PEER_CONNECTED (1 << 1)
|
#define PROXY_PEER_CONNECTED (1 << 1)
|
||||||
@ -209,7 +214,7 @@ static int proxy_snatch_client_input_raw (
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -262,17 +267,17 @@ else qse_printf (QSE_T("!!!PROXY SNATCHING DONE\n"));
|
|||||||
|
|
||||||
/* since there is no more to read from the client side.
|
/* since there is no more to read from the client side.
|
||||||
* the relay trigger is not needed any more. */
|
* the relay trigger is not needed any more. */
|
||||||
task->trigger[2].mask = 0;
|
task->trigger.v[2].mask = 0;
|
||||||
|
|
||||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0 &&
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0 &&
|
||||||
(proxy->peer_status & PROXY_PEER_CONNECTED) &&
|
(proxy->peer_status & PROXY_PEER_CONNECTED) &&
|
||||||
!(task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITE))
|
!(task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITE))
|
||||||
{
|
{
|
||||||
/* there's nothing more to read from the client side.
|
/* there's nothing more to read from the client side.
|
||||||
* there's something to forward in the forwarding buffer.
|
* there's something to forward in the forwarding buffer.
|
||||||
* but no write trigger is set. add the write trigger
|
* but no write trigger is set. add the write trigger
|
||||||
* for task invocation. */
|
* for task invocation. */
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(proxy->reqflags & PROXY_REQ_FWDERR))
|
else if (!(proxy->reqflags & PROXY_REQ_FWDERR))
|
||||||
@ -307,7 +312,7 @@ else qse_printf (QSE_T("!!!PROXY SNATCHING DONE\n"));
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("!!!PROXY SNATCHED [%.*hs]\n"), len, ptr);
|
qse_printf (QSE_T("!!!PROXY SNATCHED [%.*hs]\n"), len, ptr);
|
||||||
#endif
|
#endif
|
||||||
@ -700,7 +705,7 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
||||||
{
|
{
|
||||||
if (proxy->req == QSE_NULL) goto done;
|
if (proxy->req == QSE_NULL) goto done;
|
||||||
else task->trigger[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
else task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -720,7 +725,7 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
* qse_htre_discardcontent() */
|
* qse_htre_discardcontent() */
|
||||||
}
|
}
|
||||||
|
|
||||||
task->trigger[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,8 +736,8 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
* there is nothing more to forward in the forwarding buffer.
|
* there is nothing more to forward in the forwarding buffer.
|
||||||
* clear the read and write triggers.
|
* clear the read and write triggers.
|
||||||
*/
|
*/
|
||||||
task->trigger[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE; /* peer */
|
||||||
task->trigger[2].mask = 0; /* client-side */
|
task->trigger.v[2].mask = 0; /* client-side */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,7 +751,6 @@ static int task_init_proxy (
|
|||||||
qse_size_t len;
|
qse_size_t len;
|
||||||
const qse_mchar_t* ptr;
|
const qse_mchar_t* ptr;
|
||||||
|
|
||||||
|
|
||||||
proxy = (task_proxy_t*)qse_httpd_gettaskxtn (httpd, task);
|
proxy = (task_proxy_t*)qse_httpd_gettaskxtn (httpd, task);
|
||||||
arg = (task_proxy_arg_t*)task->ctx;
|
arg = (task_proxy_arg_t*)task->ctx;
|
||||||
|
|
||||||
@ -756,9 +760,20 @@ static int task_init_proxy (
|
|||||||
proxy->method = qse_htre_getqmethodtype(arg->req);
|
proxy->method = qse_htre_getqmethodtype(arg->req);
|
||||||
proxy->version = *qse_htre_getversion(arg->req);
|
proxy->version = *qse_htre_getversion(arg->req);
|
||||||
proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
proxy->peer.nwad = arg->rsrc->dst;
|
|
||||||
proxy->peer.local = arg->rsrc->src;
|
if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_RAW) proxy->flags |= PROXY_RAW;
|
||||||
proxy->raw = arg->rsrc->raw;
|
proxy->peer.local = arg->rsrc->src.nwad;
|
||||||
|
if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_DST_STR)
|
||||||
|
{
|
||||||
|
proxy->flags |= PROXY_RESOL_PEER_NAME;
|
||||||
|
proxy->peer_name = (const qse_mchar_t*)(proxy + 1);
|
||||||
|
qse_mbscpy ((qse_mchar_t*)proxy->peer_name, arg->rsrc->dst.str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proxy->peer.nwad = arg->rsrc->dst.nwad;
|
||||||
|
}
|
||||||
|
|
||||||
/*if (arg->rsrc->src) proxy->peer.local = arg->rsrc->src;
|
/*if (arg->rsrc->src) proxy->peer.local = arg->rsrc->src;
|
||||||
else proxy->peer.local.type = arg->rsrc->dst.type;*/
|
else proxy->peer.local.type = arg->rsrc->dst.type;*/
|
||||||
|
|
||||||
@ -770,12 +785,12 @@ static int task_init_proxy (
|
|||||||
* -------------------------------------------------------------------- */
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* TODO: DETERMINE THIS SIZE */
|
/* TODO: DETERMINE THIS SIZE */
|
||||||
len = 4096;
|
len = MAX_SEND_SIZE;
|
||||||
|
|
||||||
proxy->reqfwdbuf = qse_mbs_open (httpd->mmgr, 0, (len < 512? 512: len));
|
proxy->reqfwdbuf = qse_mbs_open (httpd->mmgr, 0, (len < 512? 512: len));
|
||||||
if (proxy->reqfwdbuf == QSE_NULL) goto oops;
|
if (proxy->reqfwdbuf == QSE_NULL) goto oops;
|
||||||
|
|
||||||
if (proxy->raw)
|
if (proxy->flags & PROXY_RAW)
|
||||||
{
|
{
|
||||||
/* TODO: when connect is attempted, no keep-alive must be hornored.
|
/* TODO: when connect is attempted, no keep-alive must be hornored.
|
||||||
* when connection fails, it returns failure page followed by close.... */
|
* when connection fails, it returns failure page followed by close.... */
|
||||||
@ -792,6 +807,9 @@ static int task_init_proxy (
|
|||||||
{
|
{
|
||||||
int snatch_needed = 0;
|
int snatch_needed = 0;
|
||||||
|
|
||||||
|
/* compose a request to send to the peer using the request
|
||||||
|
* received from the client */
|
||||||
|
|
||||||
if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqmethodname(arg->req)) == (qse_size_t)-1 ||
|
if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqmethodname(arg->req)) == (qse_size_t)-1 ||
|
||||||
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 ||
|
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 ||
|
||||||
qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto oops;
|
qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto oops;
|
||||||
@ -808,8 +826,7 @@ static int task_init_proxy (
|
|||||||
|
|
||||||
proxy->resflags |= PROXY_RES_AWAIT_RESHDR;
|
proxy->resflags |= PROXY_RES_AWAIT_RESHDR;
|
||||||
if ((arg->req->attr.flags & QSE_HTRE_ATTR_EXPECT100) &&
|
if ((arg->req->attr.flags & QSE_HTRE_ATTR_EXPECT100) &&
|
||||||
(arg->req->version.major > 1 ||
|
(arg->req->version.major > 1 || (arg->req->version.major == 1 && arg->req->version.minor >= 1)))
|
||||||
(arg->req->version.major == 1 && arg->req->version.minor >= 1)))
|
|
||||||
{
|
{
|
||||||
proxy->resflags |= PROXY_RES_AWAIT_100;
|
proxy->resflags |= PROXY_RES_AWAIT_100;
|
||||||
}
|
}
|
||||||
@ -842,8 +859,7 @@ static int task_init_proxy (
|
|||||||
if (arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
if (arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
{
|
{
|
||||||
/* add trailers if any */
|
/* add trailers if any */
|
||||||
if (qse_htre_walktrailers (
|
if (qse_htre_walktrailers (arg->req, proxy_capture_client_trailer, proxy) <= -1) goto oops;
|
||||||
arg->req, proxy_capture_client_trailer, proxy) <= -1) goto oops;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = qse_htre_getcontentlen(arg->req);
|
len = qse_htre_getcontentlen(arg->req);
|
||||||
@ -961,7 +977,8 @@ printf ("init_proxy failed...........................................\n");
|
|||||||
qse_mbs_close (proxy->reqfwdbuf);
|
qse_mbs_close (proxy->reqfwdbuf);
|
||||||
proxy->reqfwdbuf = QSE_NULL;
|
proxy->reqfwdbuf = QSE_NULL;
|
||||||
}
|
}
|
||||||
proxy->init_failed = 1;
|
|
||||||
|
proxy->flags |= PROXY_INIT_FAILED;
|
||||||
task->ctx = proxy;
|
task->ctx = proxy;
|
||||||
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
@ -995,22 +1012,22 @@ static int task_main_proxy_5 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
/* if the client side is readable */
|
/* if the client side is readable */
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
if (!(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
||||||
(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||||
{
|
{
|
||||||
if (proxy->buflen > 0)
|
if (proxy->buflen > 0)
|
||||||
{
|
{
|
||||||
@ -1044,19 +1061,19 @@ static int task_main_proxy_4 (
|
|||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
@ -1082,7 +1099,7 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
/* peer closed connection */
|
/* peer closed connection */
|
||||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (!proxy->raw);
|
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
||||||
|
|
||||||
if (proxy->peer_output_received < proxy->peer_output_length)
|
if (proxy->peer_output_received < proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
@ -1095,12 +1112,12 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
task->main = task_main_proxy_5;
|
task->main = task_main_proxy_5;
|
||||||
|
|
||||||
/* nothing to read from peer. set the mask to 0 */
|
/* nothing to read from peer. set the mask to 0 */
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
|
|
||||||
/* arrange to be called if the client side is writable */
|
/* arrange to be called if the client side is writable */
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
|
||||||
if (proxy->raw)
|
if (proxy->flags & PROXY_RAW)
|
||||||
{
|
{
|
||||||
/* peer connection has been closed.
|
/* peer connection has been closed.
|
||||||
* so no more forwarding from the client to the peer
|
* so no more forwarding from the client to the peer
|
||||||
@ -1118,7 +1135,7 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (!proxy->raw);
|
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
||||||
|
|
||||||
if (proxy->peer_output_received > proxy->peer_output_length)
|
if (proxy->peer_output_received > proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
@ -1131,8 +1148,8 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
{
|
{
|
||||||
/* proxy has finished reading all */
|
/* proxy has finished reading all */
|
||||||
task->main = task_main_proxy_5;
|
task->main = task_main_proxy_5;
|
||||||
task->trigger[0].mask = 0;
|
task->trigger.v[0].mask = 0;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1169,20 +1186,20 @@ static int task_main_proxy_3 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
proxy_forward_client_input_to_peer (httpd, task, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
if (!(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
||||||
(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
qse_size_t count;
|
qse_size_t count;
|
||||||
@ -1218,13 +1235,13 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
|||||||
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
||||||
{
|
{
|
||||||
task->main = task_main_proxy_5;
|
task->main = task_main_proxy_5;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* arrange to read the remaining contents from the peer */
|
/* arrange to read the remaining contents from the peer */
|
||||||
task->main = task_main_proxy_4;
|
task->main = task_main_proxy_4;
|
||||||
task->trigger[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1241,22 +1258,22 @@ static int task_main_proxy_2 (
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
||||||
task->trigger[0].mask, task->trigger[1].mask, task->trigger[2].mask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.v[2].mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
/* client is readable */
|
/* client is readable */
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
}
|
}
|
||||||
else if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
if (!(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITE) ||
|
||||||
(task->trigger[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
(task->trigger.v[2].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE))
|
||||||
{
|
{
|
||||||
if (proxy->res_pending > 0)
|
if (proxy->res_pending > 0)
|
||||||
{
|
{
|
||||||
@ -1308,12 +1325,12 @@ qse_printf (QSE_T("]\n"));
|
|||||||
/* '100 Continue' and payload received together
|
/* '100 Continue' and payload received together
|
||||||
* has all been relayed back. no need for writability
|
* has all been relayed back. no need for writability
|
||||||
* check of the client side */
|
* check of the client side */
|
||||||
task->trigger[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
@ -1354,7 +1371,7 @@ qse_printf (QSE_T("]\n"));
|
|||||||
* case. call qse_htrd_halt() for this. */
|
* case. call qse_htrd_halt() for this. */
|
||||||
qse_htrd_halt (proxy->peer_htrd);
|
qse_htrd_halt (proxy->peer_htrd);
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1391,12 +1408,12 @@ qse_printf (QSE_T("]\n"));
|
|||||||
{
|
{
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else if (proxy->resflags & PROXY_RES_AWAIT_RESCON)
|
else if (proxy->resflags & PROXY_RES_AWAIT_RESCON)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else if (proxy->resflags & PROXY_RES_RECEIVED_RESHDR)
|
else if (proxy->resflags & PROXY_RES_RECEIVED_RESHDR)
|
||||||
{
|
{
|
||||||
@ -1406,7 +1423,7 @@ qse_printf (QSE_T("]\n"));
|
|||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
||||||
{
|
{
|
||||||
proxy->resflags |= PROXY_RES_AWAIT_RESCON;
|
proxy->resflags |= PROXY_RES_AWAIT_RESCON;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1415,14 +1432,14 @@ qse_printf (QSE_T("TRAILING DATA=%d, [%hs]\n"), (int)QSE_MBS_LEN(proxy->res), QS
|
|||||||
#endif
|
#endif
|
||||||
/* switch to the next phase */
|
/* switch to the next phase */
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (proxy->resflags & PROXY_RES_RECEIVED_100)
|
else if (proxy->resflags & PROXY_RES_RECEIVED_100)
|
||||||
{
|
{
|
||||||
/* 100 continue has been received but
|
/* 100 continue has been received but
|
||||||
* the actual response has not. */
|
* the actual response has not. */
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1446,8 +1463,8 @@ static int task_main_proxy_1 (
|
|||||||
int http_errnum = 500;
|
int http_errnum = 500;
|
||||||
|
|
||||||
/* wait for peer to get connected */
|
/* wait for peer to get connected */
|
||||||
if (task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE ||
|
if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE ||
|
||||||
task->trigger[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
@ -1474,10 +1491,10 @@ static int task_main_proxy_1 (
|
|||||||
|
|
||||||
if (proxy->req)
|
if (proxy->req)
|
||||||
{
|
{
|
||||||
task->trigger[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
task->trigger[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
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 */
|
||||||
@ -1487,13 +1504,13 @@ static int task_main_proxy_1 (
|
|||||||
/* there are still more to forward in the buffer
|
/* there are still more to forward in the buffer
|
||||||
* request the task invocation when the peer
|
* request the task invocation when the peer
|
||||||
* is writable */
|
* is writable */
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->raw)
|
if (proxy->flags & PROXY_RAW)
|
||||||
{
|
{
|
||||||
printf ("SWITCHING TO PROXY 3...%p\n", proxy->req);
|
/* inject http response */
|
||||||
if (qse_mbs_fmt (proxy->res, QSE_MT("HTTP/%d.%d 200 Connection established\r\n\r\n"),
|
if (qse_mbs_fmt (proxy->res, QSE_MT("HTTP/%d.%d 200 Connection established\r\n\r\n"),
|
||||||
(int)proxy->version.major, (int)proxy->version.minor) == (qse_size_t)-1)
|
(int)proxy->version.major, (int)proxy->version.minor) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
@ -1504,7 +1521,7 @@ printf ("SWITCHING TO PROXY 3...%p\n", proxy->req);
|
|||||||
|
|
||||||
/* arrange to be called if the client side is writable.
|
/* arrange to be called if the client side is writable.
|
||||||
* it must write the injected response. */
|
* it must write the injected response. */
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1520,6 +1537,30 @@ oops:
|
|||||||
return (qse_httpd_entask_err (httpd, client, task, http_errnum, proxy->method, &proxy->version, proxy->keepalive) == QSE_NULL)? -1: 0;
|
return (qse_httpd_entask_err (httpd, client, task, http_errnum, proxy->method, &proxy->version, proxy->keepalive) == QSE_NULL)? -1: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_peer_name_resolved (qse_httpd_t* httpd, const qse_nwad_t* nwad, void* ctx)
|
||||||
|
{
|
||||||
|
qse_httpd_task_t* task = (qse_httpd_task_t*)ctx;
|
||||||
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
|
QSE_ASSERT (proxy->flags & PROXY_RESOL_PEER_NAME);
|
||||||
|
|
||||||
|
task->trigger.flags &= ~QSE_HTTPD_TASK_TRIGGER_INACTIVE;
|
||||||
|
|
||||||
|
if (nwad)
|
||||||
|
{
|
||||||
|
/* resolved successfully */
|
||||||
|
proxy->flags &= ~PROXY_RESOL_PEER_NAME;
|
||||||
|
proxy->peer.nwad = *nwad;
|
||||||
|
if (proxy->peer.local.type == QSE_NWAD_NX)
|
||||||
|
proxy->peer.local.type = proxy->peer.nwad.type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* resolution failure. */
|
||||||
|
proxy->flags |= PROXY_INIT_FAILED | PROXY_UNKNOWN_PEER_NWAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int task_main_proxy (
|
static int task_main_proxy (
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
{
|
{
|
||||||
@ -1528,9 +1569,22 @@ static int task_main_proxy (
|
|||||||
int http_errnum = 500;
|
int http_errnum = 500;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (proxy->init_failed) goto oops;
|
if (proxy->flags & PROXY_INIT_FAILED)
|
||||||
|
{
|
||||||
|
if (proxy->flags & PROXY_UNKNOWN_PEER_NWAD) http_errnum = 404; /* 404 Not Found */
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (!proxy->raw)
|
if (proxy->flags & PROXY_RESOL_PEER_NAME)
|
||||||
|
{
|
||||||
|
/* arrange to resolve a host name and return */
|
||||||
|
QSE_ASSERT (proxy->peer_name != QSE_NULL);
|
||||||
|
task->trigger.flags |= QSE_HTTPD_TASK_TRIGGER_INACTIVE;
|
||||||
|
if (qse_httpd_resolname (httpd, proxy->peer_name, on_peer_name_resolved, task)) goto oops;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(proxy->flags & PROXY_RAW))
|
||||||
{
|
{
|
||||||
/* set up a http reader to read a response from the peer */
|
/* set up a http reader to read a response from the peer */
|
||||||
proxy->peer_htrd = qse_htrd_open (
|
proxy->peer_htrd = qse_htrd_open (
|
||||||
@ -1564,14 +1618,14 @@ static int task_main_proxy (
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy->peer_status |= PROXY_PEER_OPEN;
|
proxy->peer_status |= PROXY_PEER_OPEN;
|
||||||
task->trigger[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[0].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
task->trigger[0].handle = proxy->peer.handle;
|
task->trigger.v[0].handle = proxy->peer.handle;
|
||||||
task->trigger[2].handle = client->handle;
|
task->trigger.v[2].handle = client->handle;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* peer not connected yet */
|
/* peer not connected yet */
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
task->main = task_main_proxy_1;
|
task->main = task_main_proxy_1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1580,7 +1634,7 @@ static int task_main_proxy (
|
|||||||
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
||||||
if (proxy->req)
|
if (proxy->req)
|
||||||
{
|
{
|
||||||
task->trigger[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.v[2].mask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||||
@ -1588,13 +1642,12 @@ static int task_main_proxy (
|
|||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
proxy_forward_client_input_to_peer (httpd, task, 0);
|
||||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) > 0)
|
||||||
{
|
{
|
||||||
task->trigger[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[0].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->raw)
|
if (proxy->flags & PROXY_RAW)
|
||||||
{
|
{
|
||||||
/* TODO: write response */
|
|
||||||
/* inject http response */
|
/* inject http response */
|
||||||
if (qse_mbs_fmt (proxy->res, QSE_MT("HTTP/%d.%d 200 Connection established\r\n\r\n"),
|
if (qse_mbs_fmt (proxy->res, QSE_MT("HTTP/%d.%d 200 Connection established\r\n\r\n"),
|
||||||
(int)proxy->version.major, (int)proxy->version.minor) == (qse_size_t)-1)
|
(int)proxy->version.major, (int)proxy->version.minor) == (qse_size_t)-1)
|
||||||
@ -1606,7 +1659,7 @@ static int task_main_proxy (
|
|||||||
|
|
||||||
/* arrange to be called if the client side is writable.
|
/* arrange to be called if the client side is writable.
|
||||||
* it must write the injected response. */
|
* it must write the injected response. */
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger.v[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1645,10 +1698,14 @@ qse_httpd_task_t* qse_httpd_entaskproxy (
|
|||||||
{
|
{
|
||||||
qse_httpd_task_t task;
|
qse_httpd_task_t task;
|
||||||
task_proxy_arg_t arg;
|
task_proxy_arg_t arg;
|
||||||
|
qse_size_t xtnsize = 0;
|
||||||
|
|
||||||
arg.rsrc = proxy;
|
arg.rsrc = proxy;
|
||||||
arg.req = req;
|
arg.req = req;
|
||||||
|
|
||||||
|
if (proxy->flags & QSE_HTTPD_RSRC_PROXY_DST_STR)
|
||||||
|
xtnsize = qse_mbslen (proxy->dst.str) + 1;
|
||||||
|
|
||||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
||||||
task.init = task_init_proxy;
|
task.init = task_init_proxy;
|
||||||
task.fini = task_fini_proxy;
|
task.fini = task_fini_proxy;
|
||||||
@ -1656,7 +1713,7 @@ qse_httpd_task_t* qse_httpd_entaskproxy (
|
|||||||
task.ctx = &arg;
|
task.ctx = &arg;
|
||||||
|
|
||||||
return qse_httpd_entask (
|
return qse_httpd_entask (
|
||||||
httpd, client, pred, &task, QSE_SIZEOF(task_proxy_t)
|
httpd, client, pred, &task, QSE_SIZEOF(task_proxy_t) + xtnsize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
Copyright 2006-2014 Chung, Hyung-Hwan.
|
|
||||||
This file is part of QSE.
|
|
||||||
|
|
||||||
QSE is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as
|
|
||||||
published by the Free Software Foundation, either version 3 of
|
|
||||||
the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
QSE is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with QSE. If not, see <htrd://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
|
|
||||||
/* UNSUPPORTED YET.. */
|
|
||||||
/* TODO: IMPLEMENT THIS */
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include "httpd.h"
|
|
||||||
#include "../cmn/mem.h"
|
|
||||||
|
|
||||||
typedef struct task_resol_arg_t task_resol_arg_t;
|
|
||||||
struct task_resol_arg_t
|
|
||||||
{
|
|
||||||
const qse_mchar_t* host;
|
|
||||||
const qse_htre_t* req;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct task_resol_t task_resol_t;
|
|
||||||
struct task_resol_t
|
|
||||||
{
|
|
||||||
int init_failed;
|
|
||||||
qse_httpd_t* httpd;
|
|
||||||
|
|
||||||
int method;
|
|
||||||
qse_http_version_t version;
|
|
||||||
int keepalive; /* taken from the request */
|
|
||||||
|
|
||||||
qse_mchar_t* host;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int task_init_resol (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
task_resol_t* resol;
|
|
||||||
task_resol_arg_t* arg;
|
|
||||||
|
|
||||||
resol = (task_resol_t*)qse_httpd_gettaskxtn (httpd, task);
|
|
||||||
arg = (task_resol_arg_t*)task->ctx;
|
|
||||||
|
|
||||||
QSE_MEMSET (resol, 0, QSE_SIZEOF(*resol));
|
|
||||||
resol->httpd = httpd;
|
|
||||||
|
|
||||||
resol->method = qse_htre_getqmethodtype(arg->req);
|
|
||||||
resol->version = *qse_htre_getversion(arg->req);
|
|
||||||
resol->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
|
||||||
|
|
||||||
resol->host = (qse_mchar_t*)(resol + 1);
|
|
||||||
qse_mbscpy (resol->host, arg->host);
|
|
||||||
|
|
||||||
task->ctx = resol;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void task_fini_resol (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
task_resol_t* resol = (task_resol_t*)task->ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int task_main_resol (
|
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
|
||||||
/* dns.open ();
|
|
||||||
|
|
||||||
dns.send (...);
|
|
||||||
|
|
||||||
dns.close ();*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
qse_httpd_task_t* qse_httpd_entaskresol (
|
|
||||||
qse_httpd_t* httpd,
|
|
||||||
qse_httpd_client_t* client,
|
|
||||||
qse_httpd_task_t* pred,
|
|
||||||
const qse_mchar_t* host,
|
|
||||||
qse_htre_t* req)
|
|
||||||
{
|
|
||||||
qse_httpd_task_t task;
|
|
||||||
task_resol_arg_t arg;
|
|
||||||
|
|
||||||
arg.host = host;
|
|
||||||
arg.req = req;
|
|
||||||
|
|
||||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
|
||||||
task.init = task_init_resol;
|
|
||||||
task.fini = task_fini_resol;
|
|
||||||
task.main = task_main_resol;
|
|
||||||
task.ctx = &arg;
|
|
||||||
|
|
||||||
return qse_httpd_entask (
|
|
||||||
httpd, client, pred, &task, QSE_SIZEOF(task_resol_t) + qse_mbslen(host) + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -363,7 +363,6 @@ static qse_httpd_errnum_t direrr_to_errnum (qse_dir_errnum_t e)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define MAX_SEND_SIZE 4096
|
|
||||||
|
|
||||||
static QSE_INLINE qse_ssize_t __send_file (
|
static QSE_INLINE qse_ssize_t __send_file (
|
||||||
qse_httpd_t* httpd, int out_fd, qse_ubi_t in_fd,
|
qse_httpd_t* httpd, int out_fd, qse_ubi_t in_fd,
|
||||||
@ -1961,6 +1960,28 @@ static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------- */
|
||||||
|
static int dns_open (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dns_close (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dns_recv (qse_httpd_t* httpd, qse_httpd_dns_t* dns)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dns_send (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
#if 0
|
#if 0
|
||||||
static qse_htb_walk_t walk (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx)
|
static qse_htb_walk_t walk (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx)
|
||||||
@ -2260,7 +2281,14 @@ static qse_httpd_scb_t httpd_system_callbacks =
|
|||||||
client_send,
|
client_send,
|
||||||
client_sendfile,
|
client_sendfile,
|
||||||
client_accepted,
|
client_accepted,
|
||||||
client_closed }
|
client_closed },
|
||||||
|
|
||||||
|
|
||||||
|
/* dns */
|
||||||
|
{ dns_open,
|
||||||
|
dns_close,
|
||||||
|
dns_recv,
|
||||||
|
dns_send }
|
||||||
};
|
};
|
||||||
|
|
||||||
static qse_httpd_rcb_t httpd_request_callbacks =
|
static qse_httpd_rcb_t httpd_request_callbacks =
|
||||||
@ -2549,12 +2577,23 @@ static int make_resource (
|
|||||||
if (mth == QSE_HTTP_CONNECT)
|
if (mth == QSE_HTTP_CONNECT)
|
||||||
{
|
{
|
||||||
/* TODO: query if CONNECT is allowed */
|
/* TODO: query if CONNECT is allowed */
|
||||||
|
/* TODO: check on what conditions CONNECT is allowed. */
|
||||||
|
/* TODO: disallow connecting back to self */
|
||||||
/* TODO: Proxy-Authorization???? */
|
/* TODO: Proxy-Authorization???? */
|
||||||
target->type = QSE_HTTPD_RSRC_PROXY;
|
|
||||||
target->u.proxy.raw = 1;
|
|
||||||
|
|
||||||
if (qse_mbstonwad (qse_htre_getqpath(req), &target->u.proxy.dst) <= -1) return -1;
|
target->type = QSE_HTTPD_RSRC_PROXY;
|
||||||
target->u.proxy.src.type = target->u.proxy.dst.type;
|
target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_RAW;
|
||||||
|
|
||||||
|
if (qse_mbstonwad (qse_htre_getqpath(req), &target->u.proxy.dst.nwad) <= -1)
|
||||||
|
{
|
||||||
|
target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_DST_STR;
|
||||||
|
target->u.proxy.dst.str = qse_htre_getqpath(req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* make the source binding type the same as destination */
|
||||||
|
target->u.proxy.src.nwad.type = target->u.proxy.dst.nwad.type;
|
||||||
|
}
|
||||||
|
|
||||||
/* mark that this request is going to be proxied. */
|
/* mark that this request is going to be proxied. */
|
||||||
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||||
@ -2567,14 +2606,14 @@ static int make_resource (
|
|||||||
case QSE_HTTPD_SERVERSTD_ROOT_NWAD:
|
case QSE_HTTPD_SERVERSTD_ROOT_NWAD:
|
||||||
/* proxy the request */
|
/* proxy the request */
|
||||||
target->type = QSE_HTTPD_RSRC_PROXY;
|
target->type = QSE_HTTPD_RSRC_PROXY;
|
||||||
target->u.proxy.raw = 0;
|
target->u.proxy.flags = 0;
|
||||||
|
|
||||||
/* transparent proxy may do the following
|
/* transparent proxy may do the following
|
||||||
target->u.proxy.dst = client->orgdst_addr;
|
target->u.proxy.dst = client->orgdst_addr;
|
||||||
target->u.proxy.src = client->remote_addr;
|
target->u.proxy.src = client->remote_addr;
|
||||||
*/
|
*/
|
||||||
target->u.proxy.dst = tmp.root.u.nwad;
|
target->u.proxy.dst.nwad = tmp.root.u.nwad;
|
||||||
target->u.proxy.src.type = target->u.proxy.dst.type;
|
target->u.proxy.src.nwad.type = target->u.proxy.dst.nwad.type;
|
||||||
|
|
||||||
/* mark that this request is going to be proxied. */
|
/* mark that this request is going to be proxied. */
|
||||||
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||||
|
@ -322,12 +322,13 @@ static QSE_INLINE int dequeue_task (
|
|||||||
task = (qse_httpd_real_task_t*)client->task.head;
|
task = (qse_httpd_real_task_t*)client->task.head;
|
||||||
|
|
||||||
/* clear task triggers from mux if they are registered */
|
/* clear task triggers from mux if they are registered */
|
||||||
for (i = 0; i < QSE_COUNTOF(task->core.trigger); i++)
|
for (i = 0; i < QSE_COUNTOF(task->core.trigger.v); i++)
|
||||||
{
|
{
|
||||||
if (client->status & CLIENT_TASK_TRIGGER_IN_MUX(i))
|
if (client->status & CLIENT_TASK_TRIGGER_RW_IN_MUX(i))
|
||||||
{
|
{
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, task->core.trigger[i].handle);
|
QSE_ASSERT (task->core.trigger.v[i].handle.i != client->handle.i);
|
||||||
client->status &= ~CLIENT_TASK_TRIGGER_IN_MUX(i);
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, task->core.trigger.v[i].handle);
|
||||||
|
client->status &= ~CLIENT_TASK_TRIGGER_RW_IN_MUX(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,8 +405,7 @@ static qse_httpd_client_t* new_client (
|
|||||||
/* copy the public fields,
|
/* copy the public fields,
|
||||||
* keep the private fields initialized at 0 */
|
* keep the private fields initialized at 0 */
|
||||||
client->status = tmpl->status;
|
client->status = tmpl->status;
|
||||||
if (httpd->opt.scb.client.accepted == QSE_NULL)
|
if (httpd->opt.scb.client.accepted == QSE_NULL) client->status |= CLIENT_READY;
|
||||||
client->status |= CLIENT_READY;
|
|
||||||
client->handle = tmpl->handle;
|
client->handle = tmpl->handle;
|
||||||
client->handle2 = tmpl->handle2;
|
client->handle2 = tmpl->handle2;
|
||||||
client->remote_addr = tmpl->remote_addr;
|
client->remote_addr = tmpl->remote_addr;
|
||||||
@ -436,10 +436,10 @@ static void free_client (
|
|||||||
qse_printf (QSE_T("Debug: CLOSING SOCKET %d\n"), client->handle.i);
|
qse_printf (QSE_T("Debug: CLOSING SOCKET %d\n"), client->handle.i);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (client->status & CLIENT_HANDLE_IN_MUX)
|
if (client->status & CLIENT_HANDLE_RW_IN_MUX)
|
||||||
{
|
{
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
||||||
client->status &= ~CLIENT_HANDLE_IN_MUX;
|
client->status &= ~CLIENT_HANDLE_RW_IN_MUX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note that client.closed is not a counterpart to client.accepted.
|
/* note that client.closed is not a counterpart to client.accepted.
|
||||||
@ -544,10 +544,9 @@ qse_printf (QSE_T("failed to accept from server [%s] [%d]\n"), tmp, server->hand
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("MUX ADDHND CLIENT READ %d\n"), client->handle.i);
|
printf ("MUX ADDHND CLIENT READ %d\n", client->handle.i);
|
||||||
#endif
|
#endif
|
||||||
if (httpd->opt.scb.mux.addhnd (
|
if (httpd->opt.scb.mux.addhnd (httpd, mux, client->handle, QSE_HTTPD_MUX_READ, client) <= -1)
|
||||||
httpd, mux, client->handle, QSE_HTTPD_MUX_READ, client) <= -1)
|
|
||||||
{
|
{
|
||||||
free_client (httpd, client);
|
free_client (httpd, client);
|
||||||
return -1;
|
return -1;
|
||||||
@ -756,11 +755,33 @@ qse_httpd_dns_t* qse_httpd_attachdns (qse_httpd_t* httpd, qse_httpd_dns_dope_t*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int activate_dns (qse_httpd_t* httpd)
|
||||||
|
{
|
||||||
|
if (httpd->opt.scb.dns.open (httpd, &httpd->dns) <= -1) return -1;
|
||||||
|
|
||||||
|
httpd->dns.type = QSE_HTTPD_DNS;
|
||||||
|
|
||||||
|
if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, httpd->dns.handle, QSE_HTTPD_MUX_READ, &httpd->dns) <= -1)
|
||||||
|
{
|
||||||
|
httpd->opt.scb.dns.close (httpd, &httpd->dns);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//httpd->dns = dns;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deactivate_dns (qse_httpd_t* httpd)
|
||||||
|
{
|
||||||
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, httpd->dns.handle);
|
||||||
|
httpd->opt.scb.dns.close (httpd, &httpd->dns);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int read_from_client (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
static int read_from_client (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||||
{
|
{
|
||||||
qse_mchar_t buf[4096]; /* TODO: adjust this buffer size */
|
qse_mchar_t buf[MAX_RECV_SIZE]; /* TODO: adjust this buffer size */
|
||||||
qse_ssize_t m;
|
qse_ssize_t m;
|
||||||
|
|
||||||
QSE_ASSERT (httpd->opt.scb.client.recv != QSE_NULL);
|
QSE_ASSERT (httpd->opt.scb.client.recv != QSE_NULL);
|
||||||
@ -896,170 +917,206 @@ static int update_mux_for_current_task (qse_httpd_t* httpd, qse_httpd_client_t*
|
|||||||
* that something can go wrong if the task handler plays
|
* that something can go wrong if the task handler plays
|
||||||
* with the trigger field in an unexpected manner.
|
* with the trigger field in an unexpected manner.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < QSE_COUNTOF(task->trigger); i++)
|
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||||
{
|
{
|
||||||
task->trigger[i].mask &= ~(QSE_HTTPD_TASK_TRIGGER_READABLE |
|
task->trigger.v[i].mask &= ~(QSE_HTTPD_TASK_TRIGGER_READABLE |
|
||||||
QSE_HTTPD_TASK_TRIGGER_WRITABLE);
|
QSE_HTTPD_TASK_TRIGGER_WRITABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QSE_MEMCMP (client->trigger, task->trigger, QSE_SIZEOF(client->trigger)) != 0 ||
|
if (QSE_MEMCMP (&client->trigger, &task->trigger, QSE_SIZEOF(client->trigger)) != 0 ||
|
||||||
((client->status & CLIENT_MUTE) && !(client->status & CLIENT_MUTE_DELETED)))
|
((client->status & CLIENT_MUTE) && !(client->status & CLIENT_MUTE_DELETED)))
|
||||||
{
|
{
|
||||||
/* manipulate muxtiplexer settings if there are trigger changes */
|
/* manipulate muxtiplexer settings if there are trigger changes */
|
||||||
|
|
||||||
int has_trigger;
|
int has_trigger = 0;
|
||||||
int trigger_mux_mask;
|
int expected_client_handle_mux_mask_from_trigger = 0;
|
||||||
int client_handle_mux_mask;
|
int expected_client_handle_mux_mask;
|
||||||
int client_handle_mux_status;
|
int expected_client_handle_mux_status;
|
||||||
|
|
||||||
/* delete previous trigger handles */
|
/* delete previous trigger handles */
|
||||||
for (i = 0; i < QSE_COUNTOF(task->trigger); i++)
|
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||||
{
|
{
|
||||||
if (client->status & CLIENT_TASK_TRIGGER_IN_MUX(i))
|
if (client->status & CLIENT_TASK_TRIGGER_RW_IN_MUX(i))
|
||||||
{
|
{
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->trigger[i].handle);
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->trigger.v[i].handle);
|
||||||
client->status &= ~CLIENT_TASK_TRIGGER_IN_MUX(i);
|
client->status &= ~CLIENT_TASK_TRIGGER_RW_IN_MUX(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
has_trigger = 0;
|
|
||||||
client_handle_mux_mask = 0;
|
|
||||||
client_handle_mux_status = 0;
|
|
||||||
if (client->status & CLIENT_MUTE)
|
|
||||||
{
|
|
||||||
client->status |= CLIENT_MUTE_DELETED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client_handle_mux_mask |= QSE_HTTPD_MUX_READ;
|
|
||||||
client_handle_mux_status |= CLIENT_HANDLE_READ_IN_MUX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add new trigger handles */
|
/* add new trigger handles */
|
||||||
for (i = 0; i < QSE_COUNTOF(task->trigger); i++)
|
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||||
{
|
{
|
||||||
trigger_mux_mask = 0;
|
int expected_trigger_mux_mask = 0;
|
||||||
if (task->trigger[i].mask & QSE_HTTPD_TASK_TRIGGER_READ)
|
int expected_trigger_mux_status = 0;
|
||||||
{
|
|
||||||
if (task->trigger[i].handle.i != client->handle.i ||
|
|
||||||
!(client->status & CLIENT_MUTE))
|
|
||||||
{
|
|
||||||
trigger_mux_mask |= QSE_HTTPD_MUX_READ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (task->trigger[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE)
|
|
||||||
trigger_mux_mask |= QSE_HTTPD_MUX_WRITE;
|
|
||||||
|
|
||||||
if (trigger_mux_mask)
|
if (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_READ)
|
||||||
|
{
|
||||||
|
if (task->trigger.v[i].handle.i != client->handle.i || !(client->status & CLIENT_MUTE))
|
||||||
|
{
|
||||||
|
expected_trigger_mux_mask |= QSE_HTTPD_MUX_READ;
|
||||||
|
expected_trigger_mux_status |= CLIENT_TASK_TRIGGER_READ_IN_MUX(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE)
|
||||||
|
{
|
||||||
|
expected_trigger_mux_mask |= QSE_HTTPD_MUX_WRITE;
|
||||||
|
expected_trigger_mux_status |= CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected_trigger_mux_mask)
|
||||||
{
|
{
|
||||||
has_trigger = 1;
|
has_trigger = 1;
|
||||||
|
|
||||||
if (task->trigger[i].handle.i == client->handle.i) /* TODO: no direct comparsion */
|
if (task->trigger.v[i].handle.i == client->handle.i) /* TODO: no direct comparsion */
|
||||||
{
|
{
|
||||||
/* if the client handle is included in the trigger,
|
/* if the client handle is included in the trigger,
|
||||||
* delay its manipulation until the loop is over.
|
* delay its manipulation until the loop is over.
|
||||||
* instead, just remember what mask is requested */
|
* instead, just remember what mask is requested */
|
||||||
client_handle_mux_mask |= trigger_mux_mask;
|
expected_client_handle_mux_mask_from_trigger |= expected_trigger_mux_mask;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (httpd->opt.scb.mux.addhnd (
|
if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, task->trigger.v[i].handle, expected_trigger_mux_mask, client) <= -1)
|
||||||
httpd, httpd->mux, task->trigger[i].handle,
|
|
||||||
trigger_mux_mask, client) <= -1)
|
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
client->status |= CLIENT_TASK_TRIGGER_IN_MUX(i);
|
client->status |= expected_trigger_mux_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_handle_mux_mask)
|
expected_client_handle_mux_mask = QSE_HTTPD_MUX_READ;
|
||||||
|
expected_client_handle_mux_status = CLIENT_HANDLE_READ_IN_MUX;
|
||||||
|
|
||||||
|
if (expected_client_handle_mux_mask_from_trigger)
|
||||||
{
|
{
|
||||||
/* if the client handle is included in the trigger
|
expected_client_handle_mux_mask |= expected_client_handle_mux_mask_from_trigger;
|
||||||
* and writing is requested, arrange writing to be
|
if (expected_client_handle_mux_mask_from_trigger & QSE_HTTPD_MUX_WRITE)
|
||||||
* enabled */
|
expected_client_handle_mux_status |= CLIENT_HANDLE_READ_IN_MUX;
|
||||||
if (client_handle_mux_mask & QSE_HTTPD_MUX_WRITE)
|
if (expected_client_handle_mux_mask_from_trigger & QSE_HTTPD_MUX_WRITE)
|
||||||
client_handle_mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
expected_client_handle_mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
||||||
}
|
|
||||||
else if (!has_trigger)
|
|
||||||
{
|
|
||||||
/* if there is no trigger, writing should be enabled */
|
|
||||||
client_handle_mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
|
||||||
client_handle_mux_mask |= QSE_HTTPD_MUX_WRITE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((client->status & CLIENT_HANDLE_IN_MUX) !=
|
if (!expected_client_handle_mux_status && !has_trigger)
|
||||||
(client_handle_mux_status & CLIENT_HANDLE_IN_MUX))
|
{
|
||||||
|
/* if there is no trigger and the client handle is to be excluded
|
||||||
|
* from reading and writing, writing should be enabled. */
|
||||||
|
expected_client_handle_mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
||||||
|
expected_client_handle_mux_mask |= QSE_HTTPD_MUX_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->status & CLIENT_MUTE)
|
||||||
|
{
|
||||||
|
/* readking should be excluded from mux if the client-side has
|
||||||
|
* been closed */
|
||||||
|
client->status |= CLIENT_MUTE_DELETED;
|
||||||
|
expected_client_handle_mux_mask &= ~QSE_HTTPD_MUX_READ;
|
||||||
|
expected_client_handle_mux_status &= ~CLIENT_HANDLE_READ_IN_MUX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((client->status & CLIENT_HANDLE_RW_IN_MUX) != expected_client_handle_mux_status)
|
||||||
{
|
{
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
||||||
client->status &= ~CLIENT_HANDLE_IN_MUX;
|
client->status &= ~CLIENT_HANDLE_RW_IN_MUX;
|
||||||
|
|
||||||
if (client_handle_mux_mask)
|
QSE_ASSERT (expected_client_handle_mux_status & CLIENT_HANDLE_RW_IN_MUX);
|
||||||
{
|
if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, client->handle, expected_client_handle_mux_mask, client) <= -1) return -1;
|
||||||
if (httpd->opt.scb.mux.addhnd (
|
client->status |= expected_client_handle_mux_status;
|
||||||
httpd, httpd->mux, client->handle,
|
|
||||||
client_handle_mux_mask, client) <= -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
client->status |= client_handle_mux_status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_MEMCPY (client->trigger, task->trigger, QSE_SIZEOF(client->trigger));
|
/* save the task trigger information */
|
||||||
|
client->trigger = task->trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update_mux_for_new_task (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||||
|
{
|
||||||
|
/* this task is the first task to activate.
|
||||||
|
*
|
||||||
|
* the client handle should be in mux for reading at this phase.
|
||||||
|
* a new task should be invoked at least once regardless of the
|
||||||
|
* data availablility(read) on the client side. arrange to invoke
|
||||||
|
* this task so long as the client-side handle is writable as well
|
||||||
|
* as when data is available for reading. */
|
||||||
|
|
||||||
|
int expected_mux_mask;
|
||||||
|
int expected_mux_status;
|
||||||
|
|
||||||
|
QSE_ASSERT (client->status & CLIENT_HANDLE_RW_IN_MUX);
|
||||||
|
|
||||||
|
expected_mux_mask = QSE_HTTPD_MUX_READ | QSE_HTTPD_MUX_WRITE;
|
||||||
|
expected_mux_status = CLIENT_HANDLE_RW_IN_MUX;
|
||||||
|
|
||||||
|
if ((client->status & CLIENT_HANDLE_RW_IN_MUX) != expected_mux_status)
|
||||||
|
{
|
||||||
|
/* no updating is needed if the client handle is in mux for
|
||||||
|
* both reading and writing. if not, the handle must be
|
||||||
|
* re-registered for both reading and writing. */
|
||||||
|
|
||||||
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
||||||
|
client->status &= ~CLIENT_HANDLE_RW_IN_MUX;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf ("MUX ADDHND CLIENT RW(ENTASK) %d\n", client->handle.i);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSE_ASSERT (expected_mux_status & CLIENT_HANDLE_RW_IN_MUX);
|
||||||
|
if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, client->handle, expected_mux_mask, client) <= -1) return -1;
|
||||||
|
client->status |= expected_mux_status;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_mux_for_next_task (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
static int update_mux_for_next_task (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
||||||
{
|
{
|
||||||
int mux_mask;
|
int expected_mux_mask;
|
||||||
int mux_status;
|
int expected_mux_status;
|
||||||
|
|
||||||
|
expected_mux_mask = QSE_HTTPD_MUX_READ;
|
||||||
|
expected_mux_status = CLIENT_HANDLE_READ_IN_MUX;
|
||||||
|
|
||||||
mux_mask = QSE_HTTPD_MUX_READ;
|
|
||||||
mux_status = CLIENT_HANDLE_READ_IN_MUX;
|
|
||||||
if (client->task.head)
|
if (client->task.head)
|
||||||
{
|
{
|
||||||
/* there is a pending task. arrange to
|
/* there is a pending task. arrange to trigger it as if it is
|
||||||
* trigger it as if it is just entasked */
|
* just entasked. */
|
||||||
mux_mask |= QSE_HTTPD_MUX_WRITE;
|
expected_mux_mask |= QSE_HTTPD_MUX_WRITE;
|
||||||
mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
expected_mux_status |= CLIENT_HANDLE_WRITE_IN_MUX;
|
||||||
|
|
||||||
if (client->status & CLIENT_MUTE)
|
if (client->status & CLIENT_MUTE)
|
||||||
{
|
{
|
||||||
mux_mask &= ~QSE_HTTPD_MUX_READ;
|
/* when client-side has been disconnected, it can't read
|
||||||
mux_status &= ~CLIENT_HANDLE_READ_IN_MUX;
|
* from the side any more. so exclude reading */
|
||||||
|
expected_mux_mask &= ~QSE_HTTPD_MUX_READ;
|
||||||
|
expected_mux_status &= ~CLIENT_HANDLE_READ_IN_MUX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* there is no pending task to invoke */
|
||||||
if (client->status & CLIENT_MUTE)
|
if (client->status & CLIENT_MUTE)
|
||||||
{
|
{
|
||||||
/* no more task. but this client
|
/* and this client has closed connection previously.
|
||||||
* has closed connection previously */
|
* if not, reading would be the only clue to mux for
|
||||||
|
* invocation. return failure as reading from the client-side
|
||||||
|
* is not possible */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((client->status & CLIENT_HANDLE_IN_MUX) !=
|
if ((client->status & CLIENT_HANDLE_RW_IN_MUX) != expected_mux_status)
|
||||||
(mux_status & CLIENT_HANDLE_IN_MUX))
|
|
||||||
{
|
{
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
||||||
client->status &= ~CLIENT_HANDLE_IN_MUX;
|
client->status &= ~CLIENT_HANDLE_RW_IN_MUX;
|
||||||
|
|
||||||
if (mux_status)
|
QSE_ASSERT (expected_mux_status & CLIENT_HANDLE_RW_IN_MUX);
|
||||||
{
|
if (httpd->opt.scb.mux.addhnd (httpd, httpd->mux, client->handle, expected_mux_mask, client) <= -1) return -1;
|
||||||
if (httpd->opt.scb.mux.addhnd (
|
client->status |= expected_mux_status;
|
||||||
httpd, httpd->mux, client->handle, mux_mask, client) <= -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
client->status |= mux_status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSE_MEMSET (client->trigger, 0, QSE_SIZEOF(client->trigger));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,24 +1158,24 @@ static int invoke_client_task (
|
|||||||
trigger_fired = 0;
|
trigger_fired = 0;
|
||||||
client_handle_writable = 0;
|
client_handle_writable = 0;
|
||||||
|
|
||||||
for (i = 0; i < QSE_COUNTOF(task->trigger); i++)
|
for (i = 0; i < QSE_COUNTOF(task->trigger.v); i++)
|
||||||
{
|
{
|
||||||
task->trigger[i].mask &= ~(QSE_HTTPD_TASK_TRIGGER_READABLE |
|
task->trigger.v[i].mask &= ~(QSE_HTTPD_TASK_TRIGGER_READABLE |
|
||||||
QSE_HTTPD_TASK_TRIGGER_WRITABLE);
|
QSE_HTTPD_TASK_TRIGGER_WRITABLE);
|
||||||
|
|
||||||
if (task->trigger[i].handle.i == handle.i) /* TODO: no direct comparision */
|
if (task->trigger.v[i].handle.i == handle.i) /* TODO: no direct comparision */
|
||||||
{
|
{
|
||||||
if (mask & QSE_HTTPD_MUX_READ)
|
if (mask & QSE_HTTPD_MUX_READ)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (task->trigger[i].mask & QSE_HTTPD_TASK_TRIGGER_READ);
|
QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_READ);
|
||||||
trigger_fired = 1;
|
trigger_fired = 1;
|
||||||
task->trigger[i].mask |= QSE_HTTPD_TASK_TRIGGER_READABLE;
|
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_READABLE;
|
||||||
}
|
}
|
||||||
if (mask & QSE_HTTPD_MUX_WRITE)
|
if (mask & QSE_HTTPD_MUX_WRITE)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (task->trigger[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE);
|
QSE_ASSERT (task->trigger.v[i].mask & QSE_HTTPD_TASK_TRIGGER_WRITE);
|
||||||
trigger_fired = 1;
|
trigger_fired = 1;
|
||||||
task->trigger[i].mask |= QSE_HTTPD_TASK_TRIGGER_WRITABLE;
|
task->trigger.v[i].mask |= QSE_HTTPD_TASK_TRIGGER_WRITABLE;
|
||||||
if (handle.i == client->handle.i) client_handle_writable = 1; /* TODO: no direct comparison */
|
if (handle.i == client->handle.i) client_handle_writable = 1; /* TODO: no direct comparison */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1139,23 +1196,25 @@ static int invoke_client_task (
|
|||||||
}
|
}
|
||||||
|
|
||||||
n = task->main (httpd, client, task);
|
n = task->main (httpd, client, task);
|
||||||
if (n <= -1)
|
if (n == 0)
|
||||||
{
|
|
||||||
/* task error */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (n == 0)
|
|
||||||
{
|
{
|
||||||
/* the current task is over. remove the task
|
/* the current task is over. remove the task
|
||||||
* from the queue. dequeue_task() clears task triggers
|
* from the queue. dequeue_task() clears task triggers
|
||||||
* from the mux. so i don't clear them explicitly here */
|
* from the mux. so i don't clear them explicitly here */
|
||||||
dequeue_task (httpd, client);
|
dequeue_task (httpd, client);
|
||||||
return update_mux_for_next_task (httpd, client);
|
|
||||||
|
/* update the multiplexer settings */
|
||||||
|
n = update_mux_for_next_task (httpd, client);
|
||||||
|
|
||||||
|
/* reset the task trigger */
|
||||||
|
QSE_MEMSET (&client->trigger, 0, QSE_SIZEOF(client->trigger));
|
||||||
}
|
}
|
||||||
else
|
else if (n > 0)
|
||||||
{
|
{
|
||||||
return update_mux_for_current_task (httpd, client, task);
|
n = update_mux_for_current_task (httpd, client, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int perform_client_task (
|
static int perform_client_task (
|
||||||
@ -1200,6 +1259,16 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int perform_dns (qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg)
|
||||||
|
{
|
||||||
|
qse_httpd_dns_t* dns = (qse_httpd_dns_t*)cbarg;
|
||||||
|
|
||||||
|
QSE_ASSERT (mask & QSE_HTTPD_MUX_READ);
|
||||||
|
QSE_ASSERT (&httpd->dns == dns);
|
||||||
|
|
||||||
|
return httpd->opt.scb.dns.recv (httpd, dns);
|
||||||
|
}
|
||||||
|
|
||||||
static void purge_bad_clients (qse_httpd_t* httpd)
|
static void purge_bad_clients (qse_httpd_t* httpd)
|
||||||
{
|
{
|
||||||
qse_httpd_client_t* client;
|
qse_httpd_client_t* client;
|
||||||
@ -1236,6 +1305,7 @@ static void purge_idle_clients (qse_httpd_t* httpd)
|
|||||||
/* TODO: */
|
/* TODO: */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* qse_httpd_gettaskxtn (qse_httpd_t* httpd, qse_httpd_task_t* task)
|
void* qse_httpd_gettaskxtn (qse_httpd_t* httpd, qse_httpd_task_t* task)
|
||||||
{
|
{
|
||||||
return (void*)((qse_httpd_real_task_t*)task + 1);
|
return (void*)((qse_httpd_real_task_t*)task + 1);
|
||||||
@ -1258,25 +1328,27 @@ qse_httpd_task_t* qse_httpd_entask (
|
|||||||
}
|
}
|
||||||
else if (new_task->prev == QSE_NULL)
|
else if (new_task->prev == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* arrange to invokde this task so long as
|
|
||||||
* the client-side handle is writable. */
|
|
||||||
QSE_ASSERT (client->status & CLIENT_HANDLE_IN_MUX);
|
|
||||||
httpd->opt.scb.mux.delhnd (httpd, httpd->mux, client->handle);
|
|
||||||
client->status &= ~CLIENT_HANDLE_IN_MUX;
|
|
||||||
|
|
||||||
#if 0
|
/* this task is the first task to activate.
|
||||||
printf ("MUX ADDHND CLIENT RW(ENTASK) %d\n", client->handle.i);
|
*
|
||||||
#endif
|
* the client handle should be in mux for reading at this phase.
|
||||||
if (httpd->opt.scb.mux.addhnd (
|
* a new task should be invoked at least once regardless of the
|
||||||
httpd, httpd->mux, client->handle,
|
* data availablility(read) on the client side. arrange to invoke
|
||||||
QSE_HTTPD_MUX_READ | QSE_HTTPD_MUX_WRITE,
|
* this task so long as the client-side handle is writable as well
|
||||||
client) <= -1)
|
* as when data is available for reading. */
|
||||||
|
|
||||||
|
if (update_mux_for_new_task (httpd, client) <= -1)
|
||||||
{
|
{
|
||||||
/*purge_client (httpd, client);*/
|
/*purge_client (httpd, client);*/
|
||||||
client->status |= CLIENT_BAD;
|
client->status |= CLIENT_BAD;
|
||||||
|
|
||||||
|
/* call dequeue_task() to get new_task removed. this works
|
||||||
|
* because it is the only task. the task finalizer is also
|
||||||
|
* called when it's dequeued. */
|
||||||
|
dequeue_task (httpd, client);
|
||||||
|
|
||||||
new_task = QSE_NULL;
|
new_task = QSE_NULL;
|
||||||
}
|
}
|
||||||
client->status |= CLIENT_HANDLE_IN_MUX; /* READ | WRITE */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (qse_httpd_task_t*)new_task;
|
return (qse_httpd_task_t*)new_task;
|
||||||
@ -1285,9 +1357,20 @@ printf ("MUX ADDHND CLIENT RW(ENTASK) %d\n", client->handle.i);
|
|||||||
static int dispatch_mux (
|
static int dispatch_mux (
|
||||||
qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg)
|
qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg)
|
||||||
{
|
{
|
||||||
return ((qse_httpd_mate_t*)cbarg)->type == QSE_HTTPD_SERVER?
|
switch (((qse_httpd_mate_t*)cbarg)->type)
|
||||||
accept_client (httpd, mux, handle, mask, cbarg):
|
{
|
||||||
perform_client_task (httpd, mux, handle, mask, cbarg);
|
case QSE_HTTPD_SERVER:
|
||||||
|
return accept_client (httpd, mux, handle, mask, cbarg);
|
||||||
|
|
||||||
|
case QSE_HTTPD_CLIENT:
|
||||||
|
return perform_client_task (httpd, mux, handle, mask, cbarg);
|
||||||
|
|
||||||
|
case QSE_HTTPD_DNS:
|
||||||
|
return perform_dns (httpd, mux, handle, mask, cbarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
httpd->errnum = QSE_HTTPD_EINTERN;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_httpd_loop (qse_httpd_t* httpd)
|
int qse_httpd_loop (qse_httpd_t* httpd)
|
||||||
@ -1319,15 +1402,24 @@ int qse_httpd_loop (qse_httpd_t* httpd)
|
|||||||
httpd->mux = httpd->opt.scb.mux.open (httpd, dispatch_mux);
|
httpd->mux = httpd->opt.scb.mux.open (httpd, dispatch_mux);
|
||||||
if (httpd->mux == QSE_NULL) return -1;
|
if (httpd->mux == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
if (activate_dns (httpd) <= -1)
|
||||||
|
{
|
||||||
|
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (activate_servers (httpd) <= -1)
|
if (activate_servers (httpd) <= -1)
|
||||||
{
|
{
|
||||||
|
deactivate_dns (httpd);
|
||||||
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (httpd->server.nactive <= 0)
|
if (httpd->server.nactive <= 0)
|
||||||
{
|
{
|
||||||
httpd->errnum = QSE_HTTPD_ENOSVR;
|
deactivate_dns (httpd);
|
||||||
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
||||||
|
|
||||||
|
httpd->errnum = QSE_HTTPD_ENOSVR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1359,11 +1451,12 @@ int qse_httpd_loop (qse_httpd_t* httpd)
|
|||||||
|
|
||||||
purge_client_list (httpd);
|
purge_client_list (httpd);
|
||||||
deactivate_servers (httpd);
|
deactivate_servers (httpd);
|
||||||
|
deactivate_dns (httpd);
|
||||||
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
httpd->opt.scb.mux.close (httpd, httpd->mux);
|
||||||
return xret;
|
return xret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
void qse_httpd_discardcontent (qse_httpd_t* httpd, qse_htre_t* req)
|
void qse_httpd_discardcontent (qse_httpd_t* httpd, qse_htre_t* req)
|
||||||
{
|
{
|
||||||
@ -1375,8 +1468,7 @@ void qse_httpd_completecontent (qse_httpd_t* httpd, qse_htre_t* req)
|
|||||||
qse_htre_completecontent (req);
|
qse_htre_completecontent (req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
void qse_httpd_setname (qse_httpd_t* httpd, const qse_mchar_t* name)
|
void qse_httpd_setname (qse_httpd_t* httpd, const qse_mchar_t* name)
|
||||||
{
|
{
|
||||||
qse_mbsxcpy (httpd->sname, QSE_COUNTOF(httpd->sname), name);
|
qse_mbsxcpy (httpd->sname, QSE_COUNTOF(httpd->sname), name);
|
||||||
@ -1408,8 +1500,7 @@ const qse_mchar_t* qse_httpd_fmtgmtimetobb (
|
|||||||
return httpd->gtbuf[idx];
|
return httpd->gtbuf[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
/* --------------------------------------------------- */
|
|
||||||
|
|
||||||
qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str)
|
qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str)
|
||||||
{
|
{
|
||||||
@ -1476,3 +1567,15 @@ qse_mchar_t* qse_httpd_escapehtml (qse_httpd_t* httpd, const qse_mchar_t* str)
|
|||||||
*ptr = QSE_MT('\0');
|
*ptr = QSE_MT('\0');
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int qse_httpd_resolname (qse_httpd_t* httpd, const qse_mchar_t* name, qse_httpd_resol_t resol, void* ctx)
|
||||||
|
{
|
||||||
|
/* TODO: find the name in cache */
|
||||||
|
|
||||||
|
/* not found in the cache */
|
||||||
|
httpd->opt.scb.dns.send (httpd, &httpd->dns, name, resol, ctx);
|
||||||
|
resol (httpd, QSE_NULL, ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -76,6 +76,7 @@ struct qse_httpd_t
|
|||||||
} server;
|
} server;
|
||||||
|
|
||||||
void* mux;
|
void* mux;
|
||||||
|
qse_httpd_dns_t dns;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* qse_httpd_real_task_t is a private type to hide some private fields
|
/* qse_httpd_real_task_t is a private type to hide some private fields
|
||||||
@ -91,7 +92,7 @@ struct qse_httpd_real_task_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SEND_SIZE 4096
|
#define MAX_SEND_SIZE 4096
|
||||||
|
#define MAX_RECV_SIZE 4096
|
||||||
|
|
||||||
/* client->status */
|
/* client->status */
|
||||||
#define CLIENT_BAD (1 << 0)
|
#define CLIENT_BAD (1 << 0)
|
||||||
@ -102,8 +103,11 @@ struct qse_httpd_real_task_t
|
|||||||
#define CLIENT_MUTE_DELETED (1 << 5)
|
#define CLIENT_MUTE_DELETED (1 << 5)
|
||||||
#define CLIENT_HANDLE_READ_IN_MUX (1 << 6)
|
#define CLIENT_HANDLE_READ_IN_MUX (1 << 6)
|
||||||
#define CLIENT_HANDLE_WRITE_IN_MUX (1 << 7)
|
#define CLIENT_HANDLE_WRITE_IN_MUX (1 << 7)
|
||||||
#define CLIENT_HANDLE_IN_MUX (CLIENT_HANDLE_READ_IN_MUX|CLIENT_HANDLE_WRITE_IN_MUX)
|
#define CLIENT_HANDLE_RW_IN_MUX (CLIENT_HANDLE_READ_IN_MUX | CLIENT_HANDLE_WRITE_IN_MUX)
|
||||||
#define CLIENT_TASK_TRIGGER_IN_MUX(i) (1 << ((i) + 8))
|
|
||||||
|
#define CLIENT_TASK_TRIGGER_READ_IN_MUX(i) (1 << ((i) + 8))
|
||||||
|
#define CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i) (1 << ((i) + 8 + QSE_HTTPD_TASK_TRIGGER_MAX))
|
||||||
|
#define CLIENT_TASK_TRIGGER_RW_IN_MUX(i) (CLIENT_TASK_TRIGGER_READ_IN_MUX(i) | CLIENT_TASK_TRIGGER_WRITE_IN_MUX(i))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user