xref: /unit/src/nxt_http_proxy.c (revision 1270)
1*1270Sigor@sysoev.ru 
2*1270Sigor@sysoev.ru /*
3*1270Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
4*1270Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
5*1270Sigor@sysoev.ru  */
6*1270Sigor@sysoev.ru 
7*1270Sigor@sysoev.ru #include <nxt_router.h>
8*1270Sigor@sysoev.ru #include <nxt_http.h>
9*1270Sigor@sysoev.ru 
10*1270Sigor@sysoev.ru 
11*1270Sigor@sysoev.ru typedef void (*nxt_http_upstream_connect_t)(nxt_task_t *task,
12*1270Sigor@sysoev.ru     nxt_http_upstream_t *upstream, nxt_http_peer_t *peer);
13*1270Sigor@sysoev.ru 
14*1270Sigor@sysoev.ru 
15*1270Sigor@sysoev.ru struct nxt_http_upstream_s {
16*1270Sigor@sysoev.ru     uint32_t                     current;
17*1270Sigor@sysoev.ru     uint32_t                     n;
18*1270Sigor@sysoev.ru     uint8_t                      protocol;
19*1270Sigor@sysoev.ru     nxt_http_upstream_connect_t  connect;
20*1270Sigor@sysoev.ru     nxt_sockaddr_t               *sockaddr[1];
21*1270Sigor@sysoev.ru };
22*1270Sigor@sysoev.ru 
23*1270Sigor@sysoev.ru 
24*1270Sigor@sysoev.ru static void nxt_http_upstream_connect(nxt_task_t *task,
25*1270Sigor@sysoev.ru     nxt_http_upstream_t *upstream, nxt_http_peer_t *peer);
26*1270Sigor@sysoev.ru static nxt_http_action_t *nxt_http_proxy_handler(nxt_task_t *task,
27*1270Sigor@sysoev.ru     nxt_http_request_t *r, nxt_http_action_t *action);
28*1270Sigor@sysoev.ru static void nxt_http_proxy_header_send(nxt_task_t *task, void *obj, void *data);
29*1270Sigor@sysoev.ru static void nxt_http_proxy_header_sent(nxt_task_t *task, void *obj, void *data);
30*1270Sigor@sysoev.ru static void nxt_http_proxy_header_read(nxt_task_t *task, void *obj, void *data);
31*1270Sigor@sysoev.ru static void nxt_http_proxy_send_body(nxt_task_t *task, void *obj, void *data);
32*1270Sigor@sysoev.ru static void nxt_http_proxy_read(nxt_task_t *task, void *obj, void *data);
33*1270Sigor@sysoev.ru static void nxt_http_proxy_buf_mem_completion(nxt_task_t *task, void *obj,
34*1270Sigor@sysoev.ru     void *data);
35*1270Sigor@sysoev.ru static void nxt_http_proxy_error(nxt_task_t *task, void *obj, void *data);
36*1270Sigor@sysoev.ru 
37*1270Sigor@sysoev.ru 
38*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_send_state;
39*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_sent_state;
40*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_read_state;
41*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_read_state;
42*1270Sigor@sysoev.ru 
43*1270Sigor@sysoev.ru 
44*1270Sigor@sysoev.ru nxt_int_t
45*1270Sigor@sysoev.ru nxt_http_proxy_create(nxt_mp_t *mp, nxt_http_action_t *action)
46*1270Sigor@sysoev.ru {
47*1270Sigor@sysoev.ru     nxt_str_t            name;
48*1270Sigor@sysoev.ru     nxt_sockaddr_t       *sa;
49*1270Sigor@sysoev.ru     nxt_http_upstream_t  *upstream;
50*1270Sigor@sysoev.ru 
51*1270Sigor@sysoev.ru     sa = NULL;
52*1270Sigor@sysoev.ru     name = action->name;
53*1270Sigor@sysoev.ru 
54*1270Sigor@sysoev.ru     if (nxt_str_start(&name, "http://", 7)) {
55*1270Sigor@sysoev.ru         name.length -= 7;
56*1270Sigor@sysoev.ru         name.start += 7;
57*1270Sigor@sysoev.ru 
58*1270Sigor@sysoev.ru         sa = nxt_sockaddr_parse(mp, &name);
59*1270Sigor@sysoev.ru         if (nxt_slow_path(sa == NULL)) {
60*1270Sigor@sysoev.ru             return NXT_ERROR;
61*1270Sigor@sysoev.ru         }
62*1270Sigor@sysoev.ru 
63*1270Sigor@sysoev.ru         sa->type = SOCK_STREAM;
64*1270Sigor@sysoev.ru     }
65*1270Sigor@sysoev.ru 
66*1270Sigor@sysoev.ru     if (sa != NULL) {
67*1270Sigor@sysoev.ru         upstream = nxt_mp_alloc(mp, sizeof(nxt_http_upstream_t));
68*1270Sigor@sysoev.ru         if (nxt_slow_path(upstream == NULL)) {
69*1270Sigor@sysoev.ru             return NXT_ERROR;
70*1270Sigor@sysoev.ru         }
71*1270Sigor@sysoev.ru 
72*1270Sigor@sysoev.ru         upstream->current = 0;
73*1270Sigor@sysoev.ru         upstream->n = 1;
74*1270Sigor@sysoev.ru         upstream->protocol = NXT_HTTP_PROTO_H1;
75*1270Sigor@sysoev.ru         upstream->connect = nxt_http_upstream_connect;
76*1270Sigor@sysoev.ru         upstream->sockaddr[0] = sa;
77*1270Sigor@sysoev.ru 
78*1270Sigor@sysoev.ru         action->u.upstream = upstream;
79*1270Sigor@sysoev.ru         action->handler = nxt_http_proxy_handler;
80*1270Sigor@sysoev.ru     }
81*1270Sigor@sysoev.ru 
82*1270Sigor@sysoev.ru     return NXT_OK;
83*1270Sigor@sysoev.ru }
84*1270Sigor@sysoev.ru 
85*1270Sigor@sysoev.ru 
86*1270Sigor@sysoev.ru static nxt_http_action_t *
87*1270Sigor@sysoev.ru nxt_http_proxy_handler(nxt_task_t *task, nxt_http_request_t *r,
88*1270Sigor@sysoev.ru     nxt_http_action_t *action)
89*1270Sigor@sysoev.ru {
90*1270Sigor@sysoev.ru     nxt_http_peer_t  *peer;
91*1270Sigor@sysoev.ru 
92*1270Sigor@sysoev.ru     peer = nxt_mp_zalloc(r->mem_pool, sizeof(nxt_http_peer_t));
93*1270Sigor@sysoev.ru     if (nxt_slow_path(peer == NULL)) {
94*1270Sigor@sysoev.ru         nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
95*1270Sigor@sysoev.ru         return NULL;
96*1270Sigor@sysoev.ru     }
97*1270Sigor@sysoev.ru 
98*1270Sigor@sysoev.ru     peer->request = r;
99*1270Sigor@sysoev.ru     r->peer = peer;
100*1270Sigor@sysoev.ru 
101*1270Sigor@sysoev.ru     nxt_mp_retain(r->mem_pool);
102*1270Sigor@sysoev.ru 
103*1270Sigor@sysoev.ru     action->u.upstream->connect(task, action->u.upstream, peer);
104*1270Sigor@sysoev.ru 
105*1270Sigor@sysoev.ru     return NULL;
106*1270Sigor@sysoev.ru }
107*1270Sigor@sysoev.ru 
108*1270Sigor@sysoev.ru 
109*1270Sigor@sysoev.ru static void
110*1270Sigor@sysoev.ru nxt_http_upstream_connect(nxt_task_t *task, nxt_http_upstream_t *upstream,
111*1270Sigor@sysoev.ru     nxt_http_peer_t *peer)
112*1270Sigor@sysoev.ru {
113*1270Sigor@sysoev.ru     peer->protocol = upstream->protocol;
114*1270Sigor@sysoev.ru     peer->sockaddr = upstream->sockaddr[0];
115*1270Sigor@sysoev.ru 
116*1270Sigor@sysoev.ru     peer->request->state = &nxt_http_proxy_header_send_state;
117*1270Sigor@sysoev.ru 
118*1270Sigor@sysoev.ru     nxt_http_proto[peer->protocol].peer_connect(task, peer);
119*1270Sigor@sysoev.ru }
120*1270Sigor@sysoev.ru 
121*1270Sigor@sysoev.ru 
122*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_send_state
123*1270Sigor@sysoev.ru     nxt_aligned(64) =
124*1270Sigor@sysoev.ru {
125*1270Sigor@sysoev.ru     .ready_handler = nxt_http_proxy_header_send,
126*1270Sigor@sysoev.ru     .error_handler = nxt_http_proxy_error,
127*1270Sigor@sysoev.ru };
128*1270Sigor@sysoev.ru 
129*1270Sigor@sysoev.ru 
130*1270Sigor@sysoev.ru static void
131*1270Sigor@sysoev.ru nxt_http_proxy_header_send(nxt_task_t *task, void *obj, void *data)
132*1270Sigor@sysoev.ru {
133*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
134*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
135*1270Sigor@sysoev.ru 
136*1270Sigor@sysoev.ru     r = obj;
137*1270Sigor@sysoev.ru     peer = data;
138*1270Sigor@sysoev.ru     r->state = &nxt_http_proxy_header_sent_state;
139*1270Sigor@sysoev.ru 
140*1270Sigor@sysoev.ru     nxt_http_proto[peer->protocol].peer_header_send(task, peer);
141*1270Sigor@sysoev.ru }
142*1270Sigor@sysoev.ru 
143*1270Sigor@sysoev.ru 
144*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_sent_state
145*1270Sigor@sysoev.ru     nxt_aligned(64) =
146*1270Sigor@sysoev.ru {
147*1270Sigor@sysoev.ru     .ready_handler = nxt_http_proxy_header_sent,
148*1270Sigor@sysoev.ru     .error_handler = nxt_http_proxy_error,
149*1270Sigor@sysoev.ru };
150*1270Sigor@sysoev.ru 
151*1270Sigor@sysoev.ru 
152*1270Sigor@sysoev.ru static void
153*1270Sigor@sysoev.ru nxt_http_proxy_header_sent(nxt_task_t *task, void *obj, void *data)
154*1270Sigor@sysoev.ru {
155*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
156*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
157*1270Sigor@sysoev.ru 
158*1270Sigor@sysoev.ru     r = obj;
159*1270Sigor@sysoev.ru     peer = data;
160*1270Sigor@sysoev.ru     r->state = &nxt_http_proxy_header_read_state;
161*1270Sigor@sysoev.ru 
162*1270Sigor@sysoev.ru     nxt_http_proto[peer->protocol].peer_header_read(task, peer);
163*1270Sigor@sysoev.ru }
164*1270Sigor@sysoev.ru 
165*1270Sigor@sysoev.ru 
166*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_header_read_state
167*1270Sigor@sysoev.ru     nxt_aligned(64) =
168*1270Sigor@sysoev.ru {
169*1270Sigor@sysoev.ru     .ready_handler = nxt_http_proxy_header_read,
170*1270Sigor@sysoev.ru     .error_handler = nxt_http_proxy_error,
171*1270Sigor@sysoev.ru };
172*1270Sigor@sysoev.ru 
173*1270Sigor@sysoev.ru 
174*1270Sigor@sysoev.ru static void
175*1270Sigor@sysoev.ru nxt_http_proxy_header_read(nxt_task_t *task, void *obj, void *data)
176*1270Sigor@sysoev.ru {
177*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
178*1270Sigor@sysoev.ru     nxt_http_field_t    *f, *field;
179*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
180*1270Sigor@sysoev.ru 
181*1270Sigor@sysoev.ru     r = obj;
182*1270Sigor@sysoev.ru     peer = data;
183*1270Sigor@sysoev.ru 
184*1270Sigor@sysoev.ru     r->status = peer->status;
185*1270Sigor@sysoev.ru 
186*1270Sigor@sysoev.ru     nxt_debug(task, "http proxy status: %d", peer->status);
187*1270Sigor@sysoev.ru 
188*1270Sigor@sysoev.ru     nxt_list_each(field, peer->fields) {
189*1270Sigor@sysoev.ru 
190*1270Sigor@sysoev.ru         nxt_debug(task, "http proxy header: \"%*s: %*s\"",
191*1270Sigor@sysoev.ru                   (size_t) field->name_length, field->name,
192*1270Sigor@sysoev.ru                   (size_t) field->value_length, field->value);
193*1270Sigor@sysoev.ru 
194*1270Sigor@sysoev.ru         if (!field->skip) {
195*1270Sigor@sysoev.ru             f = nxt_list_add(r->resp.fields);
196*1270Sigor@sysoev.ru             if (nxt_slow_path(f == NULL)) {
197*1270Sigor@sysoev.ru                 nxt_http_proxy_error(task, r, peer);
198*1270Sigor@sysoev.ru                 return;
199*1270Sigor@sysoev.ru             }
200*1270Sigor@sysoev.ru 
201*1270Sigor@sysoev.ru             *f = *field;
202*1270Sigor@sysoev.ru         }
203*1270Sigor@sysoev.ru 
204*1270Sigor@sysoev.ru     } nxt_list_loop;
205*1270Sigor@sysoev.ru 
206*1270Sigor@sysoev.ru     nxt_http_request_header_send(task, r, nxt_http_proxy_send_body, peer);
207*1270Sigor@sysoev.ru }
208*1270Sigor@sysoev.ru 
209*1270Sigor@sysoev.ru 
210*1270Sigor@sysoev.ru static void
211*1270Sigor@sysoev.ru nxt_http_proxy_send_body(nxt_task_t *task, void *obj, void *data)
212*1270Sigor@sysoev.ru {
213*1270Sigor@sysoev.ru     nxt_buf_t           *out;
214*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
215*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
216*1270Sigor@sysoev.ru 
217*1270Sigor@sysoev.ru     r = obj;
218*1270Sigor@sysoev.ru     peer = data;
219*1270Sigor@sysoev.ru     out = peer->body;
220*1270Sigor@sysoev.ru 
221*1270Sigor@sysoev.ru     if (out != NULL) {
222*1270Sigor@sysoev.ru         peer->body = NULL;
223*1270Sigor@sysoev.ru         nxt_http_request_send(task, r, out);
224*1270Sigor@sysoev.ru     }
225*1270Sigor@sysoev.ru 
226*1270Sigor@sysoev.ru     r->state = &nxt_http_proxy_read_state;
227*1270Sigor@sysoev.ru 
228*1270Sigor@sysoev.ru     nxt_http_proto[peer->protocol].peer_read(task, peer);
229*1270Sigor@sysoev.ru }
230*1270Sigor@sysoev.ru 
231*1270Sigor@sysoev.ru 
232*1270Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_proxy_read_state
233*1270Sigor@sysoev.ru     nxt_aligned(64) =
234*1270Sigor@sysoev.ru {
235*1270Sigor@sysoev.ru     .ready_handler = nxt_http_proxy_read,
236*1270Sigor@sysoev.ru     .error_handler = nxt_http_proxy_error,
237*1270Sigor@sysoev.ru };
238*1270Sigor@sysoev.ru 
239*1270Sigor@sysoev.ru 
240*1270Sigor@sysoev.ru static void
241*1270Sigor@sysoev.ru nxt_http_proxy_read(nxt_task_t *task, void *obj, void *data)
242*1270Sigor@sysoev.ru {
243*1270Sigor@sysoev.ru     nxt_buf_t           *out;
244*1270Sigor@sysoev.ru     nxt_bool_t          last;
245*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
246*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
247*1270Sigor@sysoev.ru 
248*1270Sigor@sysoev.ru     r = obj;
249*1270Sigor@sysoev.ru     peer = data;
250*1270Sigor@sysoev.ru     out = peer->body;
251*1270Sigor@sysoev.ru     peer->body = NULL;
252*1270Sigor@sysoev.ru     last = nxt_buf_is_last(out);
253*1270Sigor@sysoev.ru 
254*1270Sigor@sysoev.ru     nxt_http_request_send(task, r, out);
255*1270Sigor@sysoev.ru 
256*1270Sigor@sysoev.ru     if (!last) {
257*1270Sigor@sysoev.ru         nxt_http_proto[peer->protocol].peer_read(task, peer);
258*1270Sigor@sysoev.ru 
259*1270Sigor@sysoev.ru     } else {
260*1270Sigor@sysoev.ru         nxt_http_proto[peer->protocol].peer_close(task, peer);
261*1270Sigor@sysoev.ru 
262*1270Sigor@sysoev.ru         nxt_mp_release(r->mem_pool);
263*1270Sigor@sysoev.ru     }
264*1270Sigor@sysoev.ru }
265*1270Sigor@sysoev.ru 
266*1270Sigor@sysoev.ru 
267*1270Sigor@sysoev.ru nxt_buf_t *
268*1270Sigor@sysoev.ru nxt_http_proxy_buf_mem_alloc(nxt_task_t *task, nxt_http_request_t *r,
269*1270Sigor@sysoev.ru     size_t size)
270*1270Sigor@sysoev.ru {
271*1270Sigor@sysoev.ru     nxt_buf_t  *b;
272*1270Sigor@sysoev.ru 
273*1270Sigor@sysoev.ru     b = nxt_event_engine_buf_mem_alloc(task->thread->engine, size);
274*1270Sigor@sysoev.ru     if (nxt_fast_path(b != NULL)) {
275*1270Sigor@sysoev.ru         b->completion_handler = nxt_http_proxy_buf_mem_completion;
276*1270Sigor@sysoev.ru         b->parent = r;
277*1270Sigor@sysoev.ru         nxt_mp_retain(r->mem_pool);
278*1270Sigor@sysoev.ru 
279*1270Sigor@sysoev.ru     } else {
280*1270Sigor@sysoev.ru         nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
281*1270Sigor@sysoev.ru     }
282*1270Sigor@sysoev.ru 
283*1270Sigor@sysoev.ru     return b;
284*1270Sigor@sysoev.ru }
285*1270Sigor@sysoev.ru 
286*1270Sigor@sysoev.ru 
287*1270Sigor@sysoev.ru static void
288*1270Sigor@sysoev.ru nxt_http_proxy_buf_mem_completion(nxt_task_t *task, void *obj, void *data)
289*1270Sigor@sysoev.ru {
290*1270Sigor@sysoev.ru     nxt_buf_t           *b, *next;
291*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
292*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
293*1270Sigor@sysoev.ru 
294*1270Sigor@sysoev.ru     b = obj;
295*1270Sigor@sysoev.ru     r = data;
296*1270Sigor@sysoev.ru 
297*1270Sigor@sysoev.ru     peer = r->peer;
298*1270Sigor@sysoev.ru 
299*1270Sigor@sysoev.ru     do {
300*1270Sigor@sysoev.ru         next = b->next;
301*1270Sigor@sysoev.ru 
302*1270Sigor@sysoev.ru         nxt_http_proxy_buf_mem_free(task, r, b);
303*1270Sigor@sysoev.ru 
304*1270Sigor@sysoev.ru         b = next;
305*1270Sigor@sysoev.ru     } while (b != NULL);
306*1270Sigor@sysoev.ru 
307*1270Sigor@sysoev.ru     if (!peer->closed) {
308*1270Sigor@sysoev.ru         nxt_http_proto[peer->protocol].peer_read(task, peer);
309*1270Sigor@sysoev.ru     }
310*1270Sigor@sysoev.ru }
311*1270Sigor@sysoev.ru 
312*1270Sigor@sysoev.ru 
313*1270Sigor@sysoev.ru void
314*1270Sigor@sysoev.ru nxt_http_proxy_buf_mem_free(nxt_task_t *task, nxt_http_request_t *r,
315*1270Sigor@sysoev.ru     nxt_buf_t *b)
316*1270Sigor@sysoev.ru {
317*1270Sigor@sysoev.ru     nxt_event_engine_buf_mem_free(task->thread->engine, b);
318*1270Sigor@sysoev.ru 
319*1270Sigor@sysoev.ru     nxt_mp_release(r->mem_pool);
320*1270Sigor@sysoev.ru }
321*1270Sigor@sysoev.ru 
322*1270Sigor@sysoev.ru 
323*1270Sigor@sysoev.ru static void
324*1270Sigor@sysoev.ru nxt_http_proxy_error(nxt_task_t *task, void *obj, void *data)
325*1270Sigor@sysoev.ru {
326*1270Sigor@sysoev.ru     nxt_http_peer_t     *peer;
327*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
328*1270Sigor@sysoev.ru 
329*1270Sigor@sysoev.ru     r = obj;
330*1270Sigor@sysoev.ru     peer = r->peer;
331*1270Sigor@sysoev.ru 
332*1270Sigor@sysoev.ru     nxt_http_proto[peer->protocol].peer_close(task, peer);
333*1270Sigor@sysoev.ru 
334*1270Sigor@sysoev.ru     nxt_mp_release(r->mem_pool);
335*1270Sigor@sysoev.ru 
336*1270Sigor@sysoev.ru     nxt_http_request_error(task, r, peer->status);
337*1270Sigor@sysoev.ru }
338*1270Sigor@sysoev.ru 
339*1270Sigor@sysoev.ru 
340*1270Sigor@sysoev.ru nxt_int_t
341*1270Sigor@sysoev.ru nxt_http_proxy_date(void *ctx, nxt_http_field_t *field, uintptr_t data)
342*1270Sigor@sysoev.ru {
343*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
344*1270Sigor@sysoev.ru 
345*1270Sigor@sysoev.ru     r = ctx;
346*1270Sigor@sysoev.ru 
347*1270Sigor@sysoev.ru     r->resp.date = field;
348*1270Sigor@sysoev.ru 
349*1270Sigor@sysoev.ru     return NXT_OK;
350*1270Sigor@sysoev.ru }
351*1270Sigor@sysoev.ru 
352*1270Sigor@sysoev.ru 
353*1270Sigor@sysoev.ru nxt_int_t
354*1270Sigor@sysoev.ru nxt_http_proxy_content_length(void *ctx, nxt_http_field_t *field,
355*1270Sigor@sysoev.ru     uintptr_t data)
356*1270Sigor@sysoev.ru {
357*1270Sigor@sysoev.ru     nxt_off_t           n;
358*1270Sigor@sysoev.ru     nxt_http_request_t  *r;
359*1270Sigor@sysoev.ru 
360*1270Sigor@sysoev.ru     r = ctx;
361*1270Sigor@sysoev.ru 
362*1270Sigor@sysoev.ru     r->resp.content_length = field;
363*1270Sigor@sysoev.ru 
364*1270Sigor@sysoev.ru     n = nxt_off_t_parse(field->value, field->value_length);
365*1270Sigor@sysoev.ru 
366*1270Sigor@sysoev.ru     if (nxt_fast_path(n >= 0)) {
367*1270Sigor@sysoev.ru         r->resp.content_length_n = n;
368*1270Sigor@sysoev.ru     }
369*1270Sigor@sysoev.ru 
370*1270Sigor@sysoev.ru     return NXT_OK;
371*1270Sigor@sysoev.ru }
372*1270Sigor@sysoev.ru 
373*1270Sigor@sysoev.ru 
374*1270Sigor@sysoev.ru nxt_int_t
375*1270Sigor@sysoev.ru nxt_http_proxy_skip(void *ctx, nxt_http_field_t *field, uintptr_t data)
376*1270Sigor@sysoev.ru {
377*1270Sigor@sysoev.ru     field->skip = 1;
378*1270Sigor@sysoev.ru 
379*1270Sigor@sysoev.ru     return NXT_OK;
380*1270Sigor@sysoev.ru }
381