varnish-cache/bin/varnishd/cache/cache_vrt_var.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 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
 * Runtime support for compiled VCL programs
31
 */
32
#include "config.h"
33
34
#include <stdio.h>
35
36
#include "cache_varnishd.h"
37
#include "cache_objhead.h"
38
#include "cache_transport.h"
39
#include "common/heritage.h"
40
41
#include "vcl.h"
42
#include "vtim.h"
43
#include "vtcp.h"
44
45
#include "vrt_obj.h"
46
47
#define VRT_TMO(tmo) (isinf(tmo) ? VRT_DECIMAL_MAX : tmo)
48
49
static char vrt_hostname[255] = "";
50
51
/*--------------------------------------------------------------------
52
 * VRT variables relating to first line of HTTP/1.1 req/resp
53
 */
54
55
static void
56 138
vrt_do_strands(VRT_CTX, struct http *hp, int fld,
57
    const char *err, const char *str, VCL_STRANDS s)
58
{
59
        const char *b;
60
61 138
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
62
63 138
        b = VRT_StrandsWS(hp->ws, str, s);
64 138
        if (b == NULL) {
65 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
66 0
                WS_MarkOverflow(hp->ws);
67 0
                return;
68
        }
69 138
        if (*b == '\0') {
70 6
                VRT_fail(ctx, "Setting %s to empty string", err);
71 6
                return;
72
        }
73 132
        http_SetH(hp, fld, b);
74 138
}
75
76
#define VRT_HDR_L(obj, hdr, fld)                                        \
77
VCL_VOID                                                                \
78
VRT_l_##obj##_##hdr(VRT_CTX, const char *str, VCL_STRANDS s)            \
79
{                                                                       \
80
                                                                        \
81
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
82
        vrt_do_strands(ctx, ctx->http_##obj, fld, #obj "." #hdr, str, s);       \
83
}
84
85
#define VRT_HDR_R(obj, hdr, fld)                                        \
86
VCL_STRING                                                              \
87
VRT_r_##obj##_##hdr(VRT_CTX)                                            \
88
{                                                                       \
89
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
90
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
91
        return (ctx->http_##obj->hd[fld].b);                            \
92
}
93
94
#define VRT_HDR_LR(obj, hdr, fld)                                       \
95
        VRT_HDR_L(obj, hdr, fld)                                        \
96
        VRT_HDR_R(obj, hdr, fld)
97
98
#define VRT_STATUS_L(obj)                                               \
99
VCL_VOID                                                                \
100
VRT_l_##obj##_status(VRT_CTX, VCL_INT num)                              \
101
{                                                                       \
102
                                                                        \
103
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
104
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
105
        if (num < 0)                                                    \
106
                VRT_fail(ctx, "%s.status (%jd) is negative",            \
107
                    #obj, (intmax_t)num);                               \
108
        else if (num > 65535)                                           \
109
                VRT_fail(ctx, "%s.status (%jd) > 65535",                \
110
                    #obj, (intmax_t)num);                               \
111
        else if ((num % 1000) < 100)                                    \
112
                VRT_fail(ctx, "illegal %s.status (%jd) (..0##)",        \
113
                    #obj, (intmax_t)num);                               \
114
        else                                                            \
115
                http_SetStatus(ctx->http_##obj, (uint16_t)num, NULL);   \
116
}
117
118
#define VRT_STATUS_R(obj)                                               \
119
VCL_INT                                                                 \
120
VRT_r_##obj##_status(VRT_CTX)                                           \
121
{                                                                       \
122
                                                                        \
123
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
124
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
125
        return (ctx->http_##obj->status);                               \
126
}
127
128 11682
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
129 9757
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
130 248
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
131
132 8
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
133 8
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
134 8
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
135
136 8
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
137 2812
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
138 90
VRT_STATUS_L(resp)
139 1936
VRT_STATUS_R(resp)
140
141 4578
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
142 1126
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
143 6
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
144 4
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
145 1830
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
146 240
VRT_STATUS_L(beresp)
147 8958
VRT_STATUS_R(beresp)
148
149
/*--------------------------------------------------------------------
150
 * beresp bool-fields
151
 */
152
153
static inline int
154 752
beresp_filter_fixed(VRT_CTX, const char *s)
155
{
156 752
        if (ctx->bo->vfp_filter_list == NULL)
157 750
                return (0);
158 4
        VRT_fail(ctx,
159 2
            "beresp.filters are already fixed, beresp.%s is undefined", s);
160 2
        return (1);
161 752
}
162
163
#define VBERESPWF0(ctx, str) (void) 0
164
#define VBERESPWF1(ctx, str) do {               \
165
        if (beresp_filter_fixed((ctx), str))    \
166
                return;                 \
167
        } while(0)
168
169
#define VBERESPW0(field, str, fltchk)
170
#define VBERESPW1(field, str, fltchk)                                   \
171
void                                                                    \
172
VRT_l_beresp_##field(VRT_CTX, VCL_BOOL a)                               \
173
{                                                                       \
174
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
175
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
176
        VBERESPWF##fltchk(ctx, str);                                    \
177
        ctx->bo->field = a ? 1 : 0;                                     \
178
}
179
180
#define VBERESPRF0(ctx, str) (void) 0
181
#define VBERESPRF1(ctx, str) do {               \
182
        if (beresp_filter_fixed((ctx), str))    \
183
                return (0);                     \
184
        } while(0)
185
186
#define VBERESPR1(field, str, fltchk)                                   \
187
VCL_BOOL                                                                \
188
VRT_r_beresp_##field(VRT_CTX)                                           \
189
{                                                                       \
190
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
191
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
192
        VBERESPRF##fltchk(ctx, str);                                    \
193
        return (ctx->bo->field);                                        \
194
}
195
196
#define BERESP_FLAG(l, r, w, f, d)              \
197
        VBERESPR##r(l, #l, f)                   \
198
        VBERESPW##w(l, #l, f)
199
#include "tbl/beresp_flags.h"
200
201
#undef VBERESPWF0
202
#undef VBERESPWF1
203
#undef VBERESPW0
204
#undef VBERESPW1
205
206
#undef VBERESPRF0
207
#undef VBERESPRF1
208
#undef VBERESPR1
209
210
/*--------------------------------------------------------------------
211
 * bereq bool-fields
212
 */
213
214
#define VBEREQR0(field, str)
215
#define VBEREQR1(field, str)                                            \
216
VCL_BOOL                                                                \
217
VRT_r_bereq_##field(VRT_CTX)                                            \
218
{                                                                       \
219
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
220
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
221
        return (ctx->bo->field);                                        \
222
}
223
224
#define BEREQ_FLAG(l, r, w, d)          \
225
        VBEREQR##r(l, #l)
226
#include "tbl/bereq_flags.h"
227
228
#undef VBEREQR0
229
#undef VBEREQR1
230
/*--------------------------------------------------------------------*/
231
232
VCL_BOOL
233 3862
VRT_r_bereq_uncacheable(VRT_CTX)
234
{
235 3862
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
236 3862
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
237 3862
        return (ctx->bo->uncacheable);
238
}
239
240
VCL_VOID
241 178
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
242
{
243
        struct objcore *oc;
244
245 178
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
246 178
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
247 178
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
248
249 178
        if (ctx->bo->uncacheable && !a) {
250 0
                VSLb(ctx->vsl, SLT_VCL_Error,
251
                    "Ignoring attempt to reset beresp.uncacheable");
252 178
        } else if (a) {
253 176
                ctx->bo->uncacheable = 1;
254 176
        }
255 178
        oc = ctx->bo->fetch_objcore;
256
257 356
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
258 178
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
259 356
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
260
}
261
262
VCL_BOOL
263 2
VRT_r_beresp_uncacheable(VRT_CTX)
264
{
265 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
266 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
267 2
        return (ctx->bo->uncacheable);
268
}
269
270
VCL_VOID
271 2
VRT_l_req_trace(VRT_CTX, VCL_BOOL a)
272
{
273 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
274 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
275 2
        ctx->req->trace = a;
276 2
        VRT_trace(ctx, a);
277 2
}
278
VCL_VOID
279 0
VRT_l_bereq_trace(VRT_CTX, VCL_BOOL a)
280
{
281 0
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
282 0
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
283 0
        ctx->bo->trace = a;
284 0
        VRT_trace(ctx, a);
285 0
}
286
287
/*--------------------------------------------------------------------*/
288
289
VCL_BYTES
290 0
VRT_r_beresp_transit_buffer(VRT_CTX)
291
{
292
    struct objcore *oc;
293
294 0
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
295 0
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
296
297 0
    oc = ctx->bo->fetch_objcore;
298 0
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
299
300 0
    return oc->boc->transit_buffer;
301
}
302
303
VCL_VOID
304 4
VRT_l_beresp_transit_buffer(VRT_CTX, VCL_BYTES value)
305
{
306
    struct objcore *oc;
307
308 4
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
309 4
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
310
311 4
    oc = ctx->bo->fetch_objcore;
312 4
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
313
314 4
    oc->boc->transit_buffer = value;
315 4
}
316
317
/*--------------------------------------------------------------------*/
318
319
VCL_STRING
320 12
VRT_r_client_identity(VRT_CTX)
321
{
322
        const char *id;
323
324 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
325 12
        if (ctx->req != NULL) {
326 8
                CHECK_OBJ(ctx->req, REQ_MAGIC);
327 8
                id = ctx->req->client_identity;
328 8
        } else {
329 4
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
330 4
                id = ctx->bo->client_identity;
331
        }
332 12
        if (id != NULL)
333 8
                return (id);
334 4
        return (SES_Get_String_Attr(ctx->sp, SA_CLIENT_IP));
335 12
}
336
337
VCL_VOID
338 6
VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s)
339
{
340
        const char *b;
341
342 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
343 6
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
344 6
        b = VRT_StrandsWS(ctx->req->http->ws, str, s);
345 6
        if (b == NULL) {
346 0
                VSLb(ctx->vsl, SLT_LostHeader, "client.identity");
347 0
                WS_MarkOverflow(ctx->req->http->ws);
348 0
                return;
349
        }
350 6
        ctx->req->client_identity = b;
351 6
}
352
353
/*--------------------------------------------------------------------*/
354
355
#define BEREQ_TIMEOUT(prefix, which)                            \
356
VCL_VOID                                                        \
357
VRT_l_bereq_##which(VRT_CTX, VCL_DURATION num)                  \
358
{                                                               \
359
                                                                \
360
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
361
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
362
        ctx->bo->which = num;                                   \
363
}                                                               \
364
                                                                \
365
VCL_DURATION                                                    \
366
VRT_r_bereq_##which(VRT_CTX)                                    \
367
{                                                               \
368
        vtim_dur res;                                           \
369
                                                                \
370
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
371
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
372
        res = BUSYOBJ_TMO(ctx->bo, prefix, which);              \
373
        return (VRT_TMO(res));                                  \
374
}                                                               \
375
                                                                \
376
VCL_VOID                                                        \
377
VRT_u_bereq_##which(VRT_CTX)                                    \
378
{                                                               \
379
                                                                \
380
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
381
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
382
        ctx->bo->which = NAN;                                   \
383
}
384
385 14
BEREQ_TIMEOUT(, connect_timeout)
386 18
BEREQ_TIMEOUT(, first_byte_timeout)
387 28
BEREQ_TIMEOUT(, between_bytes_timeout)
388 18
BEREQ_TIMEOUT(pipe_, task_deadline)
389
390
391
/*--------------------------------------------------------------------*/
392
393
VCL_STRING
394 2
VRT_r_beresp_backend_name(VRT_CTX)
395
{
396
397 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
398 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
399 2
        if (ctx->bo->director_resp != NULL)
400 2
                return (ctx->bo->director_resp->vcl_name);
401 0
        return (NULL);
402 2
}
403
404
/*--------------------------------------------------------------------
405
 * Backends do not in general have a IP number (any more) and this
406
 * variable is really not about the backend, but the backend connection.
407
 * XXX: we may need a more general beresp.backend.{details|ident}
408
 */
409
410
VCL_IP
411 2
VRT_r_beresp_backend_ip(VRT_CTX)
412
{
413
414 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
415 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
416 2
        return (VDI_GetIP(ctx->bo));
417
}
418
419
/*--------------------------------------------------------------------*/
420
421
VCL_STEVEDORE
422 2
VRT_r_req_storage(VRT_CTX)
423
{
424 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
425 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
426 2
        return (ctx->req->storage);
427
}
428
429
VCL_VOID
430 12
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
431
{
432 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
433 12
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
434 12
        ctx->req->storage = stv;
435 12
}
436
437
/*--------------------------------------------------------------------*/
438
439
VCL_STEVEDORE
440 20
VRT_r_beresp_storage(VRT_CTX)
441
{
442 20
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
443 20
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
444 20
        return (ctx->bo->storage);
445
}
446
447
VCL_VOID
448 50
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
449
{
450 50
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
451 50
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
452 50
        ctx->bo->storage = stv;
453 50
}
454
455
/*--------------------------------------------------------------------
456
 * VCL <= 4.0 ONLY
457
 */
458
459
#include "storage/storage.h"
460
461
VCL_STRING
462 14
VRT_r_beresp_storage_hint(VRT_CTX)
463
{
464 14
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
465 14
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
466 14
        if (ctx->bo->storage == NULL)
467 2
                return (NULL);
468 12
        CHECK_OBJ_NOTNULL(ctx->bo->storage, STEVEDORE_MAGIC);
469 12
        return (ctx->bo->storage->vclname);
470 14
}
471
472
VCL_VOID
473 2
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, VCL_STRANDS s)
474
{
475
        const char *p;
476
        VCL_STEVEDORE stv;
477
478 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
479 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
480
481 2
        p = VRT_StrandsWS(ctx->ws, str, s);
482
483 2
        if (p == NULL) {
484 0
                VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
485 0
                WS_MarkOverflow(ctx->ws);
486 0
                return;
487
        }
488
489 2
        stv = VRT_stevedore(p);
490 2
        if (stv != NULL)
491 2
                ctx->bo->storage = stv;
492 2
}
493
494
/*--------------------------------------------------------------------*/
495
496
#define VRT_OC_VAR_R(obj, which, which_magic, field)            \
497
VCL_STEVEDORE                                                   \
498
VRT_r_##obj##_storage(VRT_CTX)                                  \
499
{                                                               \
500
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
501
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
502
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
503
        AN(ctx->which->field->stobj);                           \
504
        CHECK_OBJ_NOTNULL(ctx->which->field->stobj->stevedore,  \
505
            STEVEDORE_MAGIC);                                   \
506
        return (ctx->which->field->stobj->stevedore);           \
507
}                                                               \
508
                                                                \
509
VCL_BOOL                                                        \
510
VRT_r_##obj##_can_esi(VRT_CTX)                                  \
511
{                                                               \
512
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
513
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
514
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
515
        return (ObjHasAttr(ctx->which->wrk, ctx->which->field,  \
516
            OA_ESIDATA));                                       \
517
}                                                               \
518
                                                                \
519
VCL_BOOL                                                        \
520
VRT_r_##obj##_uncacheable(VRT_CTX)                              \
521
{                                                               \
522
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
523
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
524
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
525
                                                                \
526
        return (ctx->which->field->flags & OC_F_HFM ? 1 : 0);   \
527
}                                                               \
528
                                                                \
529
VCL_INT                                                         \
530
VRT_r_##obj##_status(VRT_CTX)                                   \
531
{                                                               \
532
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
533
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
534
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
535
                                                                \
536
        return (HTTP_GetStatusPack(ctx->which->wrk,             \
537
            ctx->which->field));                                \
538
}                                                               \
539
                                                                \
540
VCL_STRING                                                      \
541
VRT_r_##obj##_proto(VRT_CTX)                                    \
542
{                                                               \
543
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
544
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
545
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
546
                                                                \
547
        return (HTTP_GetHdrPack(ctx->which->wrk,                \
548
            ctx->which->field, H__Proto));                      \
549
}                                                               \
550
                                                                \
551
VCL_STRING                                                      \
552
VRT_r_##obj##_reason(VRT_CTX)                                   \
553
{                                                               \
554
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
555
        CHECK_OBJ_NOTNULL(ctx->which, which_magic);             \
556
        CHECK_OBJ_NOTNULL(ctx->which->field, OBJCORE_MAGIC);    \
557
                                                                \
558
        return (HTTP_GetHdrPack(ctx->which->wrk,                \
559
            ctx->which->field, H__Reason));                     \
560
}
561
562 44
VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore)
563 74
VRT_OC_VAR_R(obj_stale, bo, BUSYOBJ_MAGIC, stale_oc)
564
565
/*--------------------------------------------------------------------*/
566
567
#define REQ_VAR_L(nm, elem, type, extra)                                \
568
                                                                        \
569
VCL_VOID                                                                \
570
VRT_l_req_##nm(VRT_CTX, type arg)                                       \
571
{                                                                       \
572
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
573
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
574
        extra;                                                          \
575
        ctx->req->elem = arg;                                           \
576
}
577
578
#define REQ_VAR_R(nm, elem, type)                                       \
579
                                                                        \
580
type                                                                    \
581
VRT_r_req_##nm(VRT_CTX)                                                 \
582
{                                                                       \
583
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
584
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
585
        return (ctx->req->elem);                                        \
586
}
587
588
#define REQ_VAR_U(nm, elem, val)                                        \
589
                                                                        \
590
VCL_VOID                                                                \
591
VRT_u_req_##nm(VRT_CTX)                                                 \
592
{                                                                       \
593
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
594
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
595
        ctx->req->elem = val;                                           \
596
}
597
598 32
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
599
600 12
REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
601 12
REQ_VAR_R(ttl, d_ttl, VCL_DURATION)
602 0
REQ_VAR_U(ttl, d_ttl, -1)
603 6
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
604 18
REQ_VAR_R(grace, d_grace, VCL_DURATION)
605 2
REQ_VAR_U(grace, d_grace, -1)
606
607
VCL_VOID
608 290
VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be)
609
{
610
611 290
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
612 290
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
613 290
        VRT_Assign_Backend(&ctx->req->director_hint, be);
614 290
}
615
616
/*--------------------------------------------------------------------*/
617
618
VCL_VOID
619 532
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
620
{
621
622 532
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
623 532
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
624 532
        VRT_Assign_Backend(&ctx->bo->director_req, be);
625 532
}
626
627
VCL_BACKEND
628 92
VRT_r_bereq_backend(VRT_CTX)
629
{
630
631 92
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
632 92
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
633 92
        return (ctx->bo->director_req);
634
}
635
636
VCL_BACKEND
637 78
VRT_r_beresp_backend(VRT_CTX)
638
{
639
640 78
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
641 78
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
642 78
        return (ctx->bo->director_resp);
643
}
644
645
/*--------------------------------------------------------------------*/
646
647
VCL_VOID
648 4368
VRT_u_bereq_body(VRT_CTX)
649
{
650 4368
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
651 4368
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
652
653 4368
        http_Unset(ctx->bo->bereq, H_Content_Length);
654
655 4368
        if (ctx->bo->bereq_body != NULL)
656 10
                (void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body);
657
658 4368
        if (ctx->bo->req != NULL) {
659 16
                CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
660 16
                VBO_SetState(ctx->bo->wrk, ctx->bo, BOS_REQ_DONE);
661 16
                AZ(ctx->bo->req);
662 16
        }
663 4368
}
664
665
/*--------------------------------------------------------------------*/
666
667
VCL_VOID
668 22
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
669
{
670
671 22
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
672 22
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
673 22
        assert(ctx->syntax <= 40);
674
        /*
675
         * Only allow you to turn of esi in the main request
676
         * else everything gets confused
677
         * NOTE: this is not true, but we do not change behavior
678
         * for vcl 4.0. For 4.1, see VRT_l_resp_do_esi()
679
         */
680 22
        if (IS_TOPREQ(ctx->req))
681 14
                ctx->req->disable_esi = !process_esi;
682 22
}
683
684
VCL_BOOL
685 6
VRT_r_req_esi(VRT_CTX)
686
{
687
688 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
689 6
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
690 6
        assert(ctx->syntax <= 40);
691 6
        return (!ctx->req->disable_esi);
692
}
693
694
VCL_INT
695 461
VRT_r_req_esi_level(VRT_CTX)
696
{
697
698 461
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
699 461
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
700 461
        return (ctx->req->esi_level);
701
}
702
703
/*--------------------------------------------------------------------*/
704
705
VCL_BOOL
706 16
VRT_r_req_can_gzip(VRT_CTX)
707
{
708
709 16
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
710 16
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
711 16
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
712
}
713
714
/*--------------------------------------------------------------------*/
715
716
VCL_INT
717 282
VRT_r_req_restarts(VRT_CTX)
718
{
719
720 282
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
721 282
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
722 282
        return (ctx->req->restarts);
723
}
724
725
VCL_INT
726 124
VRT_r_bereq_retries(VRT_CTX)
727
{
728
729 124
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
730 124
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
731 124
        return (ctx->bo->retries);
732
}
733
734
/*--------------------------------------------------------------------*/
735
736
VCL_STRING
737 34
VRT_r_req_transport(VRT_CTX)
738
{
739 34
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
740
741 34
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
742 34
        CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC);
743 34
        return (ctx->req->transport->name);
744
}
745
746
/*--------------------------------------------------------------------
747
 * In exp.*:
748
 *      t_origin is absolute
749
 *      ttl is relative to t_origin
750
 *      grace&keep are relative to ttl
751
 * In VCL:
752
 *      ttl is relative to "ttl_now", which is t_req on the client
753
 *      side, except in vcl_deliver, where it is ctx->now. On the
754
 *      fetch side "ttl_now" is ctx->now (which is bo->t_prev).
755
 *      grace&keep are relative to ttl
756
 */
