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 69
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 69
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
62
63 69
        b = VRT_StrandsWS(hp->ws, str, s);
64 69
        if (b == NULL) {
65 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
66 0
                WS_MarkOverflow(hp->ws);
67 0
                return;
68
        }
69 69
        if (*b == '\0') {
70 3
                VRT_fail(ctx, "Setting %s to empty string", err);
71 3
                return;
72
        }
73 66
        http_SetH(hp, fld, b);
74 69
}
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 5838
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
129 4878
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
130 124
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
131
132 4
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
133 4
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
134 4
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
135
136 4
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
137 1406
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
138 45
VRT_STATUS_L(resp)
139 968
VRT_STATUS_R(resp)
140
141 2289
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
142 563
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
143 3
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
144 2
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
145 915
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
146 120
VRT_STATUS_L(beresp)
147 4479
VRT_STATUS_R(beresp)
148
149
/*--------------------------------------------------------------------
150
 * beresp bool-fields
151
 */
152
153
static inline int
154 376
beresp_filter_fixed(VRT_CTX, const char *s)
155
{
156 376
        if (ctx->bo->vfp_filter_list == NULL)
157 375
                return (0);
158 2
        VRT_fail(ctx,
159 1
            "beresp.filters are already fixed, beresp.%s is undefined", s);
160 1
        return (1);
161 376
}
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 1931
VRT_r_bereq_uncacheable(VRT_CTX)
234
{
235 1931
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
236 1931
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
237 1931
        return (ctx->bo->uncacheable);
238
}
239
240
VCL_VOID
241 89
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
242
{
243
        struct objcore *oc;
244
245 89
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
246 89
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
247 89
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
248
249 89
        if (ctx->bo->uncacheable && !a) {
250 0
                VSLb(ctx->vsl, SLT_VCL_Error,
251
                    "Ignoring attempt to reset beresp.uncacheable");
252 89
        } else if (a) {
253 88
                ctx->bo->uncacheable = 1;
254 88
        }
255 89
        oc = ctx->bo->fetch_objcore;
256
257 178
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
258 89
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
259 178
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
260
}
261
262
VCL_BOOL
263 1
VRT_r_beresp_uncacheable(VRT_CTX)
264
{
265 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
266 1
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
267 1
        return (ctx->bo->uncacheable);
268
}
269
270
VCL_VOID
271 1
VRT_l_req_trace(VRT_CTX, VCL_BOOL a)
272
{
273 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
274 1
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
275 1
        ctx->req->trace = a;
276 1
        VRT_trace(ctx, a);
277 1
}
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 2
VRT_l_beresp_transit_buffer(VRT_CTX, VCL_BYTES value)
305
{
306
    struct objcore *oc;
307
308 2
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
309 2
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
310
311 2
    oc = ctx->bo->fetch_objcore;
312 2
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
313
314 2
    oc->boc->transit_buffer = value;
315 2
}
316
317
/*--------------------------------------------------------------------*/
318
319
VCL_STRING
320 6
VRT_r_client_identity(VRT_CTX)
321
{
322
        const char *id;
323
324 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
325 6
        if (ctx->req != NULL) {
326 4
                CHECK_OBJ(ctx->req, REQ_MAGIC);
327 4
                id = ctx->req->client_identity;
328 4
        } else {
329 2
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
330 2
                id = ctx->bo->client_identity;
331
        }
332 6
        if (id != NULL)
333 4
                return (id);
334 2
        return (SES_Get_String_Attr(ctx->sp, SA_CLIENT_IP));
335 6
}
336
337
VCL_VOID
338 3
VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s)
339
{
340
        const char *b;
341
342 3
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
343 3
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
344 3
        b = VRT_StrandsWS(ctx->req->http->ws, str, s);
345 3
        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 3
        ctx->req->client_identity = b;
351 3
}
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 7
BEREQ_TIMEOUT(, connect_timeout)
386 9
BEREQ_TIMEOUT(, first_byte_timeout)
387 14
BEREQ_TIMEOUT(, between_bytes_timeout)
388 9
BEREQ_TIMEOUT(pipe_, task_deadline)
389
390
391
/*--------------------------------------------------------------------*/
392
393
VCL_STRING
394 1
VRT_r_beresp_backend_name(VRT_CTX)
395
{
396
397 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
398 1
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
399 1
        if (ctx->bo->director_resp != NULL)
400 1
                return (ctx->bo->director_resp->vcl_name);
401 0
        return (NULL);
402 1
}
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 1
VRT_r_beresp_backend_ip(VRT_CTX)
412
{
413
414 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
415 1
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
416 1
        return (VDI_GetIP(ctx->bo));
417
}
418
419
/*--------------------------------------------------------------------*/
420
421
VCL_STEVEDORE
422 1
VRT_r_req_storage(VRT_CTX)
423
{
424 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
425 1
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
426 1
        return (ctx->req->storage);
427
}
428
429
VCL_VOID
430 6
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
431
{
432 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
433 6
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
434 6
        ctx->req->storage = stv;
435 6
}
436
437
/*--------------------------------------------------------------------*/
438
439
VCL_STEVEDORE
440 10
VRT_r_beresp_storage(VRT_CTX)
441
{
442 10
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
443 10
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
444 10
        return (ctx->bo->storage);
445
}
446
447
VCL_VOID
448 25
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
449
{
450 25
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
451 25
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
452 25
        ctx->bo->storage = stv;
453 25
}
454
455
/*--------------------------------------------------------------------
456
 * VCL <= 4.0 ONLY
457
 */
