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 2760
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 2760
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
62
63 2760
        b = VRT_StrandsWS(hp->ws, str, s);
64 2760
        if (b == NULL) {
65 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
66 0
                WS_MarkOverflow(hp->ws);
67 0
                return;
68
        }
69 2760
        if (*b == '\0') {
70 120
                VRT_fail(ctx, "Setting %s to empty string", err);
71 120
                return;
72
        }
73 2640
        http_SetH(hp, fld, b);
74 2760
}
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 233888
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
129 195187
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
130 4963
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
131
132 160
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
133 160
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
134 160
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
135
136 160
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
137 56240
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
138 1800
VRT_STATUS_L(resp)
139 38720
VRT_STATUS_R(resp)
140
141 91599
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
142 22520
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
143 120
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
144 80
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
145 36593
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
146 4800
VRT_STATUS_L(beresp)
147 179239
VRT_STATUS_R(beresp)
148
149
/*--------------------------------------------------------------------
150
 * beresp bool-fields
151
 */
152
153
static inline int
154 15040
beresp_filter_fixed(VRT_CTX, const char *s)
155
{
156 15040
        if (ctx->bo->vfp_filter_list == NULL)
157 15000
                return (0);
158 80
        VRT_fail(ctx,
159 40
            "beresp.filters are already fixed, beresp.%s is undefined", s);
160 40
        return (1);
161 15040
}
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 77280
VRT_r_bereq_uncacheable(VRT_CTX)
234
{
235 77280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
236 77280
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
237 77280
        return (ctx->bo->uncacheable);
238
}
239
240
VCL_VOID
241 3560
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
242
{
243
        struct objcore *oc;
244
245 3560
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
246 3560
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
247 3560
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
248
249 3560
        if (ctx->bo->uncacheable && !a) {
250 0
                VSLb(ctx->vsl, SLT_VCL_Error,
251
                    "Ignoring attempt to reset beresp.uncacheable");
252 3560
        } else if (a) {
253 3520
                ctx->bo->uncacheable = 1;
254 3520
        }
255 3560
        oc = ctx->bo->fetch_objcore;
256
257 7120
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
258 3560
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
259 7120
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
260
}
261
262
VCL_BOOL
263 40
VRT_r_beresp_uncacheable(VRT_CTX)
264
{
265 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
266 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
267 40
        return (ctx->bo->uncacheable);
268
}
269
270
VCL_VOID
271 40
VRT_l_req_trace(VRT_CTX, VCL_BOOL a)
272
{
273 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
274 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
275 40
        ctx->req->trace = a;
276 40
        VRT_trace(ctx, a);
277 40
}
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 80
VRT_l_beresp_transit_buffer(VRT_CTX, VCL_BYTES value)
305
{
306
    struct objcore *oc;
307
308 80
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
309 80
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
310
311 80
    oc = ctx->bo->fetch_objcore;
312 80
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
313
314 80
    oc->boc->transit_buffer = value;
315 80
}
316
317
/*--------------------------------------------------------------------*/
318
319
VCL_STRING
320 240
VRT_r_client_identity(VRT_CTX)
321
{
322
        const char *id;
323
324 240
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
325 240
        if (ctx->req != NULL) {
326 160
                CHECK_OBJ(ctx->req, REQ_MAGIC);
327 160
                id = ctx->req->client_identity;
328 160
        } else {
329 80
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
330 80
                id = ctx->bo->client_identity;
331
        }
332 240
        if (id != NULL)
333 160
                return (id);
334 80
        return (SES_Get_String_Attr(ctx->sp, SA_CLIENT_IP));
335 240
}
336
337
VCL_VOID
338 120
VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s)
339
{
340
        const char *b;
341
342 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
343 120
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
344 120
        b = VRT_StrandsWS(ctx->req->http->ws, str, s);
345 120
        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 120
        ctx->req->client_identity = b;
351 120
}
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 280
BEREQ_TIMEOUT(, connect_timeout)
386 360
BEREQ_TIMEOUT(, first_byte_timeout)
387 560
BEREQ_TIMEOUT(, between_bytes_timeout)
388 360
BEREQ_TIMEOUT(pipe_, task_deadline)
389
390
391
/*--------------------------------------------------------------------*/
392
393
VCL_STRING
394 40
VRT_r_beresp_backend_name(VRT_CTX)
395
{
396
397 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
398 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
399 40
        if (ctx->bo->director_resp != NULL)
400 40
                return (ctx->bo->director_resp->vcl_name);
401 0
        return (NULL);
402 40
}
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 40
VRT_r_beresp_backend_ip(VRT_CTX)
412
{
413
414 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
415 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
416 40
        return (VDI_GetIP(ctx->bo));
417
}
418
419
/*--------------------------------------------------------------------*/
420
421
VCL_STEVEDORE
422 40
VRT_r_req_storage(VRT_CTX)
423
{
424 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
425 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
426 40
        return (ctx->req->storage);
427
}
428
429
VCL_VOID
430 240
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
431
{
432 240
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
433 240
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
434 240
        ctx->req->storage = stv;
435 240
}
436
437
/*--------------------------------------------------------------------*/
438
439
VCL_STEVEDORE
440 400
VRT_r_beresp_storage(VRT_CTX)
441
{
442 400
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
443 400
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
444 400
        return (ctx->bo->storage);
445
}
446
447
VCL_VOID
448 1000
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
449
{
450 1000
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
451 1000
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
452 1000
        ctx->bo->storage = stv;
453 1000
}
454
455
/*--------------------------------------------------------------------
456
 * VCL <= 4.0 ONLY
457
 */
