added hio_svc_htts_task_startreshdr(), hio_svc_htts_task_endreshdr() and others

This commit is contained in:
hyung-hwan 2023-03-11 02:32:33 +09:00
parent 933d03fe27
commit 86fc103711
7 changed files with 218 additions and 134 deletions

View File

@ -30,6 +30,7 @@ struct hio_svc_dhcs_t
{
HIO_SVC_HEADER;
int stopping;
hio_dev_sck_t* sck;
};
@ -122,6 +123,7 @@ hio_svc_dhcs_t* hio_svc_dhcs_start (hio_t* hio, const hio_skad_t* local_binds, h
if (HIO_UNLIKELY(!dhcs)) goto oops;
dhcs->hio = hio;
dhcs->svc_stop = (hio_svc_stop_t)hio_svc_dhcs_stop;
for (i = 0; i < local_nbinds; i++)
{
@ -151,3 +153,16 @@ oops:
}
return HIO_NULL;
}
void hio_svc_dhcs_stop (hio_svc_dhcs_t* dhcs)
{
hio_t* hio = dhcs->hio;
HIO_DEBUG1 (hio, "FCGIC - STOPPING SERVICE %p\n", dhcs);
dhcs->stopping = 1;
HIO_SVCL_UNLINK_SVC (dhcs);
hio_freemem (hio, dhcs);
HIO_DEBUG1 (hio, "FCGIC - STOPPED SERVICE %p\n", dhcs);
}

View File

