1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

vhost: add 404 handler url option

This allows you to set a 404 handler URL on a vhost.

The necessary user code looks like...

    info.error_document_404 = "/404.html";

... at vhost-creation time.

In the existing lws_return_http_status() api, if it sees
the vhost has an "error_document_404" path set and that
we are trying to report a 404, it changes the action
instead to a redirect to the error_document_404 path.

The redirect target is returned using 404 status code.

If the redirect target doesn't exist, then it falls back
to just reporting the simple canned 404.
This commit is contained in:
Andy Green 2018-03-07 19:57:34 +08:00
parent 46f10cade7
commit b490079b47
7 changed files with 40 additions and 0 deletions

View file

@ -583,6 +583,11 @@ lws_create_vhost(struct lws_context *context,
else
vh->name = info->vhost_name;
vh->error_document_404 = info->error_document_404;
if (info->error_document_404 &&
info->error_document_404[0] == '/')
vh->error_document_404 = info->error_document_404 + 1;
if (info->options & LWS_SERVER_OPTION_ONLY_RAW)
lwsl_info("%s set to only support RAW\n", vh->name);

View file

@ -233,6 +233,20 @@ lws_return_http_status(struct lws *wsi, unsigned int code,
int n = 0, m = 0, len;
char slen[20];
if (wsi->vhost &&
!wsi->handling_404 &&
wsi->vhost->error_document_404 &&
code == HTTP_STATUS_NOT_FOUND)
/* we should do a redirect, and do the 404 there */
if (lws_http_redirect(wsi, HTTP_STATUS_FOUND,
(uint8_t *)wsi->vhost->error_document_404,
strlen(wsi->vhost->error_document_404),
&p, end) > 0)
return 0;
/* if the redirect failed, just do a simple status */
p = start;
if (!html_body)
html_body = "";

View file

@ -2850,6 +2850,10 @@ struct lws_context_creation_info {
* platform default values.
* Just leave all at 0 if you don't care.
*/
const char *error_document_404;
/**< VHOST: If non-NULL, when asked to serve a non-existent file,
* lws attempts to server this url path instead. Eg,
* "/404.html" */
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility

View file

@ -965,6 +965,7 @@ struct lws_vhost {
const struct lws_protocol_vhost_options *pvo;
const struct lws_protocol_vhost_options *headers;
struct lws **same_vh_protocol_list;
const char *error_document_404;
#ifdef LWS_OPENSSL_SUPPORT
lws_tls_ctx *ssl_ctx;
lws_tls_ctx *ssl_client_ctx;
@ -1951,6 +1952,7 @@ struct lws {
unsigned int rxflow_will_be_applied:1;
unsigned int event_pipe:1;
unsigned int on_same_vh_list:1;
unsigned int handling_404;
unsigned int could_have_pending:1; /* detect back-to-back writes */

View file

@ -101,6 +101,7 @@ static const char * const paths_vhosts[] = {
"vhosts[].onlyraw",
"vhosts[].client-cert-required",
"vhosts[].ignore-missing-cert",
"vhosts[].error-document-404",
};
enum lejp_vhost_paths {
@ -150,6 +151,7 @@ enum lejp_vhost_paths {
LEJPVP_FLAG_ONLYRAW,
LEJPVP_FLAG_CLIENT_CERT_REQUIRED,
LEJPVP_IGNORE_MISSING_CERT,
LEJPVP_ERROR_DOCUMENT_404,
};
static const char * const parser_errs[] = {
@ -708,6 +710,10 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
return 0;
case LEJPVP_ERROR_DOCUMENT_404:
a->info->error_document_404 = a->p;
break;
case LEJPVP_SSL_OPTION_SET:
a->info->ssl_options_set |= atol(ctx->buf);
return 0;

View file

@ -386,6 +386,11 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
#endif
int n;
wsi->handling_404 = 0;
if (wsi->vhost && wsi->vhost->error_document_404 &&
!strcmp(uri, wsi->vhost->error_document_404))
wsi->handling_404 = 1;
lws_snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri);
#if !defined(_WIN32_WCE)
@ -2736,6 +2741,9 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
const struct lws_plat_file_ops *fops;
const char *vpath;
if (wsi->handling_404)
n = HTTP_STATUS_NOT_FOUND;
/*
* We either call the platform fops .open with first arg platform fops,
* or we call fops_zip .open with first arg platform fops, and fops_zip

View file

@ -54,6 +54,7 @@ int main(int argc, char **argv)
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.port = 7681;
info.mounts = &mount;
info.error_document_404 = "/404.html";
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER
/* | LLL_INFO */ /* | LLL_DEBUG */, NULL);