458
459
#include "storage/storage.h"
460
461
VCL_STRING
462 280
VRT_r_beresp_storage_hint(VRT_CTX)
463
{
464 280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
465 280
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
466 280
        if (ctx->bo->storage == NULL)
467 40
                return (NULL);
468 240
        CHECK_OBJ_NOTNULL(ctx->bo->storage, STEVEDORE_MAGIC);
469 240
        return (ctx->bo->storage->vclname);
470 280
}
471
472
VCL_VOID
473 40
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, VCL_STRANDS s)
474
{
475
        const char *p;
476
        VCL_STEVEDORE stv;
477
478 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
479 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
480
481 40
        p = VRT_StrandsWS(ctx->ws, str, s);
482
483 40
        if (p == NULL) {
484 0
                VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
485 0
                WS_MarkOverflow(ctx->ws);
486 0
                return;
487
        }
488
489 40
        stv = VRT_stevedore(p);
490 40
        if (stv != NULL)
491 40
                ctx->bo->storage = stv;
492 40
}
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 880
VRT_OC_VAR_R(obj, req, REQ_MAGIC, objcore)
563 1480
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 640
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
599
600 217
REQ_VAR_L(max_age, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
601 240
REQ_VAR_R(max_age, d_ttl, VCL_DURATION)
602 0
REQ_VAR_U(max_age, d_ttl, -1)
603 120
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
604 360
REQ_VAR_R(grace, d_grace, VCL_DURATION)
605 40
REQ_VAR_U(grace, d_grace, -1)
606
607
// deprecated, to be removed
608 0
VCL_VOID VRT_l_req_ttl(VRT_CTX, VCL_DURATION arg) { VRT_l_req_max_age(ctx, arg); }
609 0
VCL_DURATION VRT_r_req_ttl(VRT_CTX) { return (VRT_r_req_max_age(ctx)); }
610 0
VCL_VOID VRT_u_req_ttl(VRT_CTX) { return (VRT_u_req_max_age(ctx)); }
611
612
VCL_VOID
613 5800
VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be)
614
{
615
616 5800
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
617 5800
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
618 5800
        VRT_Assign_Backend(&ctx->req->director_hint, be);
619 5800
}
620
621
/*--------------------------------------------------------------------*/
622
623
VCL_VOID
624 10639
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
625
{
626
627 10639
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
628 10639
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
629 10639
        VRT_Assign_Backend(&ctx->bo->director_req, be);
630 10639
}
631
632
VCL_BACKEND
633 1840
VRT_r_bereq_backend(VRT_CTX)
634
{
635
636 1840
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
637 1840
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
638 1840
        return (ctx->bo->director_req);
639
}
640
641
VCL_BACKEND
642 1560
VRT_r_beresp_backend(VRT_CTX)
643
{
644
645 1560
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
646 1560
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
647 1560
        return (ctx->bo->director_resp);
648
}
649
650
/*--------------------------------------------------------------------*/
651
652
VCL_VOID
653 87360
VRT_u_bereq_body(VRT_CTX)
654
{
655 87360
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
656 87360
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
657
658 87360
        http_Unset(ctx->bo->bereq, H_Content_Length);
659
660 87360
        if (ctx->bo->bereq_body != NULL)
661 200
                (void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body);
662
663 87360
        if (ctx->bo->req != NULL) {
664 312
                CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
665 312
                VBO_SetState(ctx->bo->wrk, ctx->bo, BOS_REQ_DONE);
666 312
                AZ(ctx->bo->req);
667 312
        }
668 87360
}
669
670
/*--------------------------------------------------------------------*/
671
672
VCL_VOID
673 440
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
674
{
675
676 440
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
677 440
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
678 440
        assert(ctx->syntax <= 40);
679
        /*
680
         * Only allow you to turn of esi in the main request
681
         * else everything gets confused
682
         * NOTE: this is not true, but we do not change behavior
683
         * for vcl 4.0. For 4.1, see VRT_l_resp_do_esi()
684
         */
685 440
        if (IS_TOPREQ(ctx->req))
686 280
                ctx->req->disable_esi = !process_esi;
687 440
}
688
689
VCL_BOOL
690 120
VRT_r_req_esi(VRT_CTX)
691
{
692
693 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
694 120
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
695 120
        assert(ctx->syntax <= 40);
696 120
        return (!ctx->req->disable_esi);
697
}
698
699
VCL_INT
700 9243
VRT_r_req_esi_level(VRT_CTX)
701
{
702
703 9243
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
704 9243
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
705 9243
        return (ctx->req->esi_level);
706
}
707
708
/*--------------------------------------------------------------------*/
709
710
VCL_BOOL
711 320
VRT_r_req_can_gzip(VRT_CTX)
712
{
713
714 320
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
715 320
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
716 320
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
717
}
718
719
/*--------------------------------------------------------------------*/
720
721
VCL_INT
722 5617
VRT_r_req_restarts(VRT_CTX)
723
{
724
725 5617
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
726 5617
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
727 5617
        return (ctx->req->restarts);
728
}
729
730
VCL_INT
731 2480
VRT_r_bereq_retries(VRT_CTX)
732
{
733
734 2480
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
735 2480
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
736 2480
        return (ctx->bo->retries);
737
}
738
739
/*--------------------------------------------------------------------*/
740
741
VCL_STRING
742 680
VRT_r_req_transport(VRT_CTX)
743
{
744 680
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
745
746 680
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
747 680
        CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC);