@ -498,6 +498,36 @@ HIO_EXPORT int hio_svc_htts_task_buildfinalres (
int force_close
);
HIO_EXPORT int hio_svc_htts_task_startreshdr (
hio_svc_htts_task_t* task,
int status_code,
const hio_bch_t* status_desc,
int chunked
);
HIO_EXPORT int hio_svc_htts_task_addreshdrs (
hio_svc_htts_task_t* task,
const hio_bch_t* key,
const hio_htre_hdrval_t* value
);
HIO_EXPORT int hio_svc_htts_task_addreshdr (
hio_svc_htts_task_t* task,
const hio_bch_t* key,
const hio_bch_t* value
);
HIO_EXPORT int hio_svc_htts_task_addreshdrfmt (
hio_svc_htts_task_t* task,
const hio_bch_t* key,
const hio_bch_t* vfmt,
...
);
HIO_EXPORT int hio_svc_htts_task_endreshdr (
hio_svc_htts_task_t* task
);
HIO_EXPORT void hio_svc_htts_fmtgmtime (
hio_svc_htts_t* htts,
const hio_ntime_t* nt,

View File

@ -474,31 +474,7 @@ oops:
static int peer_capture_response_header (hio_htre_t* req, const hio_bch_t* key, const hio_htre_hdrval_t* val, void* ctx)
{
hio_svc_htts_cli_t* cli = (hio_svc_htts_cli_t*)ctx;
/* capture a header except Status, Connection, Transfer-Encoding, and Server */
if (hio_comp_bcstr(key, "Status", 1) != 0 &&
hio_comp_bcstr(key, "Connection", 1) != 0 &&
hio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 &&
hio_comp_bcstr(key, "Server", 1) != 0 &&
hio_comp_bcstr(key, "Date", 1) != 0)
{
do
{
if (hio_becs_cat(cli->sbuf, key) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, ": ") == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, val->ptr) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1)
{
return -1;
}
val = val->next;
}
while (val);
}
return 0;
return hio_svc_htts_task_addreshdrs((cgi_t*)ctx, key, val);
}
static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
@ -506,42 +482,24 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
cgi_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
cgi_t* cgi = peer->cgi;
hio_svc_htts_cli_t* cli = cgi->task_client;
hio_bch_t dtbuf[64];
int status_code = HIO_HTTP_STATUS_OK;
const hio_bch_t* status_desc = HIO_NULL;
int chunked;
if (req->attr.content_length)
if (HIO_UNLIKELY(!cli))
{
// TOOD: remove content_length if content_length is negative or not numeric.
cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH;
/* client disconnected or not connectd */
return 0;
}
if (req->attr.content_length) cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH;
if (req->attr.status) hio_parse_http_status_header_value(req->attr.status, &status_code, &status_desc);
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
chunked = cgi->task_keep_client_alive && !req->attr.content_length;
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d ", cgi->task_req_version.major, cgi->task_req_version.minor) == (hio_oow_t)-1) return -1;
if (hio_becs_fcat(cli->sbuf, "%d %hs\r\n", status_code, (status_desc? status_desc: 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;
switch (cgi->res_mode_to_cli)
{
case CGI_RES_MODE_CHUNKED:
if (hio_becs_cat(cli->sbuf, "Transfer-Encoding: chunked\r\n") == (hio_oow_t)-1) return -1;
/*if (hio_becs_cat(cli->sbuf, "Connection: keep-alive\r\n") == (hio_oow_t)-1) return -1;*/
break;
case CGI_RES_MODE_CLOSE:
if (hio_becs_cat(cli->sbuf, "Connection: close\r\n") == (hio_oow_t)-1) return -1;
break;
case CGI_RES_MODE_LENGTH:
if (hio_becs_cat(cli->sbuf, (cgi->task_keep_client_alive? "Connection: keep-alive\r\n": "Connection: close\r\n")) == (hio_oow_t)-1) return -1;
}
if (hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1) return -1;
if (hio_svc_htts_task_startreshdr(cgi, status_code, status_desc, chunked) <= -1 ||
hio_htre_walkheaders(req, peer_capture_response_header, cgi) <= -1 ||
hio_svc_htts_task_endreshdr(cgi) <= -1) return -1;
cgi->task_status_code = status_code;
return cgi_write_to_client(cgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));

View File

@ -374,75 +374,33 @@ oops:
static int peer_capture_response_header (hio_htre_t* req, const hio_bch_t* key, const hio_htre_hdrval_t* val, void* ctx)
{
hio_svc_htts_cli_t* cli = (hio_svc_htts_cli_t*)ctx;
/* capture a header except Status, Connection, Transfer-Encoding, and Server */
if (hio_comp_bcstr(key, "Status", 1) != 0 &&
hio_comp_bcstr(key, "Connection", 1) != 0 &&
hio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 &&
hio_comp_bcstr(key, "Server", 1) != 0 &&
hio_comp_bcstr(key, "Date", 1) != 0)
{
do
{
if (hio_becs_cat(cli->sbuf, key) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, ": ") == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, val->ptr) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1)
{
return -1;
}
val = val->next;
}
while (val);
}
return 0;
return hio_svc_htts_task_addreshdrs((fcgi_t*)ctx, key, val);
}
static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
{
fcgi_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
fcgi_t* fcgi = peer->fcgi;
hio_svc_htts_cli_t* cli = fcgi->task_client;
hio_bch_t dtbuf[64];
int status_code = HIO_HTTP_STATUS_OK;
const hio_bch_t* status_desc = HIO_NULL;
int chunked;
if (req->attr.content_length)
if (HIO_UNLIKELY(!cli))
{
// TOOD: remove content_length if content_length is negative or not numeric.
fcgi->res_mode_to_cli = FCGI_RES_MODE_LENGTH;
/* client disconnected or not connectd */
return 0;
}
// TOOD: remove content_length if content_length is negative or not numeric.
if (req->attr.content_length) fcgi->res_mode_to_cli = FCGI_RES_MODE_LENGTH;
if (req->attr.status) hio_parse_http_status_header_value(req->attr.status, &status_code, &status_desc);
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
chunked = fcgi->task_keep_client_alive && !req->attr.content_length;
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d ", fcgi->task_req_version.major, fcgi->task_req_version.minor) == (hio_oow_t)-1) return -1;
if (hio_becs_fcat(cli->sbuf, "%d %hs\r\n", status_code, (status_desc? status_desc: 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;
switch (fcgi->res_mode_to_cli)
{
case FCGI_RES_MODE_CHUNKED:
if (hio_becs_cat(cli->sbuf, "Transfer-Encoding: chunked\r\n") == (hio_oow_t)-1) return -1;
/*if (hio_becs_cat(cli->sbuf, "Connection: keep-alive\r\n") == (hio_oow_t)-1) return -1;*/
break;
case FCGI_RES_MODE_CLOSE:
if (hio_becs_cat(cli->sbuf, "Connection: close\r\n") == (hio_oow_t)-1) return -1;
break;
case FCGI_RES_MODE_LENGTH:
if (hio_becs_cat(cli->sbuf, (fcgi->task_keep_client_alive? "Connection: keep-alive\r\n": "Connection: close\r\n")) == (hio_oow_t)-1) return -1;
}
if (hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1) return -1;
if (hio_svc_htts_task_startreshdr(fcgi, status_code, status_desc, chunked) <= -1 ||
hio_htre_walkheaders(req, peer_capture_response_header, fcgi) <= -1 ||
hio_svc_htts_task_endreshdr(fcgi) <= -1) return -1;
fcgi->task_status_code = status_code;
return fcgi_write_to_client(fcgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));

View File

@ -457,6 +457,7 @@ static hio_htrd_recbs_t file_client_htrd_recbs =
static int file_send_header_to_client (file_t* file, int status_code, int force_close, const hio_bch_t* mime_type)
{
#if 0
hio_svc_htts_cli_t* cli = file->task_client;
hio_bch_t dtbuf[64];
hio_foff_t content_length;
@ -494,6 +495,43 @@ static int file_send_header_to_client (file_t* file, int status_code, int force_
file->task_status_code = status_code;
return file_write_to_client(file, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
#else
hio_svc_htts_cli_t* cli = file->task_client;
hio_foff_t content_length;
if (HIO_UNLIKELY(!cli))
{
/* client disconnected or not connectd */
return 0;
}
content_length = file->end_offset - file->start_offset + 1;
if (status_code == HIO_HTTP_STATUS_OK && file->total_size != content_length) status_code = HIO_HTTP_STATUS_PARTIAL_CONTENT;
if (hio_svc_htts_task_startreshdr(file, status_code, HIO_NULL, 0) <= -1) return -1;
if (mime_type && mime_type[0] != '\0' && hio_svc_htts_task_addreshdr(file, "Content-Type", mime_type) <= -1) return -1;
if ((file->task_req_method == HIO_HTTP_GET || file->task_req_method == HIO_HTTP_HEAD) &&
hio_svc_htts_task_addreshdr(file, "ETag", file->peer_etag) <= -1) return -1;
if (status_code == HIO_HTTP_STATUS_PARTIAL_CONTENT &&
hio_svc_htts_task_addreshdrfmt(file, "Content-Ranges", "bytes %ju-%ju/%ju", (hio_uintmax_t)file->start_offset, (hio_uintmax_t)file->end_offset, (hio_uintmax_t)file->total_size) <= -1) return -1;
/* ----- */
// TODO: Allow-Contents
// Allow-Headers... support custom headers...
if (hio_svc_htts_task_addreshdr(file, "Access-Control-Allow-Origin", "*") <= -1) return -1;
/* ----- */
if (hio_svc_htts_task_addreshdrfmt(file, "Content-Length", "%ju", (hio_uintmax_t)content_length) <= -1) return -1;
if (hio_svc_htts_task_endreshdr(file) <= -1) return -1;
file->task_status_code = status_code;
return file_write_to_client(file, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
#endif
}
static void send_contents_to_client_later (hio_t* hio, const hio_ntime_t* now, hio_tmrjob_t* tmrjob)

View File

@ -25,6 +25,7 @@
#include "http-prv.h"
#include <hio-path.h>
#include <errno.h>
#include <stdarg.h>
#define INVALID_LIDX HIO_TYPE_MAX(hio_oow_t)
@ -713,13 +714,12 @@ int hio_svc_htts_task_buildfinalres (hio_svc_htts_task_t* task, int status_code,
hio_bch_t dtbuf[64];
hio_oow_t content_len;
const hio_bch_t* status_msg;
int redir = 0;
if (!cli)
if (HIO_UNLIKELY(!cli))
{
/* the client has probably been disconnected */
HIO_ASSERT (hio, task->task_csck == HIO_NULL);
return 0;
return 0; /* no data */
}
status_msg = hio_http_status_to_bcstr(status_code);
@ -761,6 +761,87 @@ int hio_svc_htts_task_buildfinalres (hio_svc_htts_task_t* task, int status_code,
// if (hio_dev_sck_write(task->task_csck, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf), HIO_NULL, HIO_NULL) <= -1) return -1;
// if (force_close && hio_dev_sck_write(task->task_csck, HIO_NULL, 0, HIO_NULL, HIO_NULL) <= -1) return -1;
return 1;
}
int hio_svc_htts_task_startreshdr (hio_svc_htts_task_t* task, int status_code, const hio_bch_t* status_desc, int chunked)
{
hio_svc_htts_cli_t* cli = task->task_client;
hio_bch_t dtbuf[64];
HIO_ASSERT (task->htts->hio, cli != HIO_NULL);
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d ", task->task_req_version.major, task->task_req_version.minor) == (hio_oow_t)-1) return -1;
if (hio_becs_fcat(cli->sbuf, "%d %hs\r\n", status_code, (status_desc? status_desc: 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 (chunked && hio_becs_cat(cli->sbuf, "Transfer-Encoding: chunked\r\n") == (hio_oow_t)-1) return -1;
if (hio_becs_cat(cli->sbuf, (task->task_keep_client_alive? "Connection: keep-alive\r\n": "Connection: close\r\n")) == (hio_oow_t)-1) return -1;
return 0;
}
static int is_res_header_acceptable (const hio_bch_t* key)
{
return hio_comp_bcstr(key, "Status", 1) != 0 &&
hio_comp_bcstr(key, "Connection", 1) != 0 &&
hio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 &&
hio_comp_bcstr(key, "Server", 1) != 0 &&
hio_comp_bcstr(key, "Date", 1) != 0;
}
int hio_svc_htts_task_addreshdrs (hio_svc_htts_task_t* task, const hio_bch_t* key, const hio_htre_hdrval_t* value)
{
hio_svc_htts_cli_t* cli = task->task_client;
HIO_ASSERT (task->htts->hio, cli != HIO_NULL);
if (!is_res_header_acceptable(key)) return 0; /* ignore it*/
while (value)
{
if (hio_becs_fcat(cli->sbuf, "%hs: %hs\r\n", key, value->ptr) == (hio_oow_t)-1) return -1;
value = value->next;
}
return 0;
}
int hio_svc_htts_task_addreshdr (hio_svc_htts_task_t* task, const hio_bch_t* key, const hio_bch_t* value)
{
hio_svc_htts_cli_t* cli = task->task_client;
HIO_ASSERT (task->htts->hio, cli != HIO_NULL);
if (!is_res_header_acceptable(key)) return 0; /* just ignore it*/
if (hio_becs_fcat(cli->sbuf, "%hs: %hs\r\n", key, value) == (hio_oow_t)-1) return -1;
return 0;
}
int hio_svc_htts_task_addreshdrfmt (hio_svc_htts_task_t* task, const hio_bch_t* key, const hio_bch_t* vfmt, ...)
{
hio_svc_htts_cli_t* cli = task->task_client;
va_list ap;
HIO_ASSERT (task->htts->hio, cli != HIO_NULL);
if (!is_res_header_acceptable(key)) return 0; /* just ignore it*/
if (hio_becs_fcat(cli->sbuf, "%hs: ", key) == (hio_oow_t)-1) return -1;
va_start (ap, vfmt);
if (hio_becs_vfcat(cli->sbuf, vfmt, ap) == (hio_oow_t)-1)
{
va_end (ap);
return -1;
}
va_end (ap);
if (hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1) return -1;
return 0;
}
int hio_svc_htts_task_endreshdr (hio_svc_htts_task_t* task)
{
hio_svc_htts_cli_t* cli = task->task_client;
HIO_ASSERT (task->htts->hio, cli != HIO_NULL);
if (hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1) return -1;
return 0;
}

View File

@ -421,37 +421,14 @@ oops:
return 0;
}
static int thr_peer_capture_response_header (hio_htre_t* req, const hio_bch_t* key, const hio_htre_hdrval_t* val, void* ctx)
static int peer_capture_response_header (hio_htre_t* req, const hio_bch_t* key, const hio_htre_hdrval_t* val, void* ctx)
{
hio_svc_htts_cli_t* cli = (hio_svc_htts_cli_t*)ctx;
/* capture a header except Status, Connection, Transfer-Encoding, and Server */
if (hio_comp_bcstr(key, "Status", 1) != 0 &&
hio_comp_bcstr(key, "Connection", 1) != 0 &&
hio_comp_bcstr(key, "Transfer-Encoding", 1) != 0 &&
hio_comp_bcstr(key, "Server", 1) != 0 &&
hio_comp_bcstr(key, "Date", 1) != 0)
{
do
{
if (hio_becs_cat(cli->sbuf, key) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, ": ") == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, val->ptr) == (hio_oow_t)-1 ||
hio_becs_cat(cli->sbuf, "\r\n") == (hio_oow_t)-1)
{
return -1;
}
val = val->next;
}
while (val);
}
return 0;
return hio_svc_htts_task_addreshdrs((thr_task_t*)ctx, key, val);
}
static int thr_peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
{
#if 0
thr_peer_xtn_t* peer_xtn = hio_htrd_getxtn(htrd);
thr_task_t* thr = peer_xtn->task;
hio_svc_htts_cli_t* cli = thr->task_client;
@ -495,6 +472,33 @@ static int thr_peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
thr->task_status_code = status_code;
return thr_write_to_client(thr, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
#else
thr_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
thr_task_t* thr = peer->task;
hio_svc_htts_cli_t* cli = thr->task_client;
int status_code = HIO_HTTP_STATUS_OK;
const hio_bch_t* status_desc = HIO_NULL;
int chunked;
if (HIO_UNLIKELY(!cli))
{
/* client disconnected or not connectd */
return 0;
}
// TOOD: remove content_length if content_length is negative or not numeric.
if (req->attr.content_length) thr->res_mode_to_cli = THR_RES_MODE_LENGTH;
if (req->attr.status) hio_parse_http_status_header_value(req->attr.status, &status_code, &status_desc);
chunked = thr->task_keep_client_alive && !req->attr.content_length;
if (hio_svc_htts_task_startreshdr(thr, status_code, status_desc, chunked) <= -1 ||
hio_htre_walkheaders(req, peer_capture_response_header, thr) <= -1 ||
hio_svc_htts_task_endreshdr(thr) <= -1) return -1;
thr->task_status_code = status_code;
return thr_write_to_client(thr, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
#endif
}
static int thr_peer_htrd_poke (hio_htrd_t* htrd, hio_htre_t* req)