757
758
static double
759 3072
ttl_now(VRT_CTX)
760
{
761 3072
        if (ctx->bo) {
762 3016
                return (ctx->now);
763
        } else {
764 56
                CHECK_OBJ(ctx->req, REQ_MAGIC);
765 56
                return (ctx->method == VCL_MET_DELIVER
766 56
                    ? ctx->now : ctx->req->t_req);
767
        }
768 3072
}
769
770
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
771
                                                                \
772
VCL_VOID                                                        \
773
VRT_l_##which##_##fld(VRT_CTX, VCL_DURATION a)                  \
774
{                                                               \
775
                                                                \
776
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
777
        a += (offset);                                          \
778
        if (a < 0.0)                                            \
779
                a = 0.0;                                        \
780
        oc->fld = a;                                            \
781
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
782
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
783
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
784
}
785
786
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
787
                                                                \
788
VCL_DURATION                                                    \
789
VRT_r_##which##_##fld(VRT_CTX)                                  \
790
{                                                               \
791
        double d;                                               \
792
                                                                \
793
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
794
        d = oc->fld;                                            \
795
        if (d <= 0.0)                                           \
796
                d = 0.0;                                        \
797
        d -= (offset);                                          \
798
        return (d);                                             \
799
}
800
801
/*lint -save -e835 */   // Zero right hand arg to '-'
802
803 2
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, ttl,
804
    ttl_now(ctx) - ctx->bo->stale_oc->t_origin)