748 680
        return (ctx->req->transport->name);
749
}
750
751
/*--------------------------------------------------------------------
752
 * In exp.*:
753
 *      t_origin is absolute
754
 *      ttl is relative to t_origin
755
 *      grace&keep are relative to ttl
756
 * In VCL:
757
 *      ttl is relative to "ttl_now", which is t_req on the client
758
 *      side, except in vcl_deliver, where it is ctx->now. On the
759
 *      fetch side "ttl_now" is ctx->now (which is bo->t_prev).
760
 *      grace&keep are relative to ttl
761
 */
762
763
static double
764 61440
ttl_now(VRT_CTX)
765
{
766 61440
        if (ctx->bo) {
767 60320
                return (ctx->now);
768
        } else {
769 1120
                CHECK_OBJ(ctx->req, REQ_MAGIC);
770 1120
                return (ctx->method == VCL_MET_DELIVER
771 1120
                    ? ctx->now : ctx->req->t_req);
772
        }
773 61440
}
774
775
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
776
                                                                \
777
VCL_VOID                                                        \
778
VRT_l_##which##_##fld(VRT_CTX, VCL_DURATION a)                  \
779
{                                                               \
780
                                                                \
781
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
782
        a += (offset);                                          \
783
        if (a < 0.0)                                            \
784
                a = 0.0;                                        \
785
        oc->fld = a;                                            \
786
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
787
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
788
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
789
}
790
791
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
792
                                                                \
