xref: /unit/src/nxt_http_rewrite.c (revision 2567:31a8f342d32a)
1 
2 /*
3  * Copyright (C) Zhidao HONG
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_router.h>
8 #include <nxt_http.h>
9 
10 
11 nxt_int_t
nxt_http_rewrite_init(nxt_router_conf_t * rtcf,nxt_http_action_t * action,nxt_http_action_conf_t * acf)12 nxt_http_rewrite_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action,
13     nxt_http_action_conf_t *acf)
14 {
15     nxt_str_t  str;
16 
17     nxt_conf_get_string(acf->rewrite, &str);
18 
19     action->rewrite = nxt_tstr_compile(rtcf->tstr_state, &str, 0);
20     if (nxt_slow_path(action->rewrite == NULL)) {
21         return NXT_ERROR;
22     }
23 
24     return NXT_OK;
25 }
26 
27 
28 nxt_int_t
nxt_http_rewrite(nxt_task_t * task,nxt_http_request_t * r)29 nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r)
30 {
31     u_char                    *p;
32     nxt_int_t                 ret;
33     nxt_str_t                 str, encoded_path, target;
34     nxt_router_conf_t         *rtcf;
35     nxt_http_action_t         *action;
36     nxt_http_request_parse_t  rp;
37 
38     action = r->action;
39 
40     if (action == NULL || action->rewrite == NULL) {
41         return NXT_OK;
42     }
43 
44     if (nxt_tstr_is_const(action->rewrite)) {
45         nxt_tstr_str(action->rewrite, &str);
46 
47     } else {
48         rtcf = r->conf->socket_conf->router_conf;
49 
50         ret = nxt_tstr_query_init(&r->tstr_query, rtcf->tstr_state,
51                                   &r->tstr_cache, r, r->mem_pool);
52         if (nxt_slow_path(ret != NXT_OK)) {
53             return NXT_ERROR;
54         }
55 
56         nxt_tstr_query(task, r->tstr_query, action->rewrite, &str);
57 
58         if (nxt_slow_path(nxt_tstr_query_failed(r->tstr_query))) {
59             return NXT_ERROR;
60         }
61     }
62 
63     nxt_memzero(&rp, sizeof(nxt_http_request_parse_t));
64 
65     rp.mem_pool = r->mem_pool;
66 
67     rp.target_start = str.start;
68     rp.target_end = str.start + str.length;
69 
70     ret = nxt_http_parse_complex_target(&rp);
71     if (nxt_slow_path(ret != NXT_OK)) {
72         return NXT_ERROR;
73     }
74 
75     p = (rp.args.length > 0) ? rp.args.start - 1 : rp.target_end;
76 
77     encoded_path.start = rp.target_start;
78     encoded_path.length = p - encoded_path.start;
79 
80     if (r->args->length == 0) {
81         r->target = encoded_path;
82 
83     } else {
84         target.length = encoded_path.length + 1 + r->args->length;
85 
86         target.start = nxt_mp_alloc(r->mem_pool, target.length);
87         if (target.start == NULL) {
88             return NXT_ERROR;
89         }
90 
91         p = nxt_cpymem(target.start, encoded_path.start, encoded_path.length);
92         *p++ = '?';
93         nxt_memcpy(p, r->args->start, r->args->length);
94 
95         r->target = target;
96         r->args->start = p;
97     }
98 
99     r->path = nxt_mp_alloc(r->mem_pool, sizeof(nxt_str_t));
100     if (nxt_slow_path(r->path == NULL)) {
101         return NXT_ERROR;
102     }
103 
104     *r->path = rp.path;
105 
106     if (nxt_slow_path(r->log_route)) {
107         nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", &r->target);
108     }
109 
110     return NXT_OK;
111 }
112