805 40
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
806
    ttl_now(ctx) - ctx->req->objcore->t_origin)
807 2
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, grace, 0)
808 20
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
809 2
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, keep, 0)
810 14
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
811 468
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
812
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
813 2542
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
814
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
815
816 244
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
817 12
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
818 152
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
819 2
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
820
821
/*lint -restore */
822
823
// XXX more assertions?
824
#define VRT_DO_TIME_R(which, where, field)                              \
825
                                                                        \
826
VCL_TIME                                                                \
827
VRT_r_##which##_time(VRT_CTX)                                           \
828
{                                                                       \
829
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
830
        AN((ctx)->where);                                               \
831
                                                                        \
832
        return ((ctx)->where->field);                                   \
833
}
834
835 18
VRT_DO_TIME_R(req, req, t_req)
836 8
VRT_DO_TIME_R(req_top, req->top->topreq, t_req)
837 8
VRT_DO_TIME_R(resp, req, t_resp)
838 12
VRT_DO_TIME_R(bereq, bo, t_first)
839 4
VRT_DO_TIME_R(beresp, bo, t_resp)
840 4
VRT_DO_TIME_R(obj, req->objcore, t_origin)
841 2
VRT_DO_TIME_R(obj_stale, bo->stale_oc, t_origin)
842
843
/*--------------------------------------------------------------------
844
 */
