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