fixed more issues in fcgi handling
This commit is contained in:
parent
439d9c1220
commit
a2d047a676
@ -1245,7 +1245,7 @@ for (i = 0; i < 5; i++)
|
||||
HIO_INFO1 (hio, "UNABLE TO START DNC - %js\n", hio_geterrmsg(hio));
|
||||
}
|
||||
|
||||
htts = hio_svc_htts_start(hio, 0, &htts_bind_info, 1, process_http_request);
|
||||
htts = hio_svc_htts_start(hio, 0, &htts_bind_info, 1, process_http_request, HIO_NULL);
|
||||
if (htts) hio_svc_htts_setservernamewithbcstr (htts, "HIO-HTTP");
|
||||
else HIO_INFO1 (hio, "UNABLE TO START HTTS - %js\n", hio_geterrmsg(hio));
|
||||
|
||||
|
@ -252,7 +252,7 @@ void* thr_func (void* arg)
|
||||
htts_bind_info[1].ssl_keyfile = "localhost.key";
|
||||
#endif
|
||||
|
||||
htts = hio_svc_htts_start(hio, 0, htts_bind_info, HIO_COUNTOF(htts_bind_info), process_http_request);
|
||||
htts = hio_svc_htts_start(hio, 0, htts_bind_info, HIO_COUNTOF(htts_bind_info), process_http_request, HIO_NULL);
|
||||
if (!htts)
|
||||
{
|
||||
printf ("Unable to start htts\n");
|
||||
|
27
bin/webs.c
27
bin/webs.c
@ -304,6 +304,7 @@ static int process_http_request (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_
|
||||
hio_t* hio = hio_svc_htts_gethio(htts);
|
||||
hio_http_method_t mth;
|
||||
const hio_bch_t* qpath, * qpath_ext;
|
||||
int proto_len;
|
||||
|
||||
static hio_svc_htts_file_cbs_t fcbs = { file_get_mime_type, file_open_dir_list, HIO_NULL };
|
||||
|
||||
@ -314,6 +315,19 @@ static int process_http_request (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_
|
||||
qpath_ext = hio_rfind_bchar_in_bcstr(qpath, '.');
|
||||
if (!qpath_ext) qpath_ext = "";
|
||||
|
||||
/* TODO: log remote address and other information .... */
|
||||
HIO_INFO3 (hio, "%.*hs %hs\n", hio_htre_getqmethodlen(req), hio_htre_getqmethodname(req), qpath);
|
||||
|
||||
if (((proto_len = 7) && hio_comp_bcstr_limited(qpath, "http://", 7, 1) == 0) ||
|
||||
((proto_len = 8) && hio_comp_bcstr_limited(qpath, "https://", 8, 1) == 0))
|
||||
{
|
||||
const hio_bch_t* tmp;
|
||||
tmp = hio_find_bchar_in_bcstr(qpath + proto_len, '/');
|
||||
if (tmp) qpath = tmp; /* skip http://domain.name */
|
||||
|
||||
/* TODO: support proxy .... */
|
||||
}
|
||||
|
||||
if (mth == HIO_HTTP_OTHER && hio_comp_bcstr(hio_htre_getqmethodname(req), "UNTAR", 1) == 0 && hio_comp_bcstr(qpath_ext, ".tar", 0) == 0)
|
||||
{
|
||||
/* don't care about the path for now. TODO: make this secure and reasonable */
|
||||
@ -330,15 +344,17 @@ static int process_http_request (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_
|
||||
{
|
||||
if (hio_svc_htts_docgi(htts, csck, req, ext->ai->docroot, qpath, 0) <= -1) goto oops;
|
||||
}
|
||||
else if (hio_comp_bcstr(qpath_ext, ".php", 0) == 0)
|
||||
else if (hio_comp_bcstr(qpath_ext, ".php", 0) == 0 || hio_comp_bcstr(qpath_ext, ".ant", 0) == 0 /*|| hio_comp_bcstr_limited(qpath, "http://", 7, 1) == 0*/)
|
||||
{
|
||||
hio_skad_t skad;
|
||||
hio_bcstrtoskad(hio, "10.30.0.133:9000", &skad);
|
||||
|
||||
HIO_DEBUG2 (hio, "fcgi %hs %hs\n", ext->ai->docroot, qpath);
|
||||
/*if (hio_svc_htts_dofcgi(htts, csck, req, &skad, ext->ai->docroot, qpath, 0) <= -1) goto oops;*/
|
||||
/* if the document root is relative, it is hard to gurantee that the same document is
|
||||
* true to the fcgi server which is a different process. so map it a blank string for now.
|
||||
* TODO: accept a separate document root for the fcgi server and use it below */
|
||||
if (hio_svc_htts_dofcgi(htts, csck, req, &skad, "", qpath, 0) <= -1) goto oops;
|
||||
if (hio_svc_htts_dofcgi(htts, csck, req, &skad, ext->ai->docroot, qpath, 0) <= -1) goto oops;
|
||||
/*if (hio_svc_htts_dotxt(htts, csck, req, HIO_HTTP_STATUS_INTERNAL_SERVER_ERROR, "text/plain", "what the...", 0) <= -1) goto oops;*/
|
||||
}
|
||||
else // if (mth == HIO_HTTP_GET || mth == HIO_HTTP_POST)
|
||||
@ -368,6 +384,7 @@ int webs_start (hio_t* hio, const arg_info_t* ai)
|
||||
hio_oow_t bic;
|
||||
hio_svc_htts_t* webs;
|
||||
htts_ext_t* ext;
|
||||
hio_svc_fcgic_tmout_t fcgic_tmout;
|
||||
|
||||
bic = 0;
|
||||
ptr = ai->laddrs;
|
||||
@ -389,7 +406,11 @@ int webs_start (hio_t* hio, const arg_info_t* ai)
|
||||
}
|
||||
}
|
||||
|
||||
webs = hio_svc_htts_start(hio, HIO_SIZEOF(htts_ext_t), bi, bic, process_http_request);
|
||||
HIO_MEMSET (&fcgic_tmout, 0, HIO_SIZEOF(fcgic_tmout));
|
||||
fcgic_tmout.c.sec = 5;
|
||||
fcgic_tmout.r.sec = 60;
|
||||
|
||||
webs = hio_svc_htts_start(hio, HIO_SIZEOF(htts_ext_t), bi, bic, process_http_request, &fcgic_tmout);
|
||||
if (!webs) return -1; /* TODO: logging */
|
||||
|
||||
ext = hio_svc_htts_getxtn(webs);
|
||||
|
@ -88,7 +88,7 @@ struct fcgic_sck_xtn_t
|
||||
};
|
||||
typedef struct fcgic_sck_xtn_t fcgic_sck_xtn_t;
|
||||
|
||||
static int make_connection_socket (hio_svc_fcgic_conn_t* conn);
|
||||
static int make_connection_socket (hio_svc_fcgic_t* fcigc, hio_svc_fcgic_conn_t* conn);
|
||||
static void release_session (hio_svc_fcgic_sess_t* sess);
|
||||
|
||||
static void sck_on_disconnect (hio_dev_sck_t* sck)
|
||||
@ -100,15 +100,6 @@ printf ("DISCONNECT SOCKET .................. sck->%p conn->%p\n", sck, conn);
|
||||
|
||||
if (conn)
|
||||
{
|
||||
/* TODO: arrange to create it again if the server is not closing... */
|
||||
/* if (.... ) */
|
||||
#if 0
|
||||
if (sck->hio->stopreq == HIO_STOPREQ_NONE)
|
||||
{
|
||||
/* this may create a busy loop if the connection attempt fails repeatedly */
|
||||
make_connection_socket(conn); /* don't care about failure for now */
|
||||
}
|
||||
#else
|
||||
hio_oow_t i;
|
||||
for (i = 0; i < conn->sess.capa; i++)
|
||||
{
|
||||
@ -120,7 +111,6 @@ printf ("DISCONNECT SOCKET .................. sck->%p conn->%p\n", sck, conn);
|
||||
}
|
||||
}
|
||||
conn->dev = HIO_NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,11 +119,14 @@ static void sck_on_connect (hio_dev_sck_t* sck)
|
||||
fcgic_sck_xtn_t* sck_xtn = hio_dev_sck_getxtn(sck);
|
||||
hio_svc_fcgic_conn_t* conn = sck_xtn->conn;
|
||||
|
||||
printf ("CONNECTED >>>>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
printf ("FCGIC SOCKET CONNECTED >>>>>>>>>>>>>>>>>>>>>>>>>>\n");
|
||||
|
||||
/* reinitialize the input parsing information */
|
||||
HIO_MEMSET (&conn->r, 0, HIO_SIZEOF(conn->r));
|
||||
conn->r.state = R_AWAITING_HEADER;
|
||||
|
||||
if (conn->fcgic->tmout_set)
|
||||
hio_dev_sck_timedread (sck, 1, &conn->fcgic->tmout.r);
|
||||
}
|
||||
|
||||
static int sck_on_write (hio_dev_sck_t* sck, hio_iolen_t wrlen, void* wrctx, const hio_skad_t* dstaddr)
|
||||
@ -237,10 +230,12 @@ static int sck_on_read (hio_dev_sck_t* sck, const void* data, hio_iolen_t dlen,
|
||||
if (!sess || !sess->active)
|
||||
{
|
||||
/* discard the record. no associated sessoin or inactive session */
|
||||
printf ("UNKNOWN SESSION ..................... %p %d\n", sess, conn->r.id);
|
||||
HIO_DEBUG2 (hio, "UNKNOWN SESSION ..................... %p %d\n", sess, conn->r.id);
|
||||
if (sess) HIO_DEBUG1 (hio, "UNKNOWN SESSION active? %d\n", sess->active);
|
||||
goto back_to_header;
|
||||
}
|
||||
|
||||
HIO_DEBUG2 (hio, "OK SESSION ..................... %p %d\n", sess, conn->r.id);
|
||||
/* the complete body is in conn->r.buf */
|
||||
if (conn->r.type == HIO_FCGI_END_REQUEST)
|
||||
{
|
||||
@ -278,7 +273,7 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_connection_socket (hio_svc_fcgic_conn_t* conn)
|
||||
static int make_connection_socket (hio_svc_fcgic_t* fcgic, hio_svc_fcgic_conn_t* conn)
|
||||
{
|
||||
hio_t* hio = conn->fcgic->hio;
|
||||
hio_dev_sck_t* sck;
|
||||
@ -322,7 +317,7 @@ static int make_connection_socket (hio_svc_fcgic_conn_t* conn)
|
||||
|
||||
HIO_MEMSET (&ci, 0, HIO_SIZEOF(ci));
|
||||
ci.remoteaddr = conn->addr;
|
||||
ci.connect_tmout.sec = 5; /* TODO: make this configurable */
|
||||
if (fcgic->tmout_set) ci.connect_tmout = fcgic->tmout.c;
|
||||
|
||||
if (hio_dev_sck_connect(sck, &ci) <= -1)
|
||||
{
|
||||
@ -350,7 +345,7 @@ static hio_svc_fcgic_conn_t* get_connection (hio_svc_fcgic_t* fcgic, const hio_s
|
||||
if (!conn->sess.free || conn->sess.capa <= (CONN_SESS_CAPA_MAX - CONN_SESS_INC))
|
||||
{
|
||||
/* the connection has room for more sessions */
|
||||
if (!conn->dev) make_connection_socket(conn); /* conn->dev will still be null if connection fails*/
|
||||
if (!conn->dev) make_connection_socket(fcgic, conn); /* conn->dev will still be null if connection fails*/
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@ -365,7 +360,7 @@ static hio_svc_fcgic_conn_t* get_connection (hio_svc_fcgic_t* fcgic, const hio_s
|
||||
conn->sess.capa = 0;
|
||||
conn->sess.free = HIO_NULL;
|
||||
|
||||
if (make_connection_socket(conn) <= -1)
|
||||
if (make_connection_socket(fcgic, conn) <= -1)
|
||||
{
|
||||
hio_freemem (hio, conn);
|
||||
return HIO_NULL;
|
||||
@ -598,7 +593,7 @@ int hio_svc_fcgic_writeparam (hio_svc_fcgic_sess_t* sess, const void* key, hio_i
|
||||
vsz &= HIO_TYPE_MAX(hio_int32_t);
|
||||
if (ksz > 0)
|
||||
{
|
||||
if (ksz > 0xFF)
|
||||
if (ksz > 0x7F)
|
||||
{
|
||||
sz[szc++] = (ksz >> 24) | 0x80;
|
||||
sz[szc++] = (ksz >> 16) & 0xFF;
|
||||
@ -610,7 +605,7 @@ int hio_svc_fcgic_writeparam (hio_svc_fcgic_sess_t* sess, const void* key, hio_i
|
||||
sz[szc++] = ksz;
|
||||
}
|
||||
|
||||
if (vsz > 0xFF)
|
||||
if (vsz > 0x7F)
|
||||
{
|
||||
sz[szc++] = (vsz >> 24) | 0x80;
|
||||
sz[szc++] = (vsz >> 16) & 0xFF;
|
||||
@ -650,7 +645,6 @@ int hio_svc_fcgic_writestdin (hio_svc_fcgic_sess_t* sess, const void* data, hio_
|
||||
hio_iovec_t iov[2];
|
||||
hio_fcgi_record_header_t h;
|
||||
|
||||
printf (">>>>>>>>>>>>>>>>>>>>>>[%p] %p\n", sess, sess->conn);
|
||||
if (!sess->conn->dev)
|
||||
{
|
||||
/* TODO: set error **/
|
||||
|
@ -1038,4 +1038,12 @@ struct hio_cmgr_t
|
||||
((c) >= 'A' && (c) <= 'Z')? ((c) - 'A' + 10): \
|
||||
((c) >= 'a' && (c) <= 'Z')? ((c) - 'a' + 10): base)
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
* PRE-DEFINITION OF FOUNDATIONAL COMPOSITE TYPES
|
||||
* =========================================================================*/
|
||||
typedef struct hio_t hio_t;
|
||||
typedef struct hio_becs_t hio_becs_t;
|
||||
typedef struct hio_uecs_t hio_uecs_t;
|
||||
|
||||
#endif
|
||||
|
@ -60,8 +60,11 @@
|
||||
/**< last character. unsafe if length <= 0 */
|
||||
#define HIO_UECS_LASTCHAR(s) ((s)->val.ptr[(s)->val.len-1])
|
||||
|
||||
/*
|
||||
* defined in hio-cmn.h
|
||||
typedef struct hio_becs_t hio_becs_t;
|
||||
typedef struct hio_uecs_t hio_uecs_t;
|
||||
*/
|
||||
|
||||
typedef hio_oow_t (*hio_becs_sizer_t) (
|
||||
hio_becs_t* data,
|
||||
|
@ -108,6 +108,7 @@ enum hio_http_status_t
|
||||
HIO_HTTP_STATUS_PARTIAL_CONTENT = 206,
|
||||
|
||||
HIO_HTTP_STATUS_MOVED_PERMANENTLY = 301,
|
||||
HIO_HTTP_STATUS_MOVED_TEMPORARILY = 302,
|
||||
HIO_HTTP_STATUS_NOT_MODIFIED = 304,
|
||||
|
||||
HIO_HTTP_STATUS_BAD_REQUEST = 400,
|
||||
|
@ -354,11 +354,12 @@ HIO_EXPORT hio_oow_t hio_escape_html_bcstr (
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
HIO_EXPORT hio_svc_htts_t* hio_svc_htts_start (
|
||||
hio_t* hio,
|
||||
hio_oow_t xtnsize,
|
||||
hio_dev_sck_bind_t* binds,
|
||||
hio_oow_t nbinds,
|
||||
hio_svc_htts_proc_req_t proc_req
|
||||
hio_t* hio,
|
||||
hio_oow_t xtnsize,
|
||||
hio_dev_sck_bind_t* binds,
|
||||
hio_oow_t nbinds,
|
||||
hio_svc_htts_proc_req_t proc_req,
|
||||
const hio_svc_fcgic_tmout_t* fcgic_tmout
|
||||
);
|
||||
|
||||
HIO_EXPORT void hio_svc_htts_stop (
|
||||
|
11
lib/hio.c
11
lib/hio.c
@ -24,6 +24,7 @@
|
||||
|
||||
#include "hio-prv.h"
|
||||
#include <hio-fmt.h>
|
||||
#include <hio-ecs.h>
|
||||
#include <stdlib.h> /* malloc, free, etc */
|
||||
|
||||
#define DEV_CAP_ALL_WATCHED (HIO_DEV_CAP_IN_WATCHED | HIO_DEV_CAP_OUT_WATCHED | HIO_DEV_CAP_PRI_WATCHED)
|
||||
@ -123,6 +124,9 @@ int hio_init (hio_t* hio, hio_mmgr_t* mmgr, hio_cmgr_t* cmgr, hio_bitmask_t feat
|
||||
hio->log.ptr = hio_allocmem(hio, (hio->log.capa + 1) * HIO_SIZEOF(*hio->log.ptr));
|
||||
if (HIO_UNLIKELY(!hio->log.ptr)) goto oops;
|
||||
|
||||
hio->becbuf = hio_becs_open(hio, 0, 256);
|
||||
if (HIO_UNLIKELY(!hio->becbuf)) goto oops;
|
||||
|
||||
/* inititalize the system-side logging */
|
||||
if (HIO_UNLIKELY(hio_sys_init(hio) <= -1)) goto oops;
|
||||
sys_inited = 1;
|
||||
@ -149,6 +153,7 @@ oops:
|
||||
|
||||
if (sys_inited) hio_sys_fini (hio);
|
||||
|
||||
if (hio->becbuf) hio_freemem (hio, hio->becbuf);
|
||||
if (hio->log.ptr) hio_freemem (hio, hio->log.ptr);
|
||||
hio->log.capa = 0;
|
||||
return -1;
|
||||
@ -245,6 +250,12 @@ void hio_fini (hio_t* hio)
|
||||
|
||||
hio_sys_fini (hio); /* finalize the system dependent data */
|
||||
|
||||
if (hio->becbuf)
|
||||
{
|
||||
hio_becs_close (hio->becbuf);
|
||||
hio->becbuf = HIO_NULL;
|
||||
}
|
||||
|
||||
if (hio->log.ptr)
|
||||
{
|
||||
hio_freemem (hio, hio->log.ptr);
|
||||
|
10
lib/hio.h
10
lib/hio.h
@ -54,7 +54,10 @@ struct hio_devaddr_t
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
typedef struct hio_t hio_t;
|
||||
/*
|
||||
* defined in hio-cmn.h
|
||||
*typedef struct hio_t hio_t;
|
||||
*/
|
||||
typedef struct hio_dev_t hio_dev_t;
|
||||
typedef struct hio_dev_mth_t hio_dev_mth_t;
|
||||
typedef struct hio_dev_evcb_t hio_dev_evcb_t;
|
||||
@ -734,6 +737,7 @@ struct hio_t
|
||||
|
||||
hio_bitmask_t _features;
|
||||
|
||||
hio_stopreq_t stopreq; /* stop request to abort hio_loop() */
|
||||
unsigned short int _shuterr;
|
||||
unsigned short int _fini_in_progress;
|
||||
|
||||
@ -766,14 +770,14 @@ struct hio_t
|
||||
} xbuf; /* buffer to support sprintf */
|
||||
} sprintf;
|
||||
|
||||
hio_stopreq_t stopreq; /* stop request to abort hio_loop() */
|
||||
hio_becs_t* becbuf; /* temporary buffer for some string manipulation */
|
||||
hio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
|
||||
|
||||
hio_cfmb_t cfmb; /* list head of cfmbs */
|
||||
hio_dev_t actdev; /* list head of active devices */
|
||||
hio_dev_t hltdev; /* list head of halted devices */
|
||||
hio_dev_t zmbdev; /* list head of zombie devices */
|
||||
|
||||
hio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
|
||||
|
||||
hio_ntime_t init_time;
|
||||
struct
|
||||
|
@ -479,6 +479,7 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
||||
hio_svc_htts_cli_t* cli = cgi->client;
|
||||
hio_bch_t dtbuf[64];
|
||||
int status_code = HIO_HTTP_STATUS_OK;
|
||||
const hio_bch_t* status_line = HIO_NULL;
|
||||
|
||||
if (req->attr.content_length)
|
||||
{
|
||||
@ -489,19 +490,49 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
||||
if (req->attr.status)
|
||||
{
|
||||
int is_sober;
|
||||
const hio_bch_t* endptr;
|
||||
const hio_bch_t* begptr, * endptr;
|
||||
hio_intmax_t v;
|
||||
hio_oow_t code_len;
|
||||
hio_oow_t desc_len;
|
||||
|
||||
v = hio_bchars_to_intmax(req->attr.status, hio_count_bcstr(req->attr.status), HIO_BCHARS_TO_INTMAX_MAKE_OPTION(0,0,0,10), &endptr, &is_sober);
|
||||
if (*endptr == '\0' && is_sober && v > 0 && v <= HIO_TYPE_MAX(int)) status_code = v;
|
||||
endptr = req->attr.status;
|
||||
while (hio_is_bch_space(*endptr)) endptr++;
|
||||
begptr = endptr;
|
||||
while (hio_is_bch_digit(*endptr)) endptr++;
|
||||
code_len = endptr - begptr;
|
||||
|
||||
while (hio_is_bch_space(*endptr)) endptr++;
|
||||
begptr = endptr;
|
||||
while (*endptr != '\0') endptr++;
|
||||
desc_len = endptr - begptr;
|
||||
|
||||
/* the status line could be simply "Status: 302" or more verbose like "Status: 302 Moved"
|
||||
* the value may contain more than numbers */
|
||||
if (code_len > 0 && desc_len > 0)
|
||||
{
|
||||
status_line = req->attr.status;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = hio_bchars_to_intmax(req->attr.status, hio_count_bcstr(req->attr.status), HIO_BCHARS_TO_INTMAX_MAKE_OPTION(0,0,0,10), &endptr, &is_sober);
|
||||
if (*endptr == '\0' && is_sober && v > 0 && v <= HIO_TYPE_MAX(int)) status_code = v;
|
||||
}
|
||||
}
|
||||
|
||||
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
|
||||
|
||||
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %hs\r\n",
|
||||
cgi->req_version.major, cgi->req_version.minor,
|
||||
status_code, hio_http_status_to_bcstr(status_code),
|
||||
cli->htts->server_name, dtbuf) == (hio_oow_t)-1) return -1;
|
||||
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d ", cgi->req_version.major, cgi->req_version.minor) == (hio_oow_t)-1) return -1;
|
||||
if (status_line)
|
||||
{
|
||||
if (hio_becs_fcat(cli->sbuf, "%hs\r\n", status_line) == (hio_oow_t)-1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hio_becs_fcat(cli->sbuf, "%d %hs\r\n", status_code, hio_http_status_to_bcstr(status_code)) == (hio_oow_t)-1) return -1;
|
||||
}
|
||||
|
||||
if (hio_becs_fcat(cli->sbuf, "Server: %hs\r\nDate: %hs\r\n", cli->htts->server_name, dtbuf) == (hio_oow_t)-1) return -1;
|
||||
|
||||
|
||||
if (hio_htre_walkheaders(req, peer_capture_response_header, cli) <= -1) return -1;
|
||||
|
||||
|
122
lib/http-fcgi.c
122
lib/http-fcgi.c
@ -14,11 +14,9 @@ enum fcgi_res_mode_t
|
||||
};
|
||||
typedef enum fcgi_res_mode_t fcgi_res_mode_t;
|
||||
|
||||
|
||||
#define FCGI_PENDING_IO_THRESHOLD_TO_CLIENT 50
|
||||
#define FCGI_PENDING_IO_THRESHOLD_TO_PEER 50
|
||||
|
||||
|
||||
#define FCGI_OVER_READ_FROM_CLIENT (1 << 0)
|
||||
#define FCGI_OVER_READ_FROM_PEER (1 << 1)
|
||||
#define FCGI_OVER_WRITE_TO_CLIENT (1 << 2)
|
||||
@ -69,7 +67,7 @@ static void unbind_task_from_peer (fcgi_t* fcgi, int rcdown);
|
||||
static void fcgi_halt_participating_devices (fcgi_t* fcgi)
|
||||
{
|
||||
/* TODO: include fcgi session id in the output in place of peer??? */
|
||||
HIO_DEBUG5 (fcgi->htts->hio, "HTTS(%p) - cgi(t=%p,c=%p(%d),p=%p) Halting participating devices\n", fcgi->htts, fcgi, fcgi->csck, (fcgi->csck? fcgi->csck->hnd: -1), fcgi->peer);
|
||||
HIO_DEBUG5 (fcgi->htts->hio, "HTTS(%p) - fcgi(t=%p,c=%p(%d),p=%p) Halting participating devices\n", fcgi->htts, fcgi, fcgi->csck, (fcgi->csck? fcgi->csck->hnd: -1), fcgi->peer);
|
||||
|
||||
if (fcgi->csck) hio_dev_sck_halt (fcgi->csck);
|
||||
unbind_task_from_peer (fcgi, 1);
|
||||
@ -81,6 +79,7 @@ static int fcgi_write_to_client (fcgi_t* fcgi, const void* data, hio_iolen_t dle
|
||||
{
|
||||
fcgi->ever_attempted_to_write_to_client = 1;
|
||||
|
||||
HIO_DEBUG2 (fcgi->htts->hio, "WR TO C[%.*hs]\n", dlen, data);
|
||||
fcgi->num_pending_writes_to_client++;
|
||||
if (hio_dev_sck_write(fcgi->csck, data, dlen, HIO_NULL, HIO_NULL) <= -1)
|
||||
{
|
||||
@ -138,7 +137,7 @@ static int fcgi_send_final_status_to_client (fcgi_t* fcgi, int status_code, int
|
||||
const hio_bch_t* status_msg;
|
||||
hio_oow_t content_len;
|
||||
|
||||
if (!cli) return; /* client unbound or no binding client */
|
||||
if (!cli) return 0; /* client unbound or no binding client */
|
||||
|
||||
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
|
||||
status_msg = hio_http_status_to_bcstr(status_code);
|
||||
@ -249,10 +248,9 @@ static HIO_INLINE void fcgi_mark_over (fcgi_t* fcgi, int over_bits)
|
||||
{
|
||||
if (fcgi->keep_alive && !fcgi->client_eof_detected)
|
||||
{
|
||||
/* how to arrange to delete this fcgi object and put the socket back to the normal waiting state??? */
|
||||
HIO_DEBUG2 (hio, "HTTS(%p) - keeping client(%p) alive\n", fcgi->htts, fcgi->csck);
|
||||
HIO_ASSERT (fcgi->htts->hio, fcgi->client->task == (hio_svc_htts_task_t*)fcgi);
|
||||
unbind_task_from_client (fcgi, 1);
|
||||
|
||||
/* fcgi must not be accessed from here down as it could have been destroyed in unbind_task_from_client() */
|
||||
}
|
||||
else
|
||||
@ -305,13 +303,17 @@ static void fcgi_on_kill (hio_svc_htts_task_t* task)
|
||||
static void fcgi_peer_on_untie (hio_svc_fcgic_sess_t* peer, void* ctx)
|
||||
{
|
||||
fcgi_t* fcgi = (fcgi_t*)ctx;
|
||||
hio_t* hio = fcgi->htts->hio;
|
||||
|
||||
/* in case this untie event originates from the fcgi client itself.
|
||||
* fcgi_halt_participating_devices() calls hio_svc_fcgi_untie() again
|
||||
* to cause an infinite loop if we don't reset fcgi->peer to HIO_NULL here */
|
||||
|
||||
HIO_DEBUG5 (hio, "HTTS(%p) - fcgi(t=%p,c=%p[%d],p=%p) - peer untied\n", fcgi->htts, fcgi, fcgi->client, (fcgi->csck? fcgi->csck->hnd: -1), fcgi->peer);
|
||||
|
||||
fcgi->peer = HIO_NULL;
|
||||
fcgi_write_last_chunk_to_client (fcgi);
|
||||
fcgi_halt_participating_devices (fcgi); /* TODO: kill the session only??? */
|
||||
unbind_task_from_peer (fcgi, 1);
|
||||
}
|
||||
|
||||
static int fcgi_peer_on_read (hio_svc_fcgic_sess_t* peer, const void* data, hio_iolen_t dlen, void* ctx)
|
||||
@ -412,6 +414,7 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
||||
hio_svc_htts_cli_t* cli = fcgi->client;
|
||||
hio_bch_t dtbuf[64];
|
||||
int status_code = HIO_HTTP_STATUS_OK;
|
||||
const hio_bch_t* status_line = HIO_NULL;
|
||||
|
||||
if (req->attr.content_length)
|
||||
{
|
||||
@ -422,19 +425,48 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
||||
if (req->attr.status)
|
||||
{
|
||||
int is_sober;
|
||||
const hio_bch_t* endptr;
|
||||
const hio_bch_t* begptr, * endptr;
|
||||
hio_intmax_t v;
|
||||
hio_oow_t code_len;
|
||||
hio_oow_t desc_len;
|
||||
|
||||
v = hio_bchars_to_intmax(req->attr.status, hio_count_bcstr(req->attr.status), HIO_BCHARS_TO_INTMAX_MAKE_OPTION(0,0,0,10), &endptr, &is_sober);
|
||||
if (*endptr == '\0' && is_sober && v > 0 && v <= HIO_TYPE_MAX(int)) status_code = v;
|
||||
endptr = req->attr.status;
|
||||
while (hio_is_bch_space(*endptr)) endptr++;
|
||||
begptr = endptr;
|
||||
while (hio_is_bch_digit(*endptr)) endptr++;
|
||||
code_len = endptr - begptr;
|
||||
|
||||
while (hio_is_bch_space(*endptr)) endptr++;
|
||||
begptr = endptr;
|
||||
while (*endptr != '\0') endptr++;
|
||||
desc_len = endptr - begptr;
|
||||
|
||||
/* the status line could be simply "Status: 302" or more verbose like "Status: 302 Moved"
|
||||
* the value may contain more than numbers */
|
||||
if (code_len > 0 && desc_len > 0)
|
||||
{
|
||||
status_line = req->attr.status;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = hio_bchars_to_intmax(req->attr.status, hio_count_bcstr(req->attr.status), HIO_BCHARS_TO_INTMAX_MAKE_OPTION(0,0,0,10), &endptr, &is_sober);
|
||||
if (*endptr == '\0' && is_sober && v > 0 && v <= HIO_TYPE_MAX(int)) status_code = v;
|
||||
}
|
||||
}
|
||||
|
||||
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
|
||||
|
||||
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %hs\r\n",
|
||||
fcgi->req_version.major, fcgi->req_version.minor,
|
||||
status_code, hio_http_status_to_bcstr(status_code),
|
||||
cli->htts->server_name, dtbuf) == (hio_oow_t)-1) return -1;
|
||||
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d ", fcgi->req_version.major, fcgi->req_version.minor) == (hio_oow_t)-1) return -1;
|
||||
if (status_line)
|
||||
{
|
||||
if (hio_becs_fcat(cli->sbuf, "%hs\r\n", status_line) == (hio_oow_t)-1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hio_becs_fcat(cli->sbuf, "%d %hs\r\n", status_code, hio_http_status_to_bcstr(status_code)) == (hio_oow_t)-1) return -1;
|
||||
}
|
||||
|
||||
if (hio_becs_fcat(cli->sbuf, "Server: %hs\r\nDate: %hs\r\n", cli->htts->server_name, dtbuf) == (hio_oow_t)-1) return -1;
|
||||
|
||||
if (hio_htre_walkheaders(req, peer_capture_response_header, cli) <= -1) return -1;
|
||||
|
||||
@ -698,6 +730,56 @@ oops:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int peer_capture_request_header (hio_htre_t* req, const hio_bch_t* key, const hio_htre_hdrval_t* val, void* ctx)
|
||||
{
|
||||
fcgi_t* fcgi = (fcgi_t*)ctx;
|
||||
hio_svc_htts_t* htts = fcgi->htts;
|
||||
hio_t* hio = htts->hio;
|
||||
|
||||
if (hio_comp_bcstr(key, "Connection", 1) != 0 &&
|
||||
hio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 &&
|
||||
hio_comp_bcstr(key, "Content-Length", 1) != 0 &&
|
||||
hio_comp_bcstr(key, "Expect", 1) != 0)
|
||||
{
|
||||
hio_oow_t val_offset;
|
||||
hio_bch_t* ptr;
|
||||
|
||||
if (hio_comp_bcstr(key, "Content-Type", 1) == 0)
|
||||
{
|
||||
/* don't prefix CONTENT_TYPE with HTTP_ */
|
||||
hio_becs_clear (hio->becbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hio_becs_cpy(hio->becbuf, "HTTP_") == (hio_oow_t)-1) return -1;
|
||||
}
|
||||
|
||||
if (hio_becs_cat(hio->becbuf, key) == (hio_oow_t)-1 ||
|
||||
hio_becs_ccat(hio->becbuf, '\0') == (hio_oow_t)-1) return -1;
|
||||
|
||||
for (ptr = HIO_BECS_PTR(hio->becbuf); *ptr; ptr++)
|
||||
{
|
||||
*ptr = hio_to_bch_upper(*ptr);
|
||||
if (*ptr =='-') *ptr = '_';
|
||||
}
|
||||
|
||||
val_offset = HIO_BECS_LEN(hio->becbuf);
|
||||
if (hio_becs_cat(hio->becbuf, val->ptr) == (hio_oow_t)-1) return -1;
|
||||
val = val->next;
|
||||
while (val)
|
||||
{
|
||||
if (hio_becs_cat(hio->becbuf, ",") == (hio_oow_t)-1 ||
|
||||
hio_becs_cat(hio->becbuf, val->ptr) == (hio_oow_t)-1) return -1;
|
||||
val = val->next;
|
||||
}
|
||||
|
||||
hio_svc_fcgic_writeparam(fcgi->peer, HIO_BECS_PTR(hio->becbuf), val_offset - 1, HIO_BECS_CPTR(hio->becbuf, val_offset), HIO_BECS_LEN(hio->becbuf) - val_offset);
|
||||
/* TODO: error handling? */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int write_params (fcgi_t* fcgi, hio_dev_sck_t* csck, hio_htre_t* req, const hio_bch_t* docroot, const hio_bch_t* script)
|
||||
{
|
||||
@ -707,6 +789,7 @@ static int write_params (fcgi_t* fcgi, hio_dev_sck_t* csck, hio_htre_t* req, con
|
||||
const hio_bch_t* qparam;
|
||||
hio_oow_t content_length;
|
||||
hio_bch_t* actual_script = HIO_NULL;
|
||||
hio_becs_t dbuf;
|
||||
|
||||
HIO_ASSERT (hio, fcgi->csck == csck);
|
||||
|
||||
@ -727,7 +810,8 @@ static int write_params (fcgi_t* fcgi, hio_dev_sck_t* csck, hio_htre_t* req, con
|
||||
if (hio_svc_fcgic_writeparam(fcgi->peer, "REQUEST_URI", 11, hio_htre_getqpath(req), hio_htre_getqpathlen(req)) <= -1) goto oops;
|
||||
|
||||
qparam = hio_htre_getqparam(req);
|
||||
if (qparam && hio_svc_fcgic_writeparam(fcgi->peer, "QUERY_STRING", 12, qparam, hio_count_bcstr(qparam)) <= -1) goto oops;
|
||||
if (!qparam) qparam = "";
|
||||
if (hio_svc_fcgic_writeparam(fcgi->peer, "QUERY_STRING", 12, qparam, hio_count_bcstr(qparam)) <= -1) goto oops;
|
||||
|
||||
if (hio_htre_getreqcontentlen(req, &content_length) == 0)
|
||||
{
|
||||
@ -753,7 +837,8 @@ static int write_params (fcgi_t* fcgi, hio_dev_sck_t* csck, hio_htre_t* req, con
|
||||
len = hio_skadtobcstr (hio, &csck->remoteaddr, tmp, HIO_COUNTOF(tmp), HIO_SKAD_TO_BCSTR_PORT);
|
||||
if (hio_svc_fcgic_writeparam(fcgi->peer, "REMOTE_PORT", 11, tmp, len) <= -1) goto oops;
|
||||
|
||||
//hio_htre_walkheaders (req,)
|
||||
hio_htre_walkheaders (req, peer_capture_request_header, fcgi);
|
||||
/* [NOTE] trailers are not available when this cgi resource is started. let's not call hio_htre_walktrailers() */
|
||||
|
||||
hio_freemem (hio, actual_script);
|
||||
return 0;
|
||||
@ -882,10 +967,8 @@ static void unbind_task_from_peer (fcgi_t* fcgi, int rcdown)
|
||||
hio_svc_fcgic_untie (fcgi->peer);
|
||||
fcgi->peer = HIO_NULL;
|
||||
n++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (rcdown)
|
||||
{
|
||||
while (n > 0)
|
||||
@ -981,6 +1064,7 @@ static int setup_for_content_length(fcgi_t* fcgi, hio_htre_t* req)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* this may change later if Content-Length is included in the fcgi output */
|
||||
if (req->flags & HIO_HTRE_ATTR_KEEPALIVE)
|
||||
{
|
||||
@ -989,6 +1073,7 @@ static int setup_for_content_length(fcgi_t* fcgi, hio_htre_t* req)
|
||||
/* the mode still can get switched to FCGI_RES_MODE_LENGTH if the fcgi script emits Content-Length */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fcgi->keep_alive = 0;
|
||||
fcgi->res_mode_to_cli = FCGI_RES_MODE_CLOSE;
|
||||
@ -996,6 +1081,7 @@ static int setup_for_content_length(fcgi_t* fcgi, hio_htre_t* req)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hio_svc_htts_dofcgi (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* req, const hio_skad_t* fcgis_addr, const hio_bch_t* docroot, const hio_bch_t* script, int options)
|
||||
{
|
||||
hio_t* hio = htts->hio;
|
||||
|
@ -77,6 +77,9 @@ struct hio_svc_htts_t
|
||||
|
||||
hio_bch_t* server_name;
|
||||
hio_bch_t server_name_buf[64];
|
||||
|
||||
int fcgic_tmout_set;
|
||||
hio_svc_fcgic_tmout_t fcgic_tmout;
|
||||
};
|
||||
|
||||
struct hio_svc_httc_t
|
||||
|
@ -330,7 +330,8 @@ static void halt_idle_clients (hio_t* hio, const hio_ntime_t* now, hio_tmrjob_t*
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_oow_t xtnsize, hio_dev_sck_bind_t* binds, hio_oow_t nbinds, hio_svc_htts_proc_req_t proc_req)
|
||||
|
||||
hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_oow_t xtnsize, hio_dev_sck_bind_t* binds, hio_oow_t nbinds, hio_svc_htts_proc_req_t proc_req, const hio_svc_fcgic_tmout_t* fcgic_tmout)
|
||||
{
|
||||
hio_svc_htts_t* htts = HIO_NULL;
|
||||
union
|
||||
@ -357,6 +358,12 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_oow_t xtnsize, hio_dev_sck_b
|
||||
htts->proc_req = proc_req;
|
||||
htts->idle_tmridx = HIO_TMRIDX_INVALID;
|
||||
|
||||
if (fcgic_tmout)
|
||||
{
|
||||
htts->fcgic_tmout_set = 1;
|
||||
htts->fcgic_tmout = *fcgic_tmout;
|
||||
}
|
||||
|
||||
htts->l.sck = (hio_dev_sck_t**)hio_callocmem(hio, HIO_SIZEOF(*htts->l.sck) * nbinds);
|
||||
if (HIO_UNLIKELY(!htts->l.sck)) goto oops;
|
||||
htts->l.count = nbinds;
|
||||
@ -468,7 +475,8 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_oow_t xtnsize, hio_dev_sck_b
|
||||
HIO_SVC_HTTS_CLIL_INIT (&htts->cli);
|
||||
HIO_SVC_HTTS_TASKL_INIT (&htts->task);
|
||||
|
||||
htts->fcgic = hio_svc_fcgic_start(hio, HIO_NULL); /* TODO: set timeout properly */
|
||||
htts->fcgic = hio_svc_fcgic_start(htts->hio, (htts->fcgic_tmout_set? &htts->fcgic_tmout: HIO_NULL));
|
||||
|
||||
if (HIO_UNLIKELY(!htts->fcgic))
|
||||
{
|
||||
/* TODO: only warning ... */
|
||||
@ -676,9 +684,6 @@ void hio_svc_htts_task_kill (hio_svc_htts_task_t* task)
|
||||
HIO_DEBUG2 (hio, "HTTS(%p) - destroyed task %p\n", htts, task);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
int hio_svc_htts_doproxy (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* req, const hio_bch_t* upstream)
|
||||
|
Loading…
Reference in New Issue
Block a user