845
846
#define VRT_DO_AGE_R(which, oc)                                 \
847
                                                                \
848
VCL_DURATION                                                    \
849
VRT_r_##which##_##age(VRT_CTX)                                  \
850
{                                                               \
851
                                                                \
852
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
853
        return (ttl_now(ctx) - oc->t_origin);                   \
854
}
855
856 2
VRT_DO_AGE_R(obj_stale, ctx->bo->stale_oc)
857 16
VRT_DO_AGE_R(obj, ctx->req->objcore)
858 2
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
859
860
/*--------------------------------------------------------------------
861
 * [[be]req|sess].xid
862
 */
863
864
VCL_INT
865 1338
VRT_r_req_xid(VRT_CTX)
866
{
867
868 1338
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
869 1338
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
870 1338
        CHECK_OBJ_NOTNULL(ctx->req->http, HTTP_MAGIC);
871 1338
        AN(ctx->req->vsl);
872 1338
        return (VXID(ctx->req->vsl->wid));
873
}
874
875
VCL_INT
876 1108
VRT_r_bereq_xid(VRT_CTX)
877
{
878
879 1108
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
880 1108
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
881 1108
        AN(ctx->bo->vsl);
882
883 1108
        return (VXID(ctx->bo->vsl->wid));
884
}
885
886
VCL_INT
887 14
VRT_r_sess_xid(VRT_CTX)
888
{
889
        struct sess *sp;
890
891 14
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
892
893 14
        if (ctx->req) {
894 8
                CHECK_OBJ(ctx->req, REQ_MAGIC);
895 8
                sp = ctx->req->sp;
896 8
        } else {
897 6
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
898 6
                sp = ctx->bo->sp;
899
        }
900
901 14
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
902 14
        return (VXID(sp->vxid));
903
}
904
905
/*--------------------------------------------------------------------
906
 * req fields
907
 */