458
459
#include "storage/storage.h"
460
461
VCL_STRING
462 7
VRT_r_beresp_storage_hint(VRT_CTX)
463
{
464 7
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
465 7
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
466 7
        if (ctx->bo->storage == NULL)
467 1
                return (NULL);
468 6
        CHECK_OBJ_NOTNULL(ctx->bo->storage, STEVEDORE_MAGIC);
469 6
        return (ctx->bo->storage->vclname);
470 7
}
471
472
VCL_VOID
473 1
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, VCL_STRANDS s)
474
{
475
        const char *p;
476
        VCL_STEVEDORE stv;
477
478 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
479 1
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
480
481 1
        p = VRT_StrandsWS(ctx->ws, str, s);
482
483 1
        if (p == NULL) {
484 0
                VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
485 0
                WS_MarkOverflow(ctx->ws);
486 0
                return;
487
        }
488
489 1
        stv = VRT_stevedore(p);
490 1
        if (stv != NULL)
491 1
                ctx->bo->storage = stv;
492 1
}
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 22
VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore)
563 37
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 16
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
599
600 5
REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
601 6
REQ_VAR_R(ttl, d_ttl, VCL_DURATION)
602 0
REQ_VAR_U(ttl, d_ttl, -1)
603 3
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
604 9
REQ_VAR_R(grace, d_grace, VCL_DURATION)
605 1
REQ_VAR_U(grace, d_grace, -1)
606
607
VCL_VOID
608 145
VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be)
609
{
610
611 145
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
612 145
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
613 145
        VRT_Assign_Backend(&ctx->req->director_hint, be);
614 145
}
615
616
/*--------------------------------------------------------------------*/
617
618
VCL_VOID
619 266
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
620
{
621
622 266
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
623 266
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
624 266
        VRT_Assign_Backend(&ctx->bo->director_req, be);
625 266
}
626
627
VCL_BACKEND
628 46
VRT_r_bereq_backend(VRT_CTX)
629
{
630
631 46
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
632 46
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
633 46
        return (ctx->bo->director_req);
634
}
635
636
VCL_BACKEND
637 39
VRT_r_beresp_backend(VRT_CTX)
638
{
639
640 39
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
641 39
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
642 39
        return (ctx->bo->director_resp);
643
}
644
645
/*--------------------------------------------------------------------*/
646
647
VCL_VOID
648 2184
VRT_u_bereq_body(VRT_CTX)
649
{
650 2184
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
651 2184
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
652
653 2184
        http_Unset(ctx->bo->bereq, H_Content_Length);
654
655 2184
        if (ctx->bo->bereq_body != NULL)
656 5
                (void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body);
657
658 2184
        if (ctx->bo->req != NULL) {
659 8
                CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
660 8
                VBO_SetState(ctx->bo->wrk, ctx->bo, BOS_REQ_DONE);
661 8
                AZ(ctx->bo->req);
662 8
        }
663 2184
}
664
665
/*--------------------------------------------------------------------*/
666
667
VCL_VOID
668 11
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
669
{
670
671 11
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
672 11
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
673 11
        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 11
        if (IS_TOPREQ(ctx->req))
681 7
                ctx->req->disable_esi = !process_esi;
682 11
}
683
684
VCL_BOOL
685 3
VRT_r_req_esi(VRT_CTX)
686
{
687
688 3
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
689 3
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
690 3
        assert(ctx->syntax <= 40);
691 3
        return (!ctx->req->disable_esi);
692
}
693
694
VCL_INT
695 231
VRT_r_req_esi_level(VRT_CTX)
696
{
697
698 231
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
699 231
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
700 231
        return (ctx->req->esi_level);
701
}
702
703
/*--------------------------------------------------------------------*/
704
705
VCL_BOOL
706 8
VRT_r_req_can_gzip(VRT_CTX)
707
{
708
709 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
710 8
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
711 8
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
712
}
713
714
/*--------------------------------------------------------------------*/
715
716
VCL_INT
717 140
VRT_r_req_restarts(VRT_CTX)
718
{
719
720 140
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
721 140
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
722 140
        return (ctx->req->restarts);
723
}
724
725
VCL_INT
726 62
VRT_r_bereq_retries(VRT_CTX)
727
{
728
729 62
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
730 62
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
731 62
        return (ctx->bo->retries);
732
}
733
734
/*--------------------------------------------------------------------*/
735
736
VCL_STRING
737 17
VRT_r_req_transport(VRT_CTX)
738
{
739 17
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
740
741 17
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
742 17
        CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC);
