added hio_svc_htts_task_startreshdr(), hio_svc_htts_task_endreshdr() and others
This commit is contained in:
parent
933d03fe27
commit
86fc103711
@ -30,6 +30,7 @@ struct hio_svc_dhcs_t
|
|||||||
{
|
{
|
||||||
HIO_SVC_HEADER;
|
HIO_SVC_HEADER;
|
||||||
|
|
||||||
|
int stopping;
|
||||||
hio_dev_sck_t* sck;
|
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;
|
if (HIO_UNLIKELY(!dhcs)) goto oops;
|
||||||
|
|
||||||
dhcs->hio = hio;
|
dhcs->hio = hio;
|
||||||
|
dhcs->svc_stop = (hio_svc_stop_t)hio_svc_dhcs_stop;
|
||||||
|
|
||||||
for (i = 0; i < local_nbinds; i++)
|
for (i = 0; i < local_nbinds; i++)
|
||||||
{
|
{
|
||||||
@ -151,3 +153,16 @@ oops:
|
|||||||
}
|
}
|
||||||
return HIO_NULL;
|
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);
|
||||||
|
}
|
||||||
|
@ -498,6 +498,36 @@ HIO_EXPORT int hio_svc_htts_task_buildfinalres (
|
|||||||
int force_close
|
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_EXPORT void hio_svc_htts_fmtgmtime (
|
||||||
hio_svc_htts_t* htts,
|
hio_svc_htts_t* htts,
|
||||||
const hio_ntime_t* nt,
|
const hio_ntime_t* nt,
|
||||||
|
@ -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)
|
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;
|
return hio_svc_htts_task_addreshdrs((cgi_t*)ctx, key, val);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
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_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
|
||||||
cgi_t* cgi = peer->cgi;
|
cgi_t* cgi = peer->cgi;
|
||||||
hio_svc_htts_cli_t* cli = cgi->task_client;
|
hio_svc_htts_cli_t* cli = cgi->task_client;
|
||||||
hio_bch_t dtbuf[64];
|
|
||||||
int status_code = HIO_HTTP_STATUS_OK;
|
int status_code = HIO_HTTP_STATUS_OK;
|
||||||
const hio_bch_t* status_desc = HIO_NULL;
|
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.
|
/* client disconnected or not connectd */
|
||||||
cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH;
|
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);
|
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_svc_htts_task_startreshdr(cgi, status_code, status_desc, chunked) <= -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;
|
hio_htre_walkheaders(req, peer_capture_response_header, cgi) <= -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;
|
hio_svc_htts_task_endreshdr(cgi) <= -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;
|
|
||||||
|
|
||||||
cgi->task_status_code = status_code;
|
cgi->task_status_code = status_code;
|
||||||
return cgi_write_to_client(cgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
return cgi_write_to_client(cgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
||||||
|
@ -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)
|
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;
|
return hio_svc_htts_task_addreshdrs((fcgi_t*)ctx, key, val);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
||||||
{
|
{
|
||||||
fcgi_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
|
fcgi_peer_xtn_t* peer = hio_htrd_getxtn(htrd);
|
||||||
fcgi_t* fcgi = peer->fcgi;
|
fcgi_t* fcgi = peer->fcgi;
|
||||||
hio_svc_htts_cli_t* cli = fcgi->task_client;
|
hio_svc_htts_cli_t* cli = fcgi->task_client;
|
||||||
hio_bch_t dtbuf[64];
|
|
||||||
int status_code = HIO_HTTP_STATUS_OK;
|
int status_code = HIO_HTTP_STATUS_OK;
|
||||||
const hio_bch_t* status_desc = HIO_NULL;
|
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.
|
/* client disconnected or not connectd */
|
||||||
fcgi->res_mode_to_cli = FCGI_RES_MODE_LENGTH;
|
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);
|
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_svc_htts_task_startreshdr(fcgi, status_code, status_desc, chunked) <= -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;
|
hio_htre_walkheaders(req, peer_capture_response_header, fcgi) <= -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;
|
hio_svc_htts_task_endreshdr(fcgi) <= -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;
|
|
||||||
|
|
||||||
fcgi->task_status_code = status_code;
|
fcgi->task_status_code = status_code;
|
||||||
return fcgi_write_to_client(fcgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
return fcgi_write_to_client(fcgi, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
||||||
|
@ -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)
|
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_svc_htts_cli_t* cli = file->task_client;
|
||||||
hio_bch_t dtbuf[64];
|
hio_bch_t dtbuf[64];
|
||||||
hio_foff_t content_length;
|
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;
|
file->task_status_code = status_code;
|
||||||
return file_write_to_client(file, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
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)
|
static void send_contents_to_client_later (hio_t* hio, const hio_ntime_t* now, hio_tmrjob_t* tmrjob)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "http-prv.h"
|
#include "http-prv.h"
|
||||||
#include <hio-path.h>
|
#include <hio-path.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define INVALID_LIDX HIO_TYPE_MAX(hio_oow_t)
|
#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_bch_t dtbuf[64];
|
||||||
hio_oow_t content_len;
|
hio_oow_t content_len;
|
||||||
const hio_bch_t* status_msg;
|
const hio_bch_t* status_msg;
|
||||||
int redir = 0;
|
|
||||||
|
|
||||||
if (!cli)
|
if (HIO_UNLIKELY(!cli))
|
||||||
{
|
{
|
||||||
/* the client has probably been disconnected */
|
/* the client has probably been disconnected */
|
||||||
HIO_ASSERT (hio, task->task_csck == HIO_NULL);
|
HIO_ASSERT (hio, task->task_csck == HIO_NULL);
|
||||||
return 0;
|
return 0; /* no data */
|
||||||
}
|
}
|
||||||
|
|
||||||
status_msg = hio_http_status_to_bcstr(status_code);
|
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 (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;
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,37 +421,14 @@ oops:
|
|||||||
return 0;
|
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;
|
return hio_svc_htts_task_addreshdrs((thr_task_t*)ctx, key, val);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int thr_peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
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_peer_xtn_t* peer_xtn = hio_htrd_getxtn(htrd);
|
||||||
thr_task_t* thr = peer_xtn->task;
|
thr_task_t* thr = peer_xtn->task;
|
||||||
hio_svc_htts_cli_t* cli = thr->task_client;
|
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;
|
thr->task_status_code = status_code;
|
||||||
return thr_write_to_client(thr, HIO_BECS_PTR(cli->sbuf), HIO_BECS_LEN(cli->sbuf));
|
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)
|
static int thr_peer_htrd_poke (hio_htrd_t* htrd, hio_htre_t* req)
|
||||||
|
Loading…
Reference in New Issue
Block a user