793
VCL_DURATION                                                    \
794
VRT_r_##which##_##fld(VRT_CTX)                                  \
795
{                                                               \
796
        double d;                                               \
797
                                                                \
798
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
799
        d = oc->fld;                                            \
800
        if (d <= 0.0)                                           \
801
                d = 0.0;                                        \
802
        d -= (offset);                                          \
803
        return (d);                                             \
804
}
805
806
/*lint -save -e835 */   // Zero right hand arg to '-'
807
808 40
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, ttl,
809
    ttl_now(ctx) - ctx->bo->stale_oc->t_origin)
810 800
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
811
    ttl_now(ctx) - ctx->req->objcore->t_origin)
812 40
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, grace, 0)
813 400
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
814 40
VRT_DO_EXP_R(obj_stale, ctx->bo->stale_oc, keep, 0)
815 280
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
816 9360
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
817
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
818 50840
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
819
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
820
821 4880
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
822 240
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
823 3040
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
824 40
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
825
826
/*lint -restore */
827
828
// XXX more assertions?
829
#define VRT_DO_TIME_R(which, where, field)                              \
830
                                                                        \
831
VCL_TIME                                                                \
832
VRT_r_##which##_time(VRT_CTX)                                           \
833
{                                                                       \
834
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
835
        AN((ctx)->where);                                               \
836
                                                                        \
837
        return ((ctx)->where->field);                                   \
838
}
839
840 360
VRT_DO_TIME_R(req, req, t_req)
841 160
VRT_DO_TIME_R(req_top, req->top->topreq, t_req)
842 160
VRT_DO_TIME_R(resp, req, t_resp)
843 240
VRT_DO_TIME_R(bereq, bo, t_first)
844 80
VRT_DO_TIME_R(beresp, bo, t_resp)
845 80
VRT_DO_TIME_R(obj, req->objcore, t_origin)
846 40
VRT_DO_TIME_R(obj_stale, bo->stale_oc, t_origin)
847
848
/*--------------------------------------------------------------------
849
 */
850
851
#define VRT_DO_AGE_R(which, oc)                                 \
852
                                                                \
853
VCL_DURATION                                                    \
854
VRT_r_##which##_##age(VRT_CTX)                                  \
855
{                                                               \
856
                                                                \
857
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
858
        return (ttl_now(ctx) - oc->t_origin);                   \
859
}
860
861 40
VRT_DO_AGE_R(obj_stale, ctx->bo->stale_oc)
862 320
VRT_DO_AGE_R(obj, ctx->req->objcore)
863 40
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
864
865
/*--------------------------------------------------------------------
866
 * [[be]req|sess].xid
867
 */
868
869
VCL_INT
870 26760
VRT_r_req_xid(VRT_CTX)
871
{
872
873 26760
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
874 26760
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
875 26760
        CHECK_OBJ_NOTNULL(ctx->req->http, HTTP_MAGIC);
876 26760
        AN(ctx->req->vsl);
877 26760
        return (VXID(ctx->req->vsl->wid));
878
}
879
880
VCL_INT
881 22160
VRT_r_bereq_xid(VRT_CTX)
882
{
883
884 22160
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
885 22160
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
886 22160
        AN(ctx->bo->vsl);
887
888 22160
        return (VXID(ctx->bo->vsl->wid));
889
}
890
891
VCL_INT
892 280
VRT_r_sess_xid(VRT_CTX)
893
{
894
        struct sess *sp;
895
896 280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
897
898 280
        if (ctx->req) {
899 160
                CHECK_OBJ(ctx->req, REQ_MAGIC);
900 160
                sp = ctx->req->sp;
901 160
        } else {
902 120
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
903 120
                sp = ctx->bo->sp;
904
        }
905
906 280
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
907 280
        return (VXID(sp->vxid));
908
}
909
910
/*--------------------------------------------------------------------
911
 * req fields
912
 */