743 17
        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 1536
ttl_now(VRT_CTX)
760
{
761 1536
        if (ctx->bo) {
762 1508
                return (ctx->now);
763
        } else {
764 28
                CHECK_OBJ(ctx->req, REQ_MAGIC);
765 28
                return (ctx->method == VCL_MET_DELIVER
766 28
                    ? ctx->now : ctx->req->t_req);
767
        }
768 1536
}
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 1
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, ttl,
804
    ttl_now(ctx) - ctx->bo->stale_oc->t_origin)
805 20
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
806
    ttl_now(ctx) - ctx->req->objcore->t_origin)
807 1
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, grace, 0)
808 10
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
809 1
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, keep, 0)
810 7
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
811 234
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
812
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
813 1271
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
814
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
815
816 122
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
817 6
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
818 76
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
819 1
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 9
VRT_DO_TIME_R(req, req, t_req)
836 4
VRT_DO_TIME_R(req_top, req->top->topreq, t_req)
837 4
VRT_DO_TIME_R(resp, req, t_resp)
838 6
VRT_DO_TIME_R(bereq, bo, t_first)
839 2
VRT_DO_TIME_R(beresp, bo, t_resp)
840 2
VRT_DO_TIME_R(obj, req->objcore, t_origin)
841 1
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 1
VRT_DO_AGE_R(obj_stale, ctx->bo->stale_oc)
857 8
VRT_DO_AGE_R(obj, ctx->req->objcore)
858 1
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
859
860
/*--------------------------------------------------------------------
861
 * [[be]req|sess].xid
862
 */
