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