Skip to content

Commit a4dbee1

Browse files
committed
HTTP: Rewrote url target section in nxt_h1p_peer_header_send()
Previously, proxy request was constructed based on the `r->target` field. However, r->target will remain unchanged in the future, even in cases of URL rewriting because of the requirement change for $request_uri that will be changed to constant. To accommodate this, the r->target should be designed to be constant, but Unit needs to pass a changeable URL to the upstream server. Based on the above, the proxy module can't depend on r->target.
1 parent 64934e5 commit a4dbee1

File tree

3 files changed

+74
-5
lines changed

3 files changed

+74
-5
lines changed

src/nxt_h1proto.c

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ static void nxt_h1p_peer_connect(nxt_task_t *task, nxt_http_peer_t *peer);
9090
static void nxt_h1p_peer_connected(nxt_task_t *task, void *obj, void *data);
9191
static void nxt_h1p_peer_refused(nxt_task_t *task, void *obj, void *data);
9292
static void nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer);
93+
static nxt_int_t nxt_h1p_peer_request_target(nxt_http_request_t *r,
94+
nxt_str_t *target);
9395
static void nxt_h1p_peer_header_sent(nxt_task_t *task, void *obj, void *data);
9496
static void nxt_h1p_peer_header_read(nxt_task_t *task, nxt_http_peer_t *peer);
9597
static ssize_t nxt_h1p_peer_io_read_handler(nxt_task_t *task, nxt_conn_t *c);
@@ -654,6 +656,8 @@ nxt_h1p_header_process(nxt_task_t *task, nxt_h1proto_t *h1p,
654656
r->target.start = h1p->parser.target_start;
655657
r->target.length = h1p->parser.target_end - h1p->parser.target_start;
656658

659+
r->quoted_target = h1p->parser.quoted_target;
660+
657661
if (h1p->parser.version.ui64 != 0) {
658662
r->version.start = h1p->parser.version.str;
659663
r->version.length = sizeof(h1p->parser.version.str);
@@ -2263,6 +2267,8 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer)
22632267
{
22642268
u_char *p;
22652269
size_t size;
2270+
nxt_int_t ret;
2271+
nxt_str_t target;
22662272
nxt_buf_t *header, *body;
22672273
nxt_conn_t *c;
22682274
nxt_http_field_t *field;
@@ -2272,7 +2278,12 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer)
22722278

22732279
r = peer->request;
22742280

2275-
size = r->method->length + sizeof(" ") + r->target.length
2281+
ret = nxt_h1p_peer_request_target(r, &target);
2282+
if (nxt_slow_path(ret != NXT_OK)) {
2283+
goto fail;
2284+
}
2285+
2286+
size = r->method->length + sizeof(" ") + target.length
22762287
+ sizeof(" HTTP/1.1\r\n")
22772288
+ sizeof("Connection: close\r\n")
22782289
+ sizeof("\r\n");
@@ -2288,8 +2299,7 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer)
22882299

22892300
header = nxt_http_buf_mem(task, r, size);
22902301
if (nxt_slow_path(header == NULL)) {
2291-
r->state->error_handler(task, r, peer);
2292-
return;
2302+
goto fail;
22932303
}
22942304

22952305
p = header->mem.free;
@@ -2328,8 +2338,7 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer)
23282338
}
23292339

23302340
if (nxt_slow_path(body == NULL)) {
2331-
r->state->error_handler(task, r, peer);
2332-
return;
2341+
goto fail;
23332342
}
23342343

23352344
header->next = body;
@@ -2353,6 +2362,61 @@ nxt_h1p_peer_header_send(nxt_task_t *task, nxt_http_peer_t *peer)
23532362
}
23542363

23552364
nxt_conn_write(task->thread->engine, c);
2365+
2366+
return;
2367+
2368+
fail:
2369+
2370+
r->state->error_handler(task, r, peer);
2371+
}
2372+
2373+
2374+
static nxt_int_t
2375+
nxt_h1p_peer_request_target(nxt_http_request_t *r, nxt_str_t *target)
2376+
{
2377+
u_char *p;
2378+
size_t size, encode;
2379+
2380+
if (!r->uri_changed) {
2381+
*target = r->target;
2382+
return NXT_OK;
2383+
}
2384+
2385+
if (!r->quoted_target && r->args->length == 0) {
2386+
*target = *r->path;
2387+
return NXT_OK;
2388+
}
2389+
2390+
if (r->quoted_target) {
2391+
encode = nxt_encode_complex_uri(NULL, r->path->start,
2392+
r->path->length);
2393+
} else {
2394+
encode = 0;
2395+
}
2396+
2397+
size = r->path->length + encode * 2 + 1 + r->args->length;
2398+
2399+
target->start = nxt_mp_nget(r->mem_pool, size);
2400+
if (target->start == NULL) {
2401+
return NXT_ERROR;
2402+
}
2403+
2404+
if (r->quoted_target) {
2405+
p = (u_char *) nxt_encode_complex_uri(target->start, r->path->start,
2406+
r->path->length);
2407+
2408+
} else {
2409+
p = nxt_cpymem(target->start, r->path->start, r->path->length);
2410+
}
2411+
2412+
if (r->args->length > 0) {
2413+
*p++ = '?';
2414+
p = nxt_cpymem(p, r->args->start, r->args->length);
2415+
}
2416+
2417+
target->length = p - target->start;
2418+
2419+
return NXT_OK;
23562420
}
23572421

23582422

src/nxt_http.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ struct nxt_http_request_s {
192192
nxt_http_status_t status:16;
193193

194194
uint8_t log_route; /* 1 bit */
195+
uint8_t quoted_target; /* 1 bit */
196+
uint8_t uri_changed; /* 1 bit */
195197

196198
uint8_t pass_count; /* 8 bits */
197199
uint8_t app_target;

src/nxt_http_rewrite.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r)
103103

104104
*r->path = rp.path;
105105

106+
r->uri_changed = 1;
107+
r->quoted_target = rp.quoted_target;
108+
106109
if (nxt_slow_path(r->log_route)) {
107110
nxt_log(task, NXT_LOG_NOTICE, "URI rewritten to \"%V\"", &r->target);
108111
}

0 commit comments

Comments
 (0)