added hio_parse_http_status_header_value()
This commit is contained in:
parent
47b1ac034d
commit
490591ca32
@ -110,12 +110,18 @@ enum hio_http_status_t
|
|||||||
HIO_HTTP_STATUS_MOVED_PERMANENTLY = 301,
|
HIO_HTTP_STATUS_MOVED_PERMANENTLY = 301,
|
||||||
HIO_HTTP_STATUS_MOVED_TEMPORARILY = 302,
|
HIO_HTTP_STATUS_MOVED_TEMPORARILY = 302,
|
||||||
HIO_HTTP_STATUS_NOT_MODIFIED = 304,
|
HIO_HTTP_STATUS_NOT_MODIFIED = 304,
|
||||||
|
HIO_HTTP_STATUS_TEMPORARY_REDIRECT = 307,
|
||||||
|
HIO_HTTP_STATUS_PERMANENT_REDIRECT = 308,
|
||||||
|
|
||||||
HIO_HTTP_STATUS_BAD_REQUEST = 400,
|
HIO_HTTP_STATUS_BAD_REQUEST = 400,
|
||||||
HIO_HTTP_STATUS_UNAUTHORIZED = 401,
|
HIO_HTTP_STATUS_UNAUTHORIZED = 401,
|
||||||
|
HIO_HTTP_STATUS_PAYMENT_REQUIRED = 402,
|
||||||
HIO_HTTP_STATUS_FORBIDDEN = 403,
|
HIO_HTTP_STATUS_FORBIDDEN = 403,
|
||||||
HIO_HTTP_STATUS_NOT_FOUND = 404,
|
HIO_HTTP_STATUS_NOT_FOUND = 404,
|
||||||
HIO_HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
|
HIO_HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
|
||||||
|
HIO_HTTP_STATUS_NOT_ACCEPTABLE = 406,
|
||||||
|
HIO_HTTP_STATUS_PROXY_AUTH_REQUIRED = 407,
|
||||||
|
HIO_HTTP_STATUS_REQUEST_TIMEOUT = 408,
|
||||||
HIO_HTTP_STATUS_LENGTH_REQUIRED = 411,
|
HIO_HTTP_STATUS_LENGTH_REQUIRED = 411,
|
||||||
HIO_HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
|
HIO_HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
|
||||||
HIO_HTTP_STATUS_EXPECTATION_FAILED = 417,
|
HIO_HTTP_STATUS_EXPECTATION_FAILED = 417,
|
||||||
|
@ -358,6 +358,12 @@ HIO_EXPORT hio_oow_t hio_escape_html_bcstr (
|
|||||||
hio_oow_t len
|
hio_oow_t len
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HIO_EXPORT int hio_parse_http_status_header_value (
|
||||||
|
const hio_bch_t* status_value, /* value of the Status header */
|
||||||
|
int* status_code, /* [OUT] parsed status code*/
|
||||||
|
const hio_bch_t** status_desc /* [OUT] parsed status description - HIO_NULL if omitted in the value */
|
||||||
|
);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* HTTP SERVER SERVICE */
|
/* HTTP SERVER SERVICE */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
@ -533,7 +533,7 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
|||||||
hio_svc_htts_cli_t* cli = cgi->task_client;
|
hio_svc_htts_cli_t* cli = cgi->task_client;
|
||||||
hio_bch_t dtbuf[64];
|
hio_bch_t dtbuf[64];
|
||||||
int status_code = HIO_HTTP_STATUS_OK;
|
int status_code = HIO_HTTP_STATUS_OK;
|
||||||
const hio_bch_t* status_line = HIO_NULL;
|
const hio_bch_t* status_desc = HIO_NULL;
|
||||||
|
|
||||||
if (req->attr.content_length)
|
if (req->attr.content_length)
|
||||||
{
|
{
|
||||||
@ -541,53 +541,14 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
|||||||
cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH;
|
cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->attr.status)
|
if (req->attr.status) hio_parse_http_status_header_value(req->attr.status, &status_code, &status_desc);
|
||||||
{
|
|
||||||
int is_sober;
|
|
||||||
const hio_bch_t* begptr, * endptr;
|
|
||||||
hio_intmax_t v;
|
|
||||||
hio_oow_t code_len;
|
|
||||||
hio_oow_t desc_len;
|
|
||||||
|
|
||||||
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));
|
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
|
||||||
|
|
||||||
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_fmt(cli->sbuf, "HTTP/%d.%d ", cgi->task_req_version.major, cgi->task_req_version.minor) == (hio_oow_t)-1) return -1;
|
||||||
if (status_line)
|
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, "%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_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;
|
if (hio_htre_walkheaders(req, peer_capture_response_header, cli) <= -1) return -1;
|
||||||
|
|
||||||
switch (cgi->res_mode_to_cli)
|
switch (cgi->res_mode_to_cli)
|
||||||
|
@ -436,7 +436,7 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
|||||||
hio_svc_htts_cli_t* cli = fcgi->task_client;
|
hio_svc_htts_cli_t* cli = fcgi->task_client;
|
||||||
hio_bch_t dtbuf[64];
|
hio_bch_t dtbuf[64];
|
||||||
int status_code = HIO_HTTP_STATUS_OK;
|
int status_code = HIO_HTTP_STATUS_OK;
|
||||||
const hio_bch_t* status_line = HIO_NULL;
|
const hio_bch_t* status_desc = HIO_NULL;
|
||||||
|
|
||||||
if (req->attr.content_length)
|
if (req->attr.content_length)
|
||||||
{
|
{
|
||||||
@ -444,51 +444,12 @@ static int peer_htrd_peek (hio_htrd_t* htrd, hio_htre_t* req)
|
|||||||
fcgi->res_mode_to_cli = FCGI_RES_MODE_LENGTH;
|
fcgi->res_mode_to_cli = FCGI_RES_MODE_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->attr.status)
|
if (req->attr.status) hio_parse_http_status_header_value(req->attr.status, &status_code, &status_desc);
|
||||||
{
|
|
||||||
int is_sober;
|
|
||||||
const hio_bch_t* begptr, * endptr;
|
|
||||||
hio_intmax_t v;
|
|
||||||
hio_oow_t code_len;
|
|
||||||
hio_oow_t desc_len;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
/* use the whole line as it is - e.g. Status: 302 Moved*/
|
|
||||||
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));
|
hio_svc_htts_fmtgmtime (cli->htts, HIO_NULL, dtbuf, HIO_COUNTOF(dtbuf));
|
||||||
|
|
||||||
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_fmt(cli->sbuf, "HTTP/%d.%d ", fcgi->task_req_version.major, fcgi->task_req_version.minor) == (hio_oow_t)-1) return -1;
|
||||||
if (status_line)
|
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, "%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_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;
|
if (hio_htre_walkheaders(req, peer_capture_response_header, cli) <= -1) return -1;
|
||||||
|
@ -158,7 +158,10 @@ static int file_send_final_status_to_client (file_t* file, int status_code, int
|
|||||||
status_msg = "";
|
status_msg = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status_code == HIO_HTTP_STATUS_MOVED_PERMANENTLY || status_code == HIO_HTTP_STATUS_MOVED_TEMPORARILY)
|
if (status_code == HIO_HTTP_STATUS_MOVED_PERMANENTLY ||
|
||||||
|
status_code == HIO_HTTP_STATUS_MOVED_TEMPORARILY ||
|
||||||
|
status_code == HIO_HTTP_STATUS_TEMPORARY_REDIRECT ||
|
||||||
|
status_code == HIO_HTTP_STATUS_PERMANENT_REDIRECT)
|
||||||
{
|
{
|
||||||
/* don't send content body when the status code is 3xx. include the Location header only. */
|
/* don't send content body when the status code is 3xx. include the Location header only. */
|
||||||
if (hio_becs_fcat(cli->sbuf, "Content-Type: text/plain\r\nContent-Length: 0\r\nLocation: %hs%hs\r\n\r\n", file->task_req_qpath, (file->task_req_qpath_ending_with_slash? "": "/")) == (hio_oow_t)-1) return -1;
|
if (hio_becs_fcat(cli->sbuf, "Content-Type: text/plain\r\nContent-Length: 0\r\nLocation: %hs%hs\r\n\r\n", file->task_req_qpath, (file->task_req_qpath_ending_with_slash? "": "/")) == (hio_oow_t)-1) return -1;
|
||||||
|
@ -730,7 +730,10 @@ int hio_svc_https_task_sendfinal (hio_svc_htts_task_t* task, int status_code, co
|
|||||||
if (status_code != HIO_HTTP_STATUS_OK) content_len = 0;
|
if (status_code != HIO_HTTP_STATUS_OK) content_len = 0;
|
||||||
content_text = "";
|
content_text = "";
|
||||||
}
|
}
|
||||||
else if (status_code == HIO_HTTP_STATUS_MOVED_PERMANENTLY || status_code == HIO_HTTP_STATUS_MOVED_TEMPORARILY)
|
else if (status_code == HIO_HTTP_STATUS_MOVED_PERMANENTLY ||
|
||||||
|
status_code == HIO_HTTP_STATUS_MOVED_TEMPORARILY ||
|
||||||
|
status_code == HIO_HTTP_STATUS_TEMPORARY_REDIRECT ||
|
||||||
|
status_code == HIO_HTTP_STATUS_PERMANENT_REDIRECT)
|
||||||
{
|
{
|
||||||
content_len = 0;
|
content_len = 0;
|
||||||
}
|
}
|
||||||
@ -830,5 +833,3 @@ int hio_svc_htts_writetosidechan (hio_svc_htts_t* htts, hio_oow_t idx, const voi
|
|||||||
|
|
||||||
return hio_dev_sck_writetosidechan(htts->l.sck[idx], dptr, dlen);
|
return hio_dev_sck_writetosidechan(htts->l.sck[idx], dptr, dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
53
lib/http.c
53
lib/http.c
@ -63,18 +63,18 @@ const hio_bch_t* hio_http_status_to_bcstr (int code)
|
|||||||
case 303: msg = "See Other"; break;
|
case 303: msg = "See Other"; break;
|
||||||
case HIO_HTTP_STATUS_NOT_MODIFIED: msg = "Not Modified"; break;
|
case HIO_HTTP_STATUS_NOT_MODIFIED: msg = "Not Modified"; break;
|
||||||
case 305: msg = "Use Proxy"; break;
|
case 305: msg = "Use Proxy"; break;
|
||||||
case 307: msg = "Temporary Redirect"; break;
|
case HIO_HTTP_STATUS_TEMPORARY_REDIRECT: msg = "Temporary Redirect"; break;
|
||||||
case 308: msg = "Permanent Redirect"; break;
|
case HIO_HTTP_STATUS_PERMANENT_REDIRECT: msg = "Permanent Redirect"; break;
|
||||||
|
|
||||||
case HIO_HTTP_STATUS_BAD_REQUEST: msg = "Bad Request"; break;
|
case HIO_HTTP_STATUS_BAD_REQUEST: msg = "Bad Request"; break;
|
||||||
case HIO_HTTP_STATUS_UNAUTHORIZED: msg = "Unauthorized"; break;
|
case HIO_HTTP_STATUS_UNAUTHORIZED: msg = "Unauthorized"; break;
|
||||||
case 402: msg = "Payment Required"; break;
|
case HIO_HTTP_STATUS_PAYMENT_REQUIRED: msg = "Payment Required"; break;
|
||||||
case HIO_HTTP_STATUS_FORBIDDEN: msg = "Forbidden"; break;
|
case HIO_HTTP_STATUS_FORBIDDEN: msg = "Forbidden"; break;
|
||||||
case HIO_HTTP_STATUS_NOT_FOUND: msg = "Not Found"; break;
|
case HIO_HTTP_STATUS_NOT_FOUND: msg = "Not Found"; break;
|
||||||
case HIO_HTTP_STATUS_METHOD_NOT_ALLOWED: msg = "Method Not Allowed"; break;
|
case HIO_HTTP_STATUS_METHOD_NOT_ALLOWED: msg = "Method Not Allowed"; break;
|
||||||
case 406: msg = "Not Acceptable"; break;
|
case HIO_HTTP_STATUS_NOT_ACCEPTABLE: msg = "Not Acceptable"; break;
|
||||||
case 407: msg = "Proxy Authentication Required"; break;
|
case HIO_HTTP_STATUS_PROXY_AUTH_REQUIRED: msg = "Proxy Authentication Required"; break;
|
||||||
case 408: msg = "Request Timeout"; break;
|
case HIO_HTTP_STATUS_REQUEST_TIMEOUT: msg = "Request Timeout"; break;
|
||||||
case 409: msg = "Conflict"; break;
|
case 409: msg = "Conflict"; break;
|
||||||
case 410: msg = "Gone"; break;
|
case 410: msg = "Gone"; break;
|
||||||
case HIO_HTTP_STATUS_LENGTH_REQUIRED: msg = "Length Required"; break;
|
case HIO_HTTP_STATUS_LENGTH_REQUIRED: msg = "Length Required"; break;
|
||||||
@ -741,3 +741,44 @@ hio_oow_t hio_escape_html_bcstr (const hio_bch_t* str, hio_bch_t* buf, hio_oow_t
|
|||||||
|
|
||||||
return reqlen;
|
return reqlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hio_parse_http_status_header_value (const hio_bch_t* status_value, int* status_code, const hio_bch_t** status_desc)
|
||||||
|
{
|
||||||
|
const hio_bch_t* begptr, * endptr;
|
||||||
|
int v_is_sober = 1;
|
||||||
|
hio_intmax_t v = 0;
|
||||||
|
hio_oow_t code_len;
|
||||||
|
hio_oow_t desc_len;
|
||||||
|
|
||||||
|
endptr = status_value;
|
||||||
|
while (hio_is_bch_space(*endptr)) endptr++;
|
||||||
|
begptr = endptr;
|
||||||
|
while (hio_is_bch_digit(*endptr))
|
||||||
|
{
|
||||||
|
v = v * 10 + (*endptr - '0');
|
||||||
|
if (v > HIO_TYPE_MAX(int)) v_is_sober = 0;
|
||||||
|
endptr++;
|
||||||
|
}
|
||||||
|
code_len = endptr - begptr;
|
||||||
|
|
||||||
|
while (hio_is_bch_space(*endptr)) endptr++;
|
||||||
|
begptr = endptr;
|
||||||
|
while (*endptr != '\0') endptr++;
|
||||||
|
desc_len = endptr - begptr;
|
||||||
|
|
||||||
|
if (v_is_sober)
|
||||||
|
{
|
||||||
|
*status_code = v;
|
||||||
|
*status_desc = HIO_NULL;
|
||||||
|
if (code_len > 0 && desc_len > 0)
|
||||||
|
{
|
||||||
|
/* the status line could be simply "Status: 302" or more verbose like "Status: 302 Moved"
|
||||||
|
* the value may contain more than numbers */
|
||||||
|
*status_desc = begptr;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no sober - do not update *status_code and *status_desc */
|
||||||
|
return -1; /* not sober */
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user