908
909
#define VREQW0(field)
910
#define VREQW1(field)                                                   \
911
VCL_VOID                                                                \
912
VRT_l_req_##field(VRT_CTX, VCL_BOOL a)                                  \
913
{                                                                       \
914
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
915
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
916
        ctx->req->field = a ? 1 : 0;                                    \
917
}
918
919
#define VREQR0(field)
920
#define VREQR1(field)                                                   \
921
VCL_BOOL                                                                \
922
VRT_r_req_##field(VRT_CTX)                                              \
923
{                                                                       \
924
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
925
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
926
        return (ctx->req->field);                                       \
927
}
928
929
#define REQ_FLAG(l, r, w, d) \
930
        VREQR##r(l) \
931
        VREQW##w(l)
932
#include "tbl/req_flags.h"
933
934
/*--------------------------------------------------------------------*/
935
936
#define GIP(fld)                                                \
937
        VCL_IP                                                  \
938
        VRT_r_##fld##_ip(VRT_CTX)                               \
939
        {                                                       \
940
                struct suckaddr *sa;                            \
941
                                                                \
942
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
943
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
944
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
945
                return (sa);                                    \
946
        }
947
948 98
GIP(local)
949 100
GIP(remote)
950 202
GIP(client)
951 427
GIP(server)
952
#undef GIP
953
954
/*--------------------------------------------------------------------
955
 * local.[endpoint|socket]
956
 */