913
914
#define VREQW0(field)
915
#define VREQW1(field)                                                   \
916
VCL_VOID                                                                \
917
VRT_l_req_##field(VRT_CTX, VCL_BOOL a)                                  \
918
{                                                                       \
919
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
920
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
921
        ctx->req->field = a ? 1 : 0;                                    \
922
}
923
924
#define VREQR0(field)
925
#define VREQR1(field)                                                   \
926
VCL_BOOL                                                                \
927
VRT_r_req_##field(VRT_CTX)                                              \
928
{                                                                       \
929
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
930
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
931
        return (ctx->req->field);                                       \
932
}
933
934
#define REQ_FLAG(l, r, w, d) \
935
        VREQR##r(l) \
936
        VREQW##w(l)
937
#include "tbl/req_flags.h"
938
939
/*--------------------------------------------------------------------*/
940
941
#define GIP(fld)                                                \
942
        VCL_IP                                                  \
943
        VRT_r_##fld##_ip(VRT_CTX)                               \
944
        {                                                       \
945
                struct suckaddr *sa;                            \
946
                                                                \
947
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
948
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
949
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
950
                return (sa);                                    \
951
        }
952
953 1963
GIP(local)
954 2006
GIP(remote)
955 4041
GIP(client)
956 8554
GIP(server)
957
#undef GIP
958
959
/*--------------------------------------------------------------------
960
 * local.[endpoint|socket]
961
 */
962
963
#define LOC(var,fld)                                            \
964
VCL_STRING                                                      \
965
VRT_r_local_##var(VRT_CTX)                                      \
966
{                                                               \
967
        struct sess *sp;                                        \
968
                                                                \
969
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
970
        if (ctx->req) {                                         \
971
                CHECK_OBJ(ctx->req, REQ_MAGIC);                 \
972
                sp = ctx->req->sp;                              \
973
        } else {                                                \
974
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);      \
975
                sp = ctx->bo->sp;                               \
976
        }                                                       \
977
                                                                \
978
        CHECK_OBJ_NOTNULL(sp->listen_sock, LISTEN_SOCK_MAGIC);  \
979
        AN(sp->listen_sock->fld);                               \
980
        return (sp->listen_sock->fld);                          \