863
864
VCL_INT
865 669
VRT_r_req_xid(VRT_CTX)
866
{
867
868 669
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
869 669
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
870 669
        CHECK_OBJ_NOTNULL(ctx->req->http, HTTP_MAGIC);
871 669
        AN(ctx->req->vsl);
872 669
        return (VXID(ctx->req->vsl->wid));
873
}
874
875
VCL_INT
876 554
VRT_r_bereq_xid(VRT_CTX)
877
{
878
879 554
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
880 554
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
881 554
        AN(ctx->bo->vsl);
882
883 554
        return (VXID(ctx->bo->vsl->wid));
884
}
885
886
VCL_INT
887 7
VRT_r_sess_xid(VRT_CTX)
888
{
889
        struct sess *sp;
890
891 7
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
892
893 7
        if (ctx->req) {
894 4
                CHECK_OBJ(ctx->req, REQ_MAGIC);
895 4
                sp = ctx->req->sp;
896 4
        } else {
897 3
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
898 3
                sp = ctx->bo->sp;
899
        }
900
901 7
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
902 7
        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 49
GIP(local)
949 50
GIP(remote)
950 101
GIP(client)
951 214
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 7
LOC(endpoint, endpoint)
979 7
LOC(socket, name)
980
#undef LOC
981
982
/*--------------------------------------------------------------------*/
983
984
VCL_STRING
985 10
VRT_r_server_identity(VRT_CTX)
986
{
987
988 10
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
989 10
        if (heritage.identity != NULL)
990 10
                return (heritage.identity);
991
        else
992 0
                return ("varnishd");
993 10
}
994
995
VCL_STRING
996 3
VRT_r_server_hostname(VRT_CTX)
997
{
998
999 3
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1000 3
        if (vrt_hostname[0] == '\0')
1001 2
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
1002 3
        return (vrt_hostname);
1003
}
1004
1005
/*--------------------------------------------------------------------*/
1006
1007
VCL_INT
1008 52
VRT_r_obj_hits(VRT_CTX)
1009
{
1010 52
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1011 52
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1012 52
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1013 52
        if (ctx->method == VCL_MET_HIT)
1014 2
                return (ctx->req->objcore->hits);
1015 50
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
1016 52
}
1017
1018
/*--------------------------------------------------------------------*/
1019
1020
VCL_INT
1021 1
VRT_r_obj_stale_hits(VRT_CTX)
1022
{
1023 1
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1024 1
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1025 1
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1026
1027 1
        return (ctx->bo->stale_oc->hits);
1028
}
1029
1030
VCL_BOOL
1031 36
VRT_r_obj_stale_is_valid(VRT_CTX)
1032
{
1033 36
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1034 36
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1035 36
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1036
1037 36
        return (!(ctx->bo->stale_oc->flags & OC_F_DYING));
1038
}
1039
1040
/*--------------------------------------------------------------------*/
1041
1042
VCL_BOOL
1043 5
VRT_r_resp_is_streaming(VRT_CTX)
1044
{
1045 5
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1046 5
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1047 5
        if (ctx->req->objcore == NULL)
1048 1
                return (0);     /* When called from vcl_synth */
1049 4
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1050 4
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
1051 5
}
1052
1053
/*--------------------------------------------------------------------*/
1054
1055
static inline int
1056 14
resp_filter_fixed(VRT_CTX, const char *s)
1057
{
1058 14
        if (ctx->req->vdp_filter_list == NULL)
1059 13
                return (0);
1060 1
        VRT_fail(ctx, "resp.filters are already fixed, %s is undefined", s);
1061 1
        return (1);
1062 14
}
1063
1064
VCL_VOID
1065 5
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
1066
{
1067
1068 5
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1069 5
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1070 5
        assert(ctx->syntax >= 41);
1071 5
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1072 1
                return;
1073 4
        ctx->req->disable_esi = !process_esi;
1074 5
}
1075
1076
VCL_BOOL
1077 9
VRT_r_resp_do_esi(VRT_CTX)
1078
{
1079
1080 9
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1081 9
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1082 9
        assert(ctx->syntax >= 41);
1083 9
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1084 0
                return (0);
1085 9
        return (!ctx->req->disable_esi);
1086 9
}
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 4256
VRT_BODY_L(beresp)
1124 6527
VRT_BODY_L(resp)
1125
1126
/*--------------------------------------------------------------------*/
1127
1128
                        /* digest */
1129
#define BLOB_HASH_TYPE 0x00d16357
1130
1131
VCL_BLOB
1132 4
VRT_r_req_hash(VRT_CTX)
1133
{
1134 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1135 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1136 4
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN,
1137
            BLOB_HASH_TYPE));
1138
}
1139
1140
VCL_BLOB
1141 12
VRT_r_bereq_hash(VRT_CTX)
1142
{
1143 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1144 12
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1145 12
        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 15
HTTP_VAR(req)
1161 1
HTTP_VAR(resp)
1162 9
HTTP_VAR(bereq)
1163 0
HTTP_VAR(beresp)
1164
1165
/*--------------------------------------------------------------------*/
1166
1167
static inline void
1168 3
set_idle_send_timeout(const struct sess *sp, VCL_DURATION d)
1169
{
1170 3
        struct timeval tv = VTIM_timeval_sock(d);
1171 3
        VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
1172
            &tv, sizeof tv));
1173 3
}
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 10
SESS_VAR_DUR(timeout_idle, )
1206 11
SESS_VAR_DUR(timeout_linger, )
1207 7
SESS_VAR_DUR(send_timeout, )
1208 8
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 2
PARAM_VAR(timeout_idle, DURATION)
1239 0
PARAM_VAR(transit_buffer, BYTES)
1240 42
PARAM_VAR(uncacheable_ttl, DURATION)