957
958
#define LOC(var,fld)                                            \
959
VCL_STRING                                                      \
960
VRT_r_local_##var(VRT_CTX)                                      \
961
{                                                               \
962
        struct sess *sp;                                        \
963
                                                                \
964
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
965
        if (ctx->req) {                                         \
966
                CHECK_OBJ(ctx->req, REQ_MAGIC);                 \
967
                sp = ctx->req->sp;                              \
968
        } else {                                                \
969
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);      \
970
                sp = ctx->bo->sp;                               \
971
        }                                                       \
972
                                                                \
973
        CHECK_OBJ_NOTNULL(sp->listen_sock, LISTEN_SOCK_MAGIC);  \
974
        AN(sp->listen_sock->fld);                               \
975
        return (sp->listen_sock->fld);                          \
976
}
977
978 14
LOC(endpoint, endpoint)
979 14
LOC(socket, name)
980
#undef LOC
981
982
/*--------------------------------------------------------------------*/
983
984
VCL_STRING
985 20
VRT_r_server_identity(VRT_CTX)
986
{
987
988 20
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
989 20
        if (heritage.identity != NULL)
990 20
                return (heritage.identity);
991
        else
992 0
                return ("varnishd");
993 20
}
994
995
VCL_STRING
996 6
VRT_r_server_hostname(VRT_CTX)
997
{
998
999 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1000 6
        if (vrt_hostname[0] == '\0')
1001 4
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
1002 6
        return (vrt_hostname);
1003
}
1004
1005
/*--------------------------------------------------------------------*/
1006
1007
VCL_INT
1008 104
VRT_r_obj_hits(VRT_CTX)
1009
{
1010 104
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1011 104
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1012 104
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1013 104
        if (ctx->method == VCL_MET_HIT)
1014 4
                return (ctx->req->objcore->hits);
1015 100
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
1016 104
}
1017
1018
/*--------------------------------------------------------------------*/
1019
1020
VCL_INT
1021 2
VRT_r_obj_stale_hits(VRT_CTX)
1022
{
1023 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1024 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1025 2
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1026
1027 2
        return (ctx->bo->stale_oc->hits);
1028
}
1029
1030
VCL_BOOL
1031 72
VRT_r_obj_stale_is_valid(VRT_CTX)
1032
{
1033 72
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1034 72
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1035 72
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1036
1037 72
        return (!(ctx->bo->stale_oc->flags & OC_F_DYING));
1038
}
1039
1040
/*--------------------------------------------------------------------*/
1041
1042
VCL_BOOL
1043 10
VRT_r_resp_is_streaming(VRT_CTX)
1044
{
1045 10
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1046 10
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1047 10
        if (ctx->req->objcore == NULL)
1048 2
                return (0);     /* When called from vcl_synth */
1049 8
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1050 8
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
1051 10
}
1052
1053
/*--------------------------------------------------------------------*/
1054
1055
static inline int
1056 28
resp_filter_fixed(VRT_CTX, const char *s)
1057
{
1058 28
        if (ctx->req->vdp_filter_list == NULL)
1059 26
                return (0);
1060 2
        VRT_fail(ctx, "resp.filters are already fixed, %s is undefined", s);
1061 2
        return (1);
1062 28
}
1063
1064
VCL_VOID
1065 10
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
1066
{
1067
1068 10
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1069 10
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1070 10
        assert(ctx->syntax >= 41);
1071 10
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1072 2
                return;
1073 8
        ctx->req->disable_esi = !process_esi;
1074 10
}
1075
1076
VCL_BOOL
1077 18
VRT_r_resp_do_esi(VRT_CTX)
1078
{
1079
1080 18
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1081 18
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1082 18
        assert(ctx->syntax >= 41);
1083 18
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1084 0
                return (0);
1085 18
        return (!ctx->req->disable_esi);
1086 18
}
1087
1088
/*--------------------------------------------------------------------*/
1089
1090
#define VRT_BODY_L(which)                                       \
1091
VCL_VOID                                                        \
1092
VRT_l_##which##_body(VRT_CTX, enum lbody_e type,                \
1093
    const char *str, VCL_BODY body)                             \