981
}
982
983 280
LOC(endpoint, endpoint)
984 280
LOC(socket, name)
985
#undef LOC
986
987
/*--------------------------------------------------------------------*/
988
989
VCL_STRING
990 400
VRT_r_server_identity(VRT_CTX)
991
{
992
993 400
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
994 400
        if (heritage.identity != NULL)
995 400
                return (heritage.identity);
996
        else
997 0
                return ("varnishd");
998 400
}
999
1000
VCL_STRING
1001 120
VRT_r_server_hostname(VRT_CTX)
1002
{
1003
1004 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1005 120
        if (vrt_hostname[0] == '\0')
1006 80
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
1007 120
        return (vrt_hostname);
1008
}
1009
1010
/*--------------------------------------------------------------------*/
1011
1012
VCL_INT
1013 2080
VRT_r_obj_hits(VRT_CTX)
1014
{
1015 2080
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1016 2080
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1017 2080
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1018 2080
        if (ctx->method == VCL_MET_HIT)
1019 80
                return (ctx->req->objcore->hits);
1020 2000
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
1021 2080
}
1022
1023
/*--------------------------------------------------------------------*/
1024
1025
VCL_INT
1026 40
VRT_r_obj_stale_hits(VRT_CTX)
1027
{
1028 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1029 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1030 40
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1031
1032 40
        return (ctx->bo->stale_oc->hits);
1033
}
1034
1035
VCL_BOOL
1036 1440
VRT_r_obj_stale_is_valid(VRT_CTX)
1037
{
1038 1440
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1039 1440
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1040 1440
        CHECK_OBJ_NOTNULL(ctx->bo->stale_oc, OBJCORE_MAGIC);
1041
1042 1440
        return (!(ctx->bo->stale_oc->flags & OC_F_DYING));
1043
}
1044
1045
/*--------------------------------------------------------------------*/
1046
1047
VCL_BOOL
1048 200
VRT_r_resp_is_streaming(VRT_CTX)
1049
{
1050 200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1051 200
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1052 200
        if (ctx->req->objcore == NULL)
1053 40
                return (0);     /* When called from vcl_synth */
1054 160
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1055 160
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
1056 200
}
1057
1058
/*--------------------------------------------------------------------*/
1059
1060
static inline int
1061 560
resp_filter_fixed(VRT_CTX, const char *s)
1062
{
1063 560
        if (ctx->req->vdp_filter_list == NULL)
1064 520
                return (0);
1065 40
        VRT_fail(ctx, "resp.filters are already fixed, %s is undefined", s);
1066 40
        return (1);
1067 560
}
1068
1069
VCL_VOID
1070 200
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
1071
{
1072
1073 200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1074 200
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1075 200
        assert(ctx->syntax >= 41);
1076 200
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1077 40
                return;
1078 160
        ctx->req->disable_esi = !process_esi;
1079 200
}
1080
1081
VCL_BOOL
1082 360
VRT_r_resp_do_esi(VRT_CTX)
1083
{
1084
1085 360
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1086 360
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1087 360
        assert(ctx->syntax >= 41);
1088 360
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1089 0
                return (0);
1090 360
        return (!ctx->req->disable_esi);
1091 360
}
1092
1093
/*--------------------------------------------------------------------*/
1094
1095
#define VRT_BODY_L(which)                                       \
1096
VCL_VOID                                                        \
1097
VRT_l_##which##_body(VRT_CTX, enum lbody_e type,                \
1098
    const char *str, VCL_BODY body)                             \
1099
{                                                               \
1100
        int n;                                                  \
1101
        struct vsb *vsb;                                        \
1102
        VCL_STRANDS s;                                          \
1103
        VCL_BLOB b;                                             \
1104
                                                                \
1105
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1106
        AN(body);                                               \
1107
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
1108
        if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB) \
1109
                VSB_clear(vsb);                                 \
1110
        if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) { \
1111
                AZ(str);                                        \
1112
                b = body;                                       \
1113
                CHECK_OBJ_NOTNULL(b, VRT_BLOB_MAGIC);           \
1114
                VSB_bcat(vsb, b->blob, b->len);                 \
1115
                return;                                         \
1116
        }                                                       \
1117
        if (str != NULL)                                        \
1118
                VSB_cat(vsb, str);                              \
1119
        assert(type == LBODY_SET_STRING ||                      \
1120
            type == LBODY_ADD_STRING);                          \
1121
        s = body;                                               \
1122
        CHECK_OBJ_NOTNULL(s, STRANDS_MAGIC);                    \
1123
        for (n = 0; s != NULL && n < s->n; n++)                 \
1124
                if (s->p[n] != NULL)                            \
1125
                        VSB_cat(vsb, s->p[n]);                  \
1126
}
1127
1128 170222
VRT_BODY_L(beresp)
1129 261078
VRT_BODY_L(resp)
1130
1131
/*--------------------------------------------------------------------*/
1132
1133
                        /* digest */
1134
#define BLOB_HASH_TYPE 0x00d16357
1135
1136
VCL_BLOB
1137 160
VRT_r_req_hash(VRT_CTX)
1138
{
1139 160
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1140 160
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1141 160
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN,
1142
            BLOB_HASH_TYPE));
