| | varnish-cache/bin/varnishd/cache/cache_req.c |
0 |
|
/*- |
1 |
|
* Copyright (c) 2006 Verdens Gang AS |
2 |
|
* Copyright (c) 2006-2011 Varnish Software AS |
3 |
|
* All rights reserved. |
4 |
|
* |
5 |
|
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk> |
6 |
|
* |
7 |
|
* SPDX-License-Identifier: BSD-2-Clause |
8 |
|
* |
9 |
|
* Redistribution and use in source and binary forms, with or without |
10 |
|
* modification, are permitted provided that the following conditions |
11 |
|
* are met: |
12 |
|
* 1. Redistributions of source code must retain the above copyright |
13 |
|
* notice, this list of conditions and the following disclaimer. |
14 |
|
* 2. Redistributions in binary form must reproduce the above copyright |
15 |
|
* notice, this list of conditions and the following disclaimer in the |
16 |
|
* documentation and/or other materials provided with the distribution. |
17 |
|
* |
18 |
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
19 |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
21 |
|
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE |
22 |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
24 |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
26 |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
28 |
|
* SUCH DAMAGE. |
29 |
|
* |
30 |
|
* Request management |
31 |
|
* |
32 |
|
*/ |
33 |
|
|
34 |
|
#include "config.h" |
35 |
|
|
36 |
11934 |
#include <stdio.h> |
37 |
11934 |
#include <stdlib.h> |
38 |
11934 |
|
39 |
11934 |
#include "cache_varnishd.h" |
40 |
|
#include "cache_filter.h" |
41 |
|
#include "cache_pool.h" |
42 |
|
#include "cache_transport.h" |
43 |
|
|
44 |
|
#include "common/heritage.h" |
45 |
|
#include "vtim.h" |
46 |
|
|
47 |
|
void |
48 |
21259 |
Req_AcctLogCharge(struct VSC_main_wrk *ds, struct req *req) |
49 |
|
{ |
50 |
|
struct acct_req *a; |
51 |
|
|
52 |
21259 |
AN(ds); |
53 |
21259 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
54 |
|
|
55 |
21259 |
a = &req->acct; |
56 |
|
|
57 |
21259 |
if (!IS_NO_VXID(req->vsl->wid) && !req->res_pipe) { |
58 |
30864 |
VSLb(req->vsl, SLT_ReqAcct, "%ju %ju %ju %ju %ju %ju", |
59 |
15432 |
(uintmax_t)a->req_hdrbytes, |
60 |
15432 |
(uintmax_t)a->req_bodybytes, |
61 |
15432 |
(uintmax_t)(a->req_hdrbytes + a->req_bodybytes), |
62 |
15432 |
(uintmax_t)a->resp_hdrbytes, |
63 |
15432 |
(uintmax_t)a->resp_bodybytes, |
64 |
15432 |
(uintmax_t)(a->resp_hdrbytes + a->resp_bodybytes)); |
65 |
15432 |
} |
66 |
|
|
67 |
21259 |
if (IS_TOPREQ(req)) { |
68 |
|
#define ACCT(foo) ds->s_##foo += a->foo; |
69 |
|
#include "tbl/acct_fields_req.h" |
70 |
|
} |
71 |
21259 |
memset(a, 0, sizeof *a); |
72 |
21259 |
} |
73 |
|
|
74 |
|
void |
75 |
4449 |
Req_LogHit(struct worker *wrk, struct req *req, struct objcore *oc, |
76 |
|
intmax_t fetch_progress) |
77 |
|
{ |
78 |
|
const char *clen, *sep; |
79 |
|
|
80 |
4449 |
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); |
81 |
4449 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
82 |
4449 |
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); |
83 |
|
|
84 |
4449 |
if (fetch_progress >= 0) { |
85 |
371 |
clen = HTTP_GetHdrPack(wrk, oc, H_Content_Length); |
86 |
371 |
if (clen == NULL) |
87 |
34 |
clen = sep = ""; |
88 |
|
else |
89 |
337 |
sep = " "; |
90 |
742 |
VSLb(req->vsl, SLT_Hit, "%ju %.6f %.6f %.6f %jd%s%s", |
91 |
371 |
VXID(ObjGetXID(wrk, oc)), EXP_Dttl(req, oc), |
92 |
371 |
oc->grace, oc->keep, |
93 |
371 |
fetch_progress, sep, clen); |
94 |
371 |
} else { |
95 |
8156 |
VSLb(req->vsl, SLT_Hit, "%ju %.6f %.6f %.6f", |
96 |
4078 |
VXID(ObjGetXID(wrk, oc)), EXP_Dttl(req, oc), |
97 |
4078 |
oc->grace, oc->keep); |
98 |
|
} |
99 |
4449 |
} |
100 |
|
|
101 |
|
const char * |
102 |
14981 |
Req_LogStart(const struct worker *wrk, struct req *req) |
103 |
|
{ |
104 |
|
const char *ci, *cp, *endpname; |
105 |
|
|
106 |
14981 |
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); |
107 |
14981 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
108 |
14981 |
CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); |
109 |
|
|
110 |
14981 |
ci = SES_Get_String_Attr(req->sp, SA_CLIENT_IP); |
111 |
14981 |
cp = SES_Get_String_Attr(req->sp, SA_CLIENT_PORT); |
112 |
14981 |
CHECK_OBJ_NOTNULL(req->sp->listen_sock, LISTEN_SOCK_MAGIC); |
113 |
14981 |
endpname = req->sp->listen_sock->name; |
114 |
14981 |
AN(endpname); |
115 |
14981 |
VSLb(req->vsl, SLT_ReqStart, "%s %s %s", ci, cp, endpname); |
116 |
|
|
117 |
14981 |
return (ci); |
118 |
|
} |
119 |
|
|
120 |
|
/*-------------------------------------------------------------------- |
121 |
|
* Alloc/Free a request |
122 |
|
*/ |
123 |
|
|
124 |
|
struct req * |
125 |
12013 |
Req_New(struct sess *sp, const struct req *preq) |
126 |
|
{ |
127 |
|
struct pool *pp; |
128 |
|
struct req *req; |
129 |
|
uint16_t nhttp; |
130 |
|
unsigned sz, hl; |
131 |
|
char *p, *e; |
132 |
|
|
133 |
12013 |
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); |
134 |
12013 |
pp = sp->pool; |
135 |
12013 |
CHECK_OBJ_NOTNULL(pp, POOL_MAGIC); |
136 |
12013 |
CHECK_OBJ_ORNULL(preq, REQ_MAGIC); |
137 |
|
|
138 |
12013 |
req = MPL_Get(pp->mpl_req, &sz); |
139 |
12013 |
AN(req); |
140 |
12013 |
req->magic = REQ_MAGIC; |
141 |
12013 |
req->sp = sp; |
142 |
|
|
143 |
12013 |
e = (char*)req + sz; |
144 |
12013 |
p = (char*)(req + 1); |
145 |
12013 |
p = (void*)PRNDUP(p); |
146 |
12013 |
assert(p < e); |
147 |
|
|
148 |
12013 |
nhttp = (uint16_t)cache_param->http_max_hdr; |
149 |
12013 |
hl = HTTP_estimate(nhttp); |
150 |
|
|
151 |
12013 |
req->http = HTTP_create(p, nhttp, hl); |
152 |
12013 |
p += hl; |
153 |
12013 |
p = (void*)PRNDUP(p); |
154 |
12013 |
assert(p < e); |
155 |
|
|
156 |
12013 |
req->http0 = HTTP_create(p, nhttp, hl); |
157 |
12013 |
p += hl; |
158 |
12013 |
p = (void*)PRNDUP(p); |
159 |
12013 |
assert(p < e); |
160 |
|
|
161 |
12013 |
req->resp = HTTP_create(p, nhttp, hl); |
162 |
12013 |
p += hl; |
163 |
12013 |
p = (void*)PRNDUP(p); |
164 |
12013 |
assert(p < e); |
165 |
|
|
166 |
12013 |
sz = cache_param->vsl_buffer; |
167 |
12013 |
VSL_Setup(req->vsl, p, sz); |
168 |
12013 |
p += sz; |
169 |
12013 |
p = (void*)PRNDUP(p); |
170 |
|
|
171 |
12013 |
req->vfc = (void*)p; |
172 |
12013 |
INIT_OBJ(req->vfc, VFP_CTX_MAGIC); |
173 |
12013 |
p = (void*)PRNDUP(p + sizeof(*req->vfc)); |
174 |
|
|
175 |
12013 |
req->vdc = (void*)p; |
176 |
12013 |
ZERO_OBJ(req->vdc, sizeof *req->vdc); |
177 |
12013 |
p = (void*)PRNDUP(p + sizeof(*req->vdc)); |
178 |
|
|
179 |
12013 |
req->htc = (void*)p; |
180 |
12013 |
INIT_OBJ(req->htc, HTTP_CONN_MAGIC); |
181 |
12013 |
req->htc->doclose = SC_NULL; |
182 |
12013 |
p = (void*)PRNDUP(p + sizeof(*req->htc)); |
183 |
|
|
184 |
12013 |
if (UNLIKELY(preq != NULL)) |
185 |
1464 |
req->top = preq->top; |
186 |
|
else { |
187 |
10549 |
req->top = (void*)p; |
188 |
10549 |
INIT_OBJ(req->top, REQTOP_MAGIC); |
189 |
10549 |
req->top->topreq = req; |
190 |
10549 |
p = (void*)PRNDUP(p + sizeof(*req->top)); |
191 |
|
} |
192 |
|
|
193 |
12013 |
assert(p < e); |
194 |
|
|
195 |
12013 |
WS_Init(req->ws, "req", p, e - p); |
196 |
|
|
197 |
12013 |
req->t_first = NAN; |
198 |
12013 |
req->t_prev = NAN; |
199 |
12013 |
req->t_req = NAN; |
200 |
12013 |
req->req_step = R_STP_TRANSPORT; |
201 |
12013 |
req->doclose = SC_NULL; |
202 |
12013 |
req->max_restarts = cache_param->max_restarts; |
203 |
|
|
204 |
12013 |
return (req); |
205 |
|
} |
206 |
|
|
207 |
|
void |
208 |
11934 |
Req_Release(struct req *req) |
209 |
|
{ |
210 |
|
struct sess *sp; |
211 |
|
struct pool *pp; |
212 |
|
|
213 |
11934 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
214 |
|
|
215 |
|
/* Make sure the request counters have all been zeroed */ |
216 |
|
#define ACCT(foo) \ |
217 |
|
AZ(req->acct.foo); |
218 |
|
#include "tbl/acct_fields_req.h" |
219 |
|
|
220 |
11934 |
AZ(req->vcl); |
221 |
11934 |
if (!IS_NO_VXID(req->vsl->wid)) |
222 |
8 |
VSL_End(req->vsl); |
223 |
|
#ifdef ENABLE_WORKSPACE_EMULATOR |
224 |
|
WS_Rollback(req->ws, 0); |
225 |
|
#endif |
226 |
11934 |
TAKE_OBJ_NOTNULL(sp, &req->sp, SESS_MAGIC); |
227 |
|
pp = sp->pool; |
228 |
11934 |
CHECK_OBJ_NOTNULL(pp, POOL_MAGIC); |
229 |
11934 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
230 |
|
MPL_AssertSane(req); |
231 |
|
VSL_Flush(req->vsl, 0); |
232 |
|
MPL_Free(pp->mpl_req, req); |
233 |
|
} |
234 |
|
|
235 |
|
/*---------------------------------------------------------------------- |
236 |
|
* TODO: |
237 |
|
* - check for code duplication with cnt_recv_prep |
238 |
|
* - re-check if complete |
239 |
|
* - XXX should PRIV_TOP use vcl0? |
240 |
|
* - XXX PRIV_TOP does not get rolled back, should it for !IS_TOPREQ ? |
241 |
|
*/ |
242 |
|
|
243 |
|
void |
244 |
740 |
Req_Rollback(VRT_CTX) |
245 |
|
{ |
246 |
|
struct req *req; |
247 |
|
|
248 |
740 |
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); |
249 |
740 |
req = ctx->req; |
250 |
740 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
251 |
|
|
252 |
740 |
if (IS_TOPREQ(req)) |
253 |
728 |
VCL_TaskLeave(ctx, req->top->privs); |
254 |
740 |
VCL_TaskLeave(ctx, req->privs); |
255 |
740 |
VCL_TaskEnter(req->privs); |
256 |
740 |
if (IS_TOPREQ(req)) |
257 |
728 |
VCL_TaskEnter(req->top->privs); |
258 |
740 |
HTTP_Clone(req->http, req->http0); |
259 |
740 |
req->vdp_filter_list = NULL; |
260 |
740 |
req->vfp_filter_list = NULL; |
261 |
740 |
req->vcf = NULL; |
262 |
740 |
if (WS_Overflowed(req->ws)) |
263 |
40 |
req->wrk->stats->ws_client_overflow++; |
264 |
740 |
AN(req->ws_req); |
265 |
740 |
WS_Rollback(req->ws, req->ws_req); |
266 |
740 |
} |
267 |
|
|
268 |
|
/*---------------------------------------------------------------------- |
269 |
|
* TODO: remove code duplication with cnt_recv_prep |
270 |
|
*/ |
271 |
|
|
272 |
|
void |
273 |
16119 |
Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req) |
274 |
|
{ |
275 |
|
|
276 |
16119 |
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); |
277 |
16119 |
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); |
278 |
16119 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
279 |
16119 |
assert(sp == req->sp); |
280 |
16119 |
if (IS_TOPREQ(req)) |
281 |
14655 |
AZ(req->top->vcl0); |
282 |
|
|
283 |
16119 |
AZ(req->director_hint); |
284 |
16119 |
req->restarts = 0; |
285 |
|
|
286 |
16119 |
if (req->vcl != NULL) |
287 |
13127 |
VCL_Recache(wrk, &req->vcl); |
288 |
|
|
289 |
|
/* Charge and log byte counters */ |
290 |
16119 |
if (!IS_NO_VXID(req->vsl->wid)) { |
291 |
15524 |
Req_AcctLogCharge(wrk->stats, req); |
292 |
15524 |
if (!IS_SAME_VXID(req->vsl->wid, sp->vxid)) |
293 |
14937 |
VSL_End(req->vsl); |
294 |
|
else |
295 |
587 |
req->vsl->wid = NO_VXID; /* ending an h2 stream 0 */ |
296 |
15524 |
} |
297 |
|
|
298 |
16119 |
if (!isnan(req->t_prev) && req->t_prev > 0. && req->t_prev > sp->t_idle) |
299 |
14618 |
sp->t_idle = req->t_prev; |
300 |
|
else |
301 |
1501 |
sp->t_idle = W_TIM_real(wrk); |
302 |
|
|
303 |
16119 |
req->t_first = NAN; |
304 |
16119 |
req->t_prev = NAN; |
305 |
16119 |
req->t_req = NAN; |
306 |
16119 |
req->req_body_status = NULL; |
307 |
|
|
308 |
16119 |
req->hash_always_miss = 0; |
309 |
16119 |
req->hash_ignore_busy = 0; |
310 |
16119 |
req->hash_ignore_vary = 0; |
311 |
16119 |
req->esi_level = 0; |
312 |
16119 |
req->is_hit = 0; |
313 |
16119 |
req->req_step = R_STP_TRANSPORT; |
314 |
16119 |
req->vcf = NULL; |
315 |
16119 |
req->doclose = SC_NULL; |
316 |
16119 |
req->htc->doclose = SC_NULL; |
317 |
16119 |
req->htc->body_status = NULL; |
318 |
|
|
319 |
16119 |
if (WS_Overflowed(req->ws)) |
320 |
668 |
wrk->stats->ws_client_overflow++; |
321 |
|
|
322 |
16119 |
wrk->seen_methods = 0; |
323 |
|
|
324 |
16119 |
VDP_Fini(req->vdc); |
325 |
16119 |
} |
326 |
|
|
327 |
|
/*---------------------------------------------------------------------- |
328 |
|
*/ |
329 |
|
|
330 |
|
void v_matchproto_(vtr_req_fail_f) |
331 |
116 |
Req_Fail(struct req *req, stream_close_t reason) |
332 |
|
{ |
333 |
116 |
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); |
334 |
|
|
335 |
116 |
AN(req->transport->req_fail); |
336 |
116 |
req->transport->req_fail(req, reason); |
337 |
116 |
} |