1094
{                                                               \
1095
        int n;                                                  \
1096
        struct vsb *vsb;                                        \
1097
        VCL_STRANDS s;                                          \
1098
        VCL_BLOB b;                                             \
1099
                                                                \
1100
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1101
        AN(body);                                               \
1102
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
1103
        if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB) \
1104
                VSB_clear(vsb);                                 \
1105
        if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) { \
1106
                AZ(str);                                        \
1107
                b = body;                                       \
1108
                CHECK_OBJ_NOTNULL(b, VRT_BLOB_MAGIC);           \
1109
                VSB_bcat(vsb, b->blob, b->len);                 \
1110
                return;                                         \
1111
        }                                                       \
1112
        if (str != NULL)                                        \
1113
                VSB_cat(vsb, str);                              \
1114
        assert(type == LBODY_SET_STRING ||                      \
1115
            type == LBODY_ADD_STRING);                          \
1116
        s = body;                                               \
1117
        CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);                    \
1118
        for (n = 0; s != NULL && n < s->n; n++)                 \
1119
                if (s->p[n] != NULL)                            \
1120
                        VSB_cat(vsb, s->p[n]);                  \
1121
}
1122
1123 8512
VRT_BODY_L(beresp)
1124 13054
VRT_BODY_L(resp)
1125
1126
/*--------------------------------------------------------------------*/
1127
1128
                        /* digest */