1143
}
1144
1145
VCL_BLOB
1146 480
VRT_r_bereq_hash(VRT_CTX)
1147
{
1148 480
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1149 480
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1150 480
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN,
1151
            BLOB_HASH_TYPE));
1152
}
1153
1154
/*--------------------------------------------------------------------*/
1155
1156
#define HTTP_VAR(x)                                             \
1157
VCL_HTTP                                                        \
1158
VRT_r_##x(VRT_CTX)                                              \
1159
{                                                               \
1160
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1161
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
1162
        return (ctx->http_##x);                                 \
1163
}
1164
1165 600
HTTP_VAR(req)
1166 40
HTTP_VAR(resp)
1167 360
HTTP_VAR(bereq)
1168 0
HTTP_VAR(beresp)
1169
1170
/*--------------------------------------------------------------------*/
1171
1172
static inline void
1173 120
set_idle_send_timeout(const struct sess *sp, VCL_DURATION d)
1174
{
1175 120
        struct timeval tv = VTIM_timeval_sock(d);
1176 120
        VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
1177
            &tv, sizeof tv));
1178 120
}
1179
1180
#define SESS_VAR_DUR(x, setter)                         \
1181
VCL_VOID                                                \
1182
VRT_l_sess_##x(VRT_CTX, VCL_DURATION d)                 \
1183
{                                                       \
1184
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1185
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1186
        d = vmax(d, 0.0);                               \
1187
        setter;                                         \
1188
        ctx->sp->x = d;                                 \
1189
}                                                       \
1190
                                                        \
1191
VCL_DURATION                                            \
1192
VRT_r_sess_##x(VRT_CTX)                                 \
1193
{                                                       \
1194
        vtim_dur res;                                   \
1195
                                                        \
1196
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1197
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1198
        res = SESS_TMO(ctx->sp, x);                     \
1199
        return (VRT_TMO(res));                          \
1200
}                                                       \
1201
                                                        \
1202
VCL_VOID                                                \
1203
VRT_u_sess_##x(VRT_CTX)                                 \
1204
{                                                       \
1205
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1206
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1207
        ctx->sp->x = NAN;                               \
1208
}
1209
1210 400
SESS_VAR_DUR(timeout_idle, )
1211 440
SESS_VAR_DUR(timeout_linger, )
1212 280
SESS_VAR_DUR(send_timeout, )
1213 320
SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d))
1214
1215
/*--------------------------------------------------------------------*/
1216
1217
#define PARAM_VAR(x, type)                              \
1218
VCL_##type                                              \
1219
VRT_r_param_##x(VRT_CTX)                                \
1220
{                                                       \
1221
                                                        \
1222
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1223
        return (cache_param->x);                        \
1224
}                                                       \
1225
1226 0
PARAM_VAR(backend_idle_timeout, DURATION)
1227 0
PARAM_VAR(backend_wait_limit, INT)
1228 0
PARAM_VAR(backend_wait_timeout, DURATION)
1229 0
PARAM_VAR(between_bytes_timeout, DURATION)
1230 0
PARAM_VAR(connect_timeout, DURATION)
1231 0
PARAM_VAR(default_grace, DURATION)
1232 0
PARAM_VAR(default_keep, DURATION)
1233 0
PARAM_VAR(default_ttl, DURATION)
1234 0
PARAM_VAR(first_byte_timeout, DURATION)
1235 0
PARAM_VAR(idle_send_timeout, DURATION)
1236 0
PARAM_VAR(max_esi_depth, INT)
1237 0
PARAM_VAR(max_restarts, INT)
1238 0
PARAM_VAR(max_retries, INT)
1239 0
PARAM_VAR(pipe_task_deadline, DURATION)
1240 0
PARAM_VAR(pipe_timeout, DURATION)
1241 0
PARAM_VAR(send_timeout, DURATION)
1242 0
PARAM_VAR(shortlived, DURATION)
1243 80
PARAM_VAR(timeout_idle, DURATION)
1244 0
PARAM_VAR(transit_buffer, BYTES)
1245 1680
PARAM_VAR(uncacheable_ttl, DURATION)