xref: /unit/src/nxt_http_return.c (revision 2102:9ad9385c16e1)
11429Svbart@nginx.com 
21429Svbart@nginx.com /*
31429Svbart@nginx.com  * Copyright (C) NGINX, Inc.
41429Svbart@nginx.com  */
51429Svbart@nginx.com 
61429Svbart@nginx.com #include <nxt_router.h>
71429Svbart@nginx.com #include <nxt_http.h>
81429Svbart@nginx.com 
91429Svbart@nginx.com 
101903Sz.hong@f5.com typedef struct {
112081Salx.manpages@gmail.com     nxt_http_status_t  status;
122081Salx.manpages@gmail.com     nxt_var_t          *location;
132081Salx.manpages@gmail.com     nxt_str_t          encoded;
141903Sz.hong@f5.com } nxt_http_return_conf_t;
151903Sz.hong@f5.com 
161903Sz.hong@f5.com 
172081Salx.manpages@gmail.com typedef struct {
182081Salx.manpages@gmail.com     nxt_str_t          location;
192081Salx.manpages@gmail.com     nxt_str_t          encoded;
202081Salx.manpages@gmail.com } nxt_http_return_ctx_t;
212081Salx.manpages@gmail.com 
222081Salx.manpages@gmail.com 
231903Sz.hong@f5.com static nxt_http_action_t *nxt_http_return(nxt_task_t *task,
241903Sz.hong@f5.com     nxt_http_request_t *r, nxt_http_action_t *action);
252081Salx.manpages@gmail.com static nxt_int_t nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded,
262081Salx.manpages@gmail.com     const nxt_str_t *location);
272081Salx.manpages@gmail.com static void nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data);
282081Salx.manpages@gmail.com static void nxt_http_return_var_error(nxt_task_t *task, void *obj, void *data);
291903Sz.hong@f5.com 
301903Sz.hong@f5.com 
311429Svbart@nginx.com static const nxt_http_request_state_t  nxt_http_return_send_state;
321429Svbart@nginx.com 
331429Svbart@nginx.com 
341903Sz.hong@f5.com nxt_int_t
nxt_http_return_init(nxt_mp_t * mp,nxt_http_action_t * action,nxt_http_action_conf_t * acf)351903Sz.hong@f5.com nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
361903Sz.hong@f5.com     nxt_http_action_conf_t *acf)
371903Sz.hong@f5.com {
382081Salx.manpages@gmail.com     nxt_str_t               str;
391903Sz.hong@f5.com     nxt_http_return_conf_t  *conf;
401903Sz.hong@f5.com 
411903Sz.hong@f5.com     conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t));
421903Sz.hong@f5.com     if (nxt_slow_path(conf == NULL)) {
431903Sz.hong@f5.com         return NXT_ERROR;
441903Sz.hong@f5.com     }
451903Sz.hong@f5.com 
461903Sz.hong@f5.com     action->handler = nxt_http_return;
471903Sz.hong@f5.com     action->u.conf = conf;
481903Sz.hong@f5.com 
491903Sz.hong@f5.com     conf->status = nxt_conf_get_number(acf->ret);
501903Sz.hong@f5.com 
512098Salx.manpages@gmail.com     if (acf->location == NULL) {
522081Salx.manpages@gmail.com         return NXT_OK;
532081Salx.manpages@gmail.com     }
541903Sz.hong@f5.com 
552098Salx.manpages@gmail.com     nxt_conf_get_string(acf->location, &str);
562098Salx.manpages@gmail.com 
572098Salx.manpages@gmail.com     conf->location = nxt_var_compile(&str, mp, 0);
582098Salx.manpages@gmail.com     if (nxt_slow_path(conf->location == NULL)) {
592081Salx.manpages@gmail.com         return NXT_ERROR;
602081Salx.manpages@gmail.com     }
611903Sz.hong@f5.com 
622098Salx.manpages@gmail.com     if (nxt_var_is_const(conf->location)) {
632081Salx.manpages@gmail.com         nxt_var_raw(conf->location, &str);
642081Salx.manpages@gmail.com         return nxt_http_return_encode(mp, &conf->encoded, &str);
651903Sz.hong@f5.com     }
661903Sz.hong@f5.com 
671903Sz.hong@f5.com     return NXT_OK;
681903Sz.hong@f5.com }
691903Sz.hong@f5.com 
701903Sz.hong@f5.com 
711429Svbart@nginx.com nxt_http_action_t *
nxt_http_return(nxt_task_t * task,nxt_http_request_t * r,nxt_http_action_t * action)721903Sz.hong@f5.com nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
731429Svbart@nginx.com     nxt_http_action_t *action)
741429Svbart@nginx.com {
752081Salx.manpages@gmail.com     nxt_int_t               ret;
762081Salx.manpages@gmail.com     nxt_http_return_ctx_t   *ctx;
771903Sz.hong@f5.com     nxt_http_return_conf_t  *conf;
781429Svbart@nginx.com 
791903Sz.hong@f5.com     conf = action->u.conf;
801429Svbart@nginx.com 
81*2102Salx.manpages@gmail.com #if (NXT_DEBUG)
82*2102Salx.manpages@gmail.com     nxt_str_t  loc;
83*2102Salx.manpages@gmail.com 
842081Salx.manpages@gmail.com     if (conf->location == NULL) {
852101Salx.manpages@gmail.com         nxt_str_set(&loc, "");
862081Salx.manpages@gmail.com 
872081Salx.manpages@gmail.com     } else {
882081Salx.manpages@gmail.com         nxt_var_raw(conf->location, &loc);
892081Salx.manpages@gmail.com     }
902081Salx.manpages@gmail.com 
912081Salx.manpages@gmail.com     nxt_debug(task, "http return: %d (loc: \"%V\")", conf->status, &loc);
92*2102Salx.manpages@gmail.com #endif
931903Sz.hong@f5.com 
941903Sz.hong@f5.com     if (conf->status >= NXT_HTTP_BAD_REQUEST
951903Sz.hong@f5.com         && conf->status <= NXT_HTTP_SERVER_ERROR_MAX)
961429Svbart@nginx.com     {
971903Sz.hong@f5.com         nxt_http_request_error(task, r, conf->status);
981429Svbart@nginx.com         return NULL;
991429Svbart@nginx.com     }
1001429Svbart@nginx.com 
1012098Salx.manpages@gmail.com     if (conf->location == NULL) {
1022098Salx.manpages@gmail.com         ctx = NULL;
1032098Salx.manpages@gmail.com 
1042098Salx.manpages@gmail.com     } else {
1052098Salx.manpages@gmail.com         ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_return_ctx_t));
1062098Salx.manpages@gmail.com         if (nxt_slow_path(ctx == NULL)) {
1072098Salx.manpages@gmail.com             goto fail;
1082098Salx.manpages@gmail.com         }
1092081Salx.manpages@gmail.com     }
1102081Salx.manpages@gmail.com 
1111903Sz.hong@f5.com     r->status = conf->status;
1121429Svbart@nginx.com     r->resp.content_length_n = 0;
1131432Svbart@nginx.com 
1142098Salx.manpages@gmail.com     if (ctx == NULL || nxt_var_is_const(conf->location)) {
1152098Salx.manpages@gmail.com         if (ctx != NULL) {
1162098Salx.manpages@gmail.com             ctx->encoded = conf->encoded;
1172098Salx.manpages@gmail.com         }
1182081Salx.manpages@gmail.com 
1192081Salx.manpages@gmail.com         nxt_http_return_send_ready(task, r, ctx);
1202081Salx.manpages@gmail.com 
1212081Salx.manpages@gmail.com     } else {
1222081Salx.manpages@gmail.com         ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
1232081Salx.manpages@gmail.com         if (nxt_slow_path(ret != NXT_OK)) {
1242081Salx.manpages@gmail.com             goto fail;
1252081Salx.manpages@gmail.com         }
1262081Salx.manpages@gmail.com 
1272081Salx.manpages@gmail.com         nxt_var_query(task, r->var_query, conf->location, &ctx->location);
1282081Salx.manpages@gmail.com 
1292081Salx.manpages@gmail.com         nxt_var_query_resolve(task, r->var_query, ctx,
1302081Salx.manpages@gmail.com                               nxt_http_return_send_ready,
1312081Salx.manpages@gmail.com                               nxt_http_return_var_error);
1322081Salx.manpages@gmail.com     }
1332081Salx.manpages@gmail.com 
1342081Salx.manpages@gmail.com     return NULL;
1352081Salx.manpages@gmail.com 
1362081Salx.manpages@gmail.com fail:
1372081Salx.manpages@gmail.com 
1382081Salx.manpages@gmail.com     nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
1392081Salx.manpages@gmail.com     return NULL;
1402081Salx.manpages@gmail.com }
1412081Salx.manpages@gmail.com 
1422081Salx.manpages@gmail.com 
1432081Salx.manpages@gmail.com static nxt_int_t
nxt_http_return_encode(nxt_mp_t * mp,nxt_str_t * encoded,const nxt_str_t * location)1442081Salx.manpages@gmail.com nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded,
1452081Salx.manpages@gmail.com     const nxt_str_t *location)
1462081Salx.manpages@gmail.com {
1472081Salx.manpages@gmail.com     nxt_uint_t  encode;
1482081Salx.manpages@gmail.com 
1492081Salx.manpages@gmail.com     if (nxt_is_complex_uri_encoded(location->start, location->length)) {
1502081Salx.manpages@gmail.com         *encoded = *location;
1512081Salx.manpages@gmail.com 
1522081Salx.manpages@gmail.com         return NXT_OK;
1532081Salx.manpages@gmail.com     }
1542081Salx.manpages@gmail.com 
1552081Salx.manpages@gmail.com     encode = nxt_encode_complex_uri(NULL, location->start, location->length);
1562081Salx.manpages@gmail.com     encoded->length = location->length + encode * 2;
1572081Salx.manpages@gmail.com 
158