Implemented "return" action.
The "return" action can be used to immediately generate a simple HTTP response
with an arbitrary status:
{
"action": {
"return": 404
}
}
This is especially useful for denying access to specific resources.
This commit is contained in:
@@ -87,6 +87,7 @@ NXT_LIB_SRCS=" \
|
|||||||
src/nxt_http_error.c \
|
src/nxt_http_error.c \
|
||||||
src/nxt_http_route.c \
|
src/nxt_http_route.c \
|
||||||
src/nxt_http_route_addr.c \
|
src/nxt_http_route_addr.c \
|
||||||
|
src/nxt_http_return.c \
|
||||||
src/nxt_http_static.c \
|
src/nxt_http_static.c \
|
||||||
src/nxt_http_proxy.c \
|
src/nxt_http_proxy.c \
|
||||||
src/nxt_application.c \
|
src/nxt_application.c \
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ static nxt_int_t nxt_conf_vldt_action(nxt_conf_validation_t *vldt,
|
|||||||
nxt_conf_value_t *value, void *data);
|
nxt_conf_value_t *value, void *data);
|
||||||
static nxt_int_t nxt_conf_vldt_pass(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_pass(nxt_conf_validation_t *vldt,
|
||||||
nxt_conf_value_t *value, void *data);
|
nxt_conf_value_t *value, void *data);
|
||||||
|
static nxt_int_t nxt_conf_vldt_return(nxt_conf_validation_t *vldt,
|
||||||
|
nxt_conf_value_t *value, void *data);
|
||||||
static nxt_int_t nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt,
|
||||||
nxt_conf_value_t *value, void *data);
|
nxt_conf_value_t *value, void *data);
|
||||||
static nxt_int_t nxt_conf_vldt_routes(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_routes(nxt_conf_validation_t *vldt,
|
||||||
@@ -354,6 +356,16 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_pass_action_members[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_conf_vldt_object_t nxt_conf_vldt_return_action_members[] = {
|
||||||
|
{ nxt_string("return"),
|
||||||
|
NXT_CONF_VLDT_INTEGER,
|
||||||
|
&nxt_conf_vldt_return,
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
NXT_CONF_VLDT_END
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = {
|
static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = {
|
||||||
{ nxt_string("share"),
|
{ nxt_string("share"),
|
||||||
NXT_CONF_VLDT_STRING,
|
NXT_CONF_VLDT_STRING,
|
||||||
@@ -978,6 +990,7 @@ nxt_conf_vldt_action(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
|
|
||||||
} actions[] = {
|
} actions[] = {
|
||||||
{ nxt_string("pass"), nxt_conf_vldt_pass_action_members },
|
{ nxt_string("pass"), nxt_conf_vldt_pass_action_members },
|
||||||
|
{ nxt_string("return"), nxt_conf_vldt_return_action_members },
|
||||||
{ nxt_string("share"), nxt_conf_vldt_share_action_members },
|
{ nxt_string("share"), nxt_conf_vldt_share_action_members },
|
||||||
{ nxt_string("proxy"), nxt_conf_vldt_proxy_action_members },
|
{ nxt_string("proxy"), nxt_conf_vldt_proxy_action_members },
|
||||||
};
|
};
|
||||||
@@ -993,8 +1006,8 @@ nxt_conf_vldt_action(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
|
|
||||||
if (members != NULL) {
|
if (members != NULL) {
|
||||||
return nxt_conf_vldt_error(vldt, "The \"action\" object must have "
|
return nxt_conf_vldt_error(vldt, "The \"action\" object must have "
|
||||||
"just one of \"pass\", \"share\" or "
|
"just one of \"pass\", \"return\", "
|
||||||
"\"proxy\" options set.");
|
"\"share\", or \"proxy\" options set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
members = actions[i].members;
|
members = actions[i].members;
|
||||||
@@ -1002,8 +1015,8 @@ nxt_conf_vldt_action(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
|||||||
|
|
||||||
if (members == NULL) {
|
if (members == NULL) {
|
||||||
return nxt_conf_vldt_error(vldt, "The \"action\" object must have "
|
return nxt_conf_vldt_error(vldt, "The \"action\" object must have "
|
||||||
"either \"pass\", \"share\", or "
|
"either \"pass\", \"return\", \"share\", "
|
||||||
"\"proxy\" option set.");
|
"or \"proxy\" option set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return nxt_conf_vldt_object(vldt, value, members);
|
return nxt_conf_vldt_object(vldt, value, members);
|
||||||
@@ -1114,6 +1127,23 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_return(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int64_t status;
|
||||||
|
|
||||||
|
status = nxt_conf_get_integer(value);
|
||||||
|
|
||||||
|
if (status < NXT_HTTP_INVALID || status > NXT_HTTP_STATUS_MAX) {
|
||||||
|
return nxt_conf_vldt_error(vldt, "The \"return\" value is out of "
|
||||||
|
"allowed HTTP status code range 0-999.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||||
void *data)
|
void *data)
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ typedef enum {
|
|||||||
NXT_HTTP_SERVICE_UNAVAILABLE = 503,
|
NXT_HTTP_SERVICE_UNAVAILABLE = 503,
|
||||||
NXT_HTTP_GATEWAY_TIMEOUT = 504,
|
NXT_HTTP_GATEWAY_TIMEOUT = 504,
|
||||||
NXT_HTTP_VERSION_NOT_SUPPORTED = 505,
|
NXT_HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||||
|
NXT_HTTP_SERVER_ERROR_MAX = 599,
|
||||||
|
|
||||||
|
NXT_HTTP_STATUS_MAX = 999,
|
||||||
} nxt_http_status_t;
|
} nxt_http_status_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -192,6 +195,7 @@ struct nxt_http_action_s {
|
|||||||
nxt_http_action_t *fallback;
|
nxt_http_action_t *fallback;
|
||||||
nxt_upstream_t *upstream;
|
nxt_upstream_t *upstream;
|
||||||
uint32_t upstream_number;
|
uint32_t upstream_number;
|
||||||
|
nxt_http_status_t return_code;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
nxt_str_t name;
|
nxt_str_t name;
|
||||||
@@ -282,6 +286,9 @@ nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
|
nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
|
||||||
nxt_upstream_t ***upstream_joint);
|
nxt_upstream_t ***upstream_joint);
|
||||||
|
|
||||||
|
nxt_http_action_t *nxt_http_return_handler(nxt_task_t *task,
|
||||||
|
nxt_http_request_t *r, nxt_http_action_t *action);
|
||||||
|
|
||||||
nxt_http_action_t *nxt_http_static_handler(nxt_task_t *task,
|
nxt_http_action_t *nxt_http_static_handler(nxt_task_t *task,
|
||||||
nxt_http_request_t *r, nxt_http_action_t *action);
|
nxt_http_request_t *r, nxt_http_action_t *action);
|
||||||
nxt_int_t nxt_http_static_mtypes_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
|
nxt_int_t nxt_http_static_mtypes_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
|
||||||
|
|||||||
42
src/nxt_http_return.c
Normal file
42
src/nxt_http_return.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) NGINX, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nxt_router.h>
|
||||||
|
#include <nxt_http.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_http_request_state_t nxt_http_return_send_state;
|
||||||
|
|
||||||
|
|
||||||
|
nxt_http_action_t *
|
||||||
|
nxt_http_return_handler(nxt_task_t *task, nxt_http_request_t *r,
|
||||||
|
nxt_http_action_t *action)
|
||||||
|
{
|
||||||
|
nxt_http_status_t status;
|
||||||
|
|
||||||
|
status = action->u.return_code;
|
||||||
|
|
||||||
|
if (status >= NXT_HTTP_BAD_REQUEST
|
||||||
|
&& status <= NXT_HTTP_SERVER_ERROR_MAX)
|
||||||
|
{
|
||||||
|
nxt_http_request_error(task, r, status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->status = status;
|
||||||
|
r->resp.content_length_n = 0;
|
||||||
|
r->state = &nxt_http_return_send_state;
|
||||||
|
|
||||||
|
nxt_http_request_header_send(task, r, NULL, NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const nxt_http_request_state_t nxt_http_return_send_state
|
||||||
|
nxt_aligned(64) =
|
||||||
|
{
|
||||||
|
.error_handler = nxt_http_request_error_handler,
|
||||||
|
};
|
||||||
@@ -41,6 +41,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nxt_conf_value_t *pass;
|
nxt_conf_value_t *pass;
|
||||||
|
nxt_conf_value_t *ret;
|
||||||
nxt_conf_value_t *share;
|
nxt_conf_value_t *share;
|
||||||
nxt_conf_value_t *proxy;
|
nxt_conf_value_t *proxy;
|
||||||
nxt_conf_value_t *fallback;
|
nxt_conf_value_t *fallback;
|
||||||
@@ -575,6 +576,11 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = {
|
|||||||
NXT_CONF_MAP_PTR,
|
NXT_CONF_MAP_PTR,
|
||||||
offsetof(nxt_http_route_action_conf_t, pass)
|
offsetof(nxt_http_route_action_conf_t, pass)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
nxt_string("return"),
|
||||||
|
NXT_CONF_MAP_PTR,
|
||||||
|
offsetof(nxt_http_route_action_conf_t, ret)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
nxt_string("share"),
|
nxt_string("share"),
|
||||||
NXT_CONF_MAP_PTR,
|
NXT_CONF_MAP_PTR,
|
||||||
@@ -613,6 +619,12 @@ nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv,
|
|||||||
|
|
||||||
nxt_memzero(action, sizeof(nxt_http_action_t));
|
nxt_memzero(action, sizeof(nxt_http_action_t));
|
||||||
|
|
||||||
|
if (accf.ret != NULL) {
|
||||||
|
action->handler = nxt_http_return_handler;
|
||||||
|
action->u.return_code = nxt_conf_get_integer(accf.ret);
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
conf = accf.pass;
|
conf = accf.pass;
|
||||||
|
|
||||||
if (accf.share != NULL) {
|
if (accf.share != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user