1129
#define BLOB_HASH_TYPE 0x00d16357
1130
1131
VCL_BLOB
1132 8
VRT_r_req_hash(VRT_CTX)
1133
{
1134 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1135 8
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1136 8
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN,
1137
            BLOB_HASH_TYPE));
1138
}
1139
1140
VCL_BLOB
1141 24
VRT_r_bereq_hash(VRT_CTX)
1142
{
1143 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1144 24
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1145 24
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN,
1146
            BLOB_HASH_TYPE));
1147
}
1148
1149
/*--------------------------------------------------------------------*/
1150
1151
#define HTTP_VAR(x)                                             \
1152
VCL_HTTP                                                        \
1153
VRT_r_##x(VRT_CTX)                                              \
1154
{                                                               \
1155
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1156
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
1157
        return (ctx->http_##x);                                 \
1158
}
1159
1160 30
HTTP_VAR(req)
1161 2
HTTP_VAR(resp)
1162 18
HTTP_VAR(bereq)
1163 0
HTTP_VAR(beresp)
1164
1165
/*--------------------------------------------------------------------*/
1166
1167
static inline void
1168 6
set_idle_send_timeout(const struct sess *sp, VCL_DURATION d)
1169
{
1170 6
        struct timeval tv = VTIM_timeval_sock(d);
1171 6
        VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
1172
            &tv, sizeof tv));
1173 6
}
1174
1175
#define SESS_VAR_DUR(x, setter)                         \
1176
VCL_VOID                                                \
1177
VRT_l_sess_##x(VRT_CTX, VCL_DURATION d)                 \
1178
{                                                       \
1179
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1180
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1181
        d = vmax(d, 0.0);                               \
1182
        setter;                                         \
1183
        ctx->sp->x = d;                                 \
1184
}                                                       \
1185
                                                        \
1186
VCL_DURATION                                            \
1187
VRT_r_sess_##x(VRT_CTX)                                 \
1188
{                                                       \
1189
        vtim_dur res;                                   \
1190
                                                        \
1191
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1192
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1193
        res = SESS_TMO(ctx->sp, x);                     \
1194
        return (VRT_TMO(res));                          \
1195
}                                                       \
1196
                                                        \
1197
VCL_VOID                                                \
1198
VRT_u_sess_##x(VRT_CTX)                                 \
1199
{                                                       \
1200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1201
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1202
        ctx->sp->x = NAN;                               \
1203
}
1204
1205 20
SESS_VAR_DUR(timeout_idle, )
1206 22
SESS_VAR_DUR(timeout_linger, )
1207 14
SESS_VAR_DUR(send_timeout, )
1208 16
SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d))
1209
1210
/*--------------------------------------------------------------------*/
1211
1212
#define PARAM_VAR(x, type)                              \
1213
VCL_##type                                              \
1214
VRT_r_param_##x(VRT_CTX)                                \
1215
{                                                       \
1216
                                                        \
1217
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1218
        return (cache_param->x);                        \
1219
}                                                       \
1220
1221 0
PARAM_VAR(backend_idle_timeout, DURATION)
1222 0
PARAM_VAR(backend_wait_limit, INT)
1223 0
PARAM_VAR(backend_wait_timeout, DURATION)
1224 0
PARAM_VAR(between_bytes_timeout, DURATION)
1225 0
PARAM_VAR(connect_timeout, DURATION)
1226 0
PARAM_VAR(default_grace, DURATION)
1227 0
PARAM_VAR(default_keep, DURATION)
1228 0
PARAM_VAR(default_ttl, DURATION)
1229 0
PARAM_VAR(first_byte_timeout, DURATION)
1230 0
PARAM_VAR(idle_send_timeout, DURATION)
1231 0
PARAM_VAR(max_esi_depth, INT)
1232 0
PARAM_VAR(max_restarts, INT)
1233 0
PARAM_VAR(max_retries, INT)
1234 0
PARAM_VAR(pipe_task_deadline, DURATION)
1235 0
PARAM_VAR(pipe_timeout, DURATION)
1236 0
PARAM_VAR(send_timeout, DURATION)
1237 0
PARAM_VAR(shortlived, DURATION)
1238 4
PARAM_VAR(timeout_idle, DURATION)
1239 0
PARAM_VAR(transit_buffer, BYTES)
1240 84
PARAM_VAR(uncacheable_ttl, DURATION)