varnish-cache/bin/varnishd/cache/cache_vrt_var.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 * Runtime support for compiled VCL programs
30
 */
31
#include "config.h"
32
33
#include <stdio.h>
34
35
#include "cache_varnishd.h"
36
#include "common/heritage.h"
37
38
#include "vcl.h"
39
40
#include "vrt_obj.h"
41
42
static char vrt_hostname[255] = "";
43
44
/*--------------------------------------------------------------------
45
 * VRT variables relating to first line of HTTP/1.1 req/resp
46
 */
47
48
static void
49 184
vrt_do_string(VRT_CTX, struct http *hp, int fld,
50
    const char *err, const char *p, va_list ap)
51
{
52
        const char *b;
53
54 184
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
55
56 184
        b = VRT_String(hp->ws, NULL, p, ap);
57 184
        if (b == NULL) {
58 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
59 0
                WS_MarkOverflow(hp->ws);
60 0
                return;
61
        }
62 184
        if (*b == '\0') {
63 12
                VRT_fail(ctx, "Setting %s to empty string", err);
64 12
                return;
65
        }
66 172
        http_SetH(hp, fld, b);
67
}
68
69
#define VRT_HDR_L(obj, hdr, fld)                                        \
70
VCL_VOID                                                                \
71
VRT_l_##obj##_##hdr(VRT_CTX, const char *p, ...)                        \
72
{                                                                       \
73
        va_list ap;                                                     \
74
                                                                        \
75
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
76
        va_start(ap, p);                                                \
77
        vrt_do_string(ctx, ctx->http_##obj, fld, #obj "." #hdr, p, ap); \
78
        va_end(ap);                                                     \
79
}
80
81
#define VRT_HDR_R(obj, hdr, fld)                                        \
82
VCL_STRING                                                              \
83
VRT_r_##obj##_##hdr(VRT_CTX)                                            \
84
{                                                                       \
85
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
86
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
87
        return (ctx->http_##obj->hd[fld].b);                            \
88
}
89
90
#define VRT_HDR_LR(obj, hdr, fld)                                       \
91
        VRT_HDR_L(obj, hdr, fld)                                        \
92
        VRT_HDR_R(obj, hdr, fld)
93
94
#define VRT_STATUS_L(obj)                                               \
95
VCL_VOID                                                                \
96
VRT_l_##obj##_status(VRT_CTX, VCL_INT num)                              \
97
{                                                                       \
98
                                                                        \
99
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
100
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
101
        if (num < 0)                                                    \
102
                VRT_fail(ctx, "%s.status (%jd) is negative",            \
103
                    #obj, (intmax_t)num);                               \
104
        else if (num > 65535)                                           \
105
                VRT_fail(ctx, "%s.status (%jd) > 65535",                \
106
                    #obj, (intmax_t)num);                               \
107
        else if ((num % 1000) < 100)                                    \
108
                VRT_fail(ctx, "illegal %s.status (%jd) (..0##)",        \
109
                    #obj, (intmax_t)num);                               \
110
        else                                                            \
111
                http_SetStatus(ctx->http_##obj, (uint16_t)num);         \
112
}
113
114
#define VRT_STATUS_R(obj)                                               \
115
VCL_INT                                                                 \
116
VRT_r_##obj##_status(VRT_CTX)                                           \
117
{                                                                       \
118
                                                                        \
119
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
120
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
121
        return (ctx->http_##obj->status);                               \
122
}
123
124 21580
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
125 12984
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
126 264
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
127
128 16
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
129 16
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
130 16
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
131
132 8
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
133 2900
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
134 60
VRT_STATUS_L(resp)
135 2016
VRT_STATUS_R(resp)
136
137 6652
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
138 1776
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
139 12
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
140 8
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
141 1636
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
142 64
VRT_STATUS_L(beresp)
143 1212
VRT_STATUS_R(beresp)
144
145
/*--------------------------------------------------------------------
146
 * Pulling things out of the packed object->http
147
 */
148
149
VCL_INT
150 4
VRT_r_obj_status(VRT_CTX)
151
{
152 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
153 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
154 4
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
155
156 4
        return (HTTP_GetStatusPack(ctx->req->wrk, ctx->req->objcore));
157
}
158
159
VCL_STRING
160 4
VRT_r_obj_proto(VRT_CTX)
161
{
162 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
163 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
164 4
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
165
166 4
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
167
            H__Proto));
168
}
169
170
VCL_STRING
171 4
VRT_r_obj_reason(VRT_CTX)
172
{
173 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
174 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
175 4
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
176
177 4
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
178
            H__Reason));
179
}
180
181
/*--------------------------------------------------------------------
182
 * bool-fields (.do_*)
183
 */
184
185
#define VBERESPW0(field)
186
#define VBERESPW1(field)                                                \
187
void                                                                    \
188
VRT_l_beresp_##field(VRT_CTX, VCL_BOOL a)                               \
189
{                                                                       \
190
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
191
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
192
        ctx->bo->field = a ? 1 : 0;                                     \
193
}
194
195
#define VBERESPR0(field)
196
#define VBERESPR1(field)                                                \
197
VCL_BOOL                                                                \
198
VRT_r_beresp_##field(VRT_CTX)                                           \
199
{                                                                       \
200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
201
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
202
        return (ctx->bo->field);                                        \
203
}
204
205
#define BO_FLAG(l, r, w, d) \
206
        VBERESPR##r(l) \
207
        VBERESPW##w(l)
208
#include "tbl/bo_flags.h"
209
210
/*--------------------------------------------------------------------*/
211
212
VCL_BOOL
213 28
VRT_r_bereq_is_bgfetch(VRT_CTX)
214
{
215 28
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
216 28
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
217 28
        return (ctx->bo->is_bgfetch);
218
}
219
220
VCL_BOOL
221 5936
VRT_r_bereq_uncacheable(VRT_CTX)
222
{
223 5936
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
224 5936
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
225 5936
        return (ctx->bo->do_pass);
226
}
227
228
VCL_VOID
229 212
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
230
{
231
        struct objcore *oc;
232
233 212
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
234 212
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
235 212
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
236
237 212
        if (ctx->bo->uncacheable && !a) {
238 0
                VSLb(ctx->vsl, SLT_VCL_Error,
239
                    "Ignoring attempt to reset beresp.uncacheable");
240 212
        } else if (a) {
241 208
                ctx->bo->uncacheable = 1;
242
        }
243 212
        oc = ctx->bo->fetch_objcore;
244
245 848
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
246 636
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
247 212
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
248
}
249
250
VCL_BOOL
251 4
VRT_r_beresp_uncacheable(VRT_CTX)
252
{
253 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
254 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
255 4
        return (ctx->bo->uncacheable);
256
}
257
258
/*--------------------------------------------------------------------*/
259
260
VCL_STRING
261 16
VRT_r_client_identity(VRT_CTX)
262
{
263 16
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
264 16
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
265 16
        if (ctx->req->client_identity != NULL)
266 12
                return (ctx->req->client_identity);
267 4
        return (SES_Get_String_Attr(ctx->req->sp, SA_CLIENT_IP));
268
}
269
270
VCL_VOID
271 12
VRT_l_client_identity(VRT_CTX, const char *str, ...)
272
{
273
        va_list ap;
274
        const char *b;
275
276 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
277 12
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
278 12
        va_start(ap, str);
279 12
        b = VRT_String(ctx->req->http->ws, NULL, str, ap);
280 12
        va_end(ap);
281 12
        if (b == NULL) {
282 0
                VSLb(ctx->vsl, SLT_LostHeader, "client.identity");
283 0
                WS_MarkOverflow(ctx->req->http->ws);
284 0
                return;
285
        }
286 12
        ctx->req->client_identity = b;
287
}
288
289
/*--------------------------------------------------------------------*/
290
291
#define BEREQ_TIMEOUT(which)                                    \
292
VCL_VOID                                                        \
293
VRT_l_bereq_##which(VRT_CTX, VCL_DURATION num)                  \
294
{                                                               \
295
                                                                \
296
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
297
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
298
        ctx->bo->which = (num > 0.0 ? num : 0.0);               \
299
}                                                               \
300
                                                                \
301
VCL_DURATION                                                    \
302
VRT_r_bereq_##which(VRT_CTX)                                    \
303
{                                                               \
304
                                                                \
305
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
306
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
307
        return (ctx->bo->which);                                \
308
}
309
310 8
BEREQ_TIMEOUT(connect_timeout)
311 16
BEREQ_TIMEOUT(first_byte_timeout)
312 32
BEREQ_TIMEOUT(between_bytes_timeout)
313
314
/*--------------------------------------------------------------------*/
315
316
VCL_STRING
317 4
VRT_r_beresp_backend_name(VRT_CTX)
318
{
319
320 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
321 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
322 4
        if (ctx->bo->director_resp != NULL)
323 4
                return (ctx->bo->director_resp->vcl_name);
324 0
        return (NULL);
325
}
326
327
/*--------------------------------------------------------------------
328
 * Backends do not in general have a IP number (any more) and this
329
 * variable is really not about the backend, but the backend connection.
330
 * XXX: we may need a more general beresp.backend.{details|ident}
331
 */
332
333
VCL_IP
334 4
VRT_r_beresp_backend_ip(VRT_CTX)
335
{
336
337 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
338 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
339 4
        return (VDI_GetIP(ctx->bo));
340
}
341
342
/*--------------------------------------------------------------------*/
343
344
VCL_STEVEDORE
345 4
VRT_r_req_storage(VRT_CTX)
346
{
347 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
348 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
349 4
        return (ctx->req->storage);
350
}
351
352
VCL_VOID
353 8
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
354
{
355 8
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
356 8
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
357 8
        ctx->req->storage = stv;
358 8
}
359
360
/*--------------------------------------------------------------------*/
361
362
VCL_STEVEDORE
363 40
VRT_r_beresp_storage(VRT_CTX)
364
{
365 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
366 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
367 40
        return (ctx->bo->storage);
368
}
369
370
VCL_VOID
371 76
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
372
{
373 76
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
374 76
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
375 76
        ctx->bo->storage = stv;
376 76
}
377
378
/*--------------------------------------------------------------------
379
 * VCL <= 4.0 ONLY
380
 */
381
382
#include "storage/storage.h"
383
384
VCL_STRING
385 28
VRT_r_beresp_storage_hint(VRT_CTX)
386
{
387 28
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
388 28
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
389 28
        if (ctx->bo->storage == NULL)
390 4
                return (NULL);
391 24
        CHECK_OBJ_NOTNULL(ctx->bo->storage, STEVEDORE_MAGIC);
392 24
        return (ctx->bo->storage->vclname);
393
}
394
395
VCL_VOID
396 4
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, ...)
397
{
398
        const char *p;
399
        va_list ap;
400
        uintptr_t sn;
401
        VCL_STEVEDORE stv;
402
403 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
404 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
405
406 4
        sn = WS_Snapshot(ctx->ws);
407 4
        va_start(ap, str);
408 4
        p = VRT_String(ctx->ws, NULL, str, ap);
409 4
        va_end(ap);
410
411 4
        if (p == NULL) {
412 0
                VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
413 0
                WS_Reset(ctx->ws, sn);
414 0
                WS_MarkOverflow(ctx->ws);
415 0
                return;
416
        }
417
418 4
        stv = VRT_stevedore(p);
419 4
        if (stv != NULL)
420 4
                ctx->bo->storage = stv;
421
422 4
        WS_Reset(ctx->ws, sn);
423
}
424
425
/*--------------------------------------------------------------------*/
426
427
VCL_STEVEDORE
428 16
VRT_r_obj_storage(VRT_CTX)
429
{
430 16
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
431 16
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
432 16
        return (ctx->req->objcore->stobj->stevedore);
433
}
434
435
/*--------------------------------------------------------------------*/
436
437
#define REQ_VAR_L(nm, elem, type, extra)                                \
438
                                                                        \
439
VCL_VOID                                                                \
440
VRT_l_req_##nm(VRT_CTX, type arg)                                       \
441
{                                                                       \
442
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
443
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
444
        extra;                                                          \
445
        ctx->req->elem = arg;                                           \
446
}
447
448
#define REQ_VAR_R(nm, elem, type)                                       \
449
                                                                        \
450
type                                                                    \
451
VRT_r_req_##nm(VRT_CTX)                                                 \
452
{                                                                       \
453
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
454
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
455
        return (ctx->req->elem);                                        \
456
}
457
458 440
REQ_VAR_L(backend_hint, director_hint, VCL_BACKEND,)
459 36
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
460 20
REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
461 24
REQ_VAR_R(ttl, d_ttl, VCL_DURATION)
462 8
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
463 12
REQ_VAR_R(grace, d_grace, VCL_DURATION)
464
465
/*--------------------------------------------------------------------*/
466
467
VCL_VOID
468 885
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
469
{
470
471 885
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
472 885
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
473 885
        ctx->bo->director_req = be;
474 885
}
475
476
VCL_BACKEND
477 140
VRT_r_bereq_backend(VRT_CTX)
478
{
479
480 140
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
481 140
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
482 140
        return (ctx->bo->director_req);
483
}
484
485
VCL_BACKEND
486 116
VRT_r_beresp_backend(VRT_CTX)
487
{
488
489 116
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
490 116
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
491 116
        return (ctx->bo->director_resp);
492
}
493
494
/*--------------------------------------------------------------------*/
495
496
VCL_VOID
497 6467
VRT_u_bereq_body(VRT_CTX)
498
{
499 6467
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
500 6467
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
501 6467
        if (ctx->bo->req != NULL) {
502 16
                CHECK_OBJ_NOTNULL(ctx->bo->req, REQ_MAGIC);
503 16
                ctx->bo->req = NULL;
504 16
                ObjSetState(ctx->bo->wrk,
505 16
                    ctx->bo->fetch_objcore, BOS_REQ_DONE);
506 16
                http_Unset(ctx->bo->bereq, H_Content_Length);
507
        }
508 6467
}
509
510
/*--------------------------------------------------------------------*/
511
512
VCL_VOID
513 44
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
514
{
515
516 44
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
517 44
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
518 44
        assert(ctx->syntax <= 40);
519
        /*
520
         * Only allow you to turn of esi in the main request
521
         * else everything gets confused
522
         */
523 44
        if (ctx->req->esi_level == 0)
524 28
                ctx->req->disable_esi = !process_esi;
525 44
}
526
527
VCL_BOOL
528 12
VRT_r_req_esi(VRT_CTX)
529
{
530
531 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
532 12
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
533 12
        assert(ctx->syntax <= 40);
534 12
        return (!ctx->req->disable_esi);
535
}
536
537
VCL_INT
538 344
VRT_r_req_esi_level(VRT_CTX)
539
{
540
541 344
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
542 344
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
543 344
        return (ctx->req->esi_level);
544
}
545
546
/*--------------------------------------------------------------------*/
547
548
VCL_BOOL
549 32
VRT_r_req_can_gzip(VRT_CTX)
550
{
551
552 32
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
553 32
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
554 32
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
555
}
556
557
/*--------------------------------------------------------------------*/
558
559
VCL_INT
560 276
VRT_r_req_restarts(VRT_CTX)
561
{
562
563 276
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
564 276
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
565 276
        return (ctx->req->restarts);
566
}
567
568
VCL_INT
569 152
VRT_r_bereq_retries(VRT_CTX)
570
{
571
572 152
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
573 152
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
574 152
        return (ctx->bo->retries);
575
}
576
577
/*--------------------------------------------------------------------
578
 * In exp.*:
579
 *      t_origin is absolute
580
 *      ttl is relative to t_origin
581
 *      grace&keep are relative to ttl
582
 * In VCL:
583
 *      ttl is relative to "ttl_now", which is t_req on the client
584
 *      side, except in vcl_deliver, where it is ctx->now. On the
585
 *      fetch side "ttl_now" is ctx->now (which is bo->t_prev).
586
 *      grace&keep are relative to ttl
587
 */
588
589
static double
590 7312
ttl_now(VRT_CTX)
591
{
592 7312
        if (ctx->bo) {
593 4640
                return (ctx->now);
594
        } else {
595 2672
                CHECK_OBJ(ctx->req, REQ_MAGIC);
596 2672
                return (ctx->method == VCL_MET_DELIVER
597 2672
                    ? ctx->now : ctx->req->t_req);
598
        }
599
}
600
601
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
602
                                                                \
603
VCL_VOID                                                        \
604
VRT_l_##which##_##fld(VRT_CTX, VCL_DURATION a)                  \
605
{                                                               \
606
                                                                \
607
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
608
        a += (offset);                                          \
609
        if (a < 0.0)                                            \
610
                a = 0.0;                                        \
611
        oc->fld = a;                                            \
612
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
613
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
614
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
615
}
616
617
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
618
                                                                \
619
VCL_DURATION                                                    \
620
VRT_r_##which##_##fld(VRT_CTX)                                  \
621
{                                                               \
622
        double d;                                               \
623
                                                                \
624
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
625
        d = oc->fld;                                            \
626
        if (d <= 0.0)                                           \
627
                d = 0.0;                                        \
628
        d -= (offset);                                          \
629
        return (d);                                             \
630
}
631
632
/*lint -save -e835 */   // Zero right hand arg to '-'
633
634 2640
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
635
    ttl_now(ctx) - ctx->req->objcore->t_origin)
636 112
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
637 28
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
638 512
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
639
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
640 4124
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
641
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
642
643 268
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
644 20
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
645 192
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
646 4
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
647
648
/*lint -restore */
649
650
/*--------------------------------------------------------------------
651
 */
652
653
#define VRT_DO_AGE_R(which, oc)                                 \
654
                                                                \
655
VCL_DURATION                                                    \
656
VRT_r_##which##_##age(VRT_CTX)                                  \
657
{                                                               \
658
                                                                \
659
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
660
        return (ttl_now(ctx) - oc->t_origin);                   \
661
}
662
663 32
VRT_DO_AGE_R(obj, ctx->req->objcore)
664 4
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
665
666
/*--------------------------------------------------------------------
667
 * [[be]req|sess].xid
668
 */
669
670
VCL_STRING
671 1348
VRT_r_req_xid(VRT_CTX)
672
{
673
674 1348
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
675 1348
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
676
677 1348
        return (WS_Printf(ctx->req->http->ws, "%u",
678 1348
            VXID(ctx->req->vsl->wid)));
679
}
680
681
VCL_STRING
682 960
VRT_r_bereq_xid(VRT_CTX)
683
{
684
685 960
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
686 960
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
687
688 960
        return (WS_Printf(ctx->bo->bereq->ws, "%u",
689 960
            VXID(ctx->bo->vsl->wid)));
690
}
691
692
VCL_STRING
693 24
VRT_r_sess_xid(VRT_CTX)
694
{
695 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
696
697 24
        if (VALID_OBJ(ctx->req, REQ_MAGIC))
698 12
                return (WS_Printf(ctx->req->http->ws, "%u",
699 12
                    VXID(ctx->req->sp->vxid)));
700
701 12
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
702 12
        return (WS_Printf(ctx->bo->bereq->ws, "%u",
703 12
            VXID(ctx->bo->sp->vxid)));
704
}
705
706
/*--------------------------------------------------------------------
707
 * req fields
708
 */
709
710
#define VREQW0(field)
711
#define VREQW1(field)                                                   \
712
VCL_VOID                                                                \
713
VRT_l_req_##field(VRT_CTX, VCL_BOOL a)                                  \
714
{                                                                       \
715
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
716
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
717
        ctx->req->field = a ? 1 : 0;                                    \
718
}
719
720
#define VREQR0(field)
721
#define VREQR1(field)                                                   \
722
VCL_BOOL                                                                \
723
VRT_r_req_##field(VRT_CTX)                                              \
724
{                                                                       \
725
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
726
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
727
        return (ctx->req->field);                                       \
728
}
729
730
#define REQ_FLAG(l, r, w, d) \
731
        VREQR##r(l) \
732
        VREQW##w(l)
733
#include "tbl/req_flags.h"
734
735
/*--------------------------------------------------------------------*/
736
737
#define GIP(fld)                                                \
738
        VCL_IP                                                  \
739
        VRT_r_##fld##_ip(VRT_CTX)                               \
740
        {                                                       \
741
                struct suckaddr *sa;                            \
742
                                                                \
743
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
744
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
745
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
746
                return (sa);                                    \
747
        }
748
749 148
GIP(local)
750 148
GIP(remote)
751 276
GIP(client)
752 480
GIP(server)
753
#undef GIP
754
755
/*--------------------------------------------------------------------
756
 * local.[endpoint|socket]
757
 */
758
759
#define LOC(var,fld)                                            \
760
VCL_STRING                                                      \
761
VRT_r_local_##var(VRT_CTX)                                      \
762
{                                                               \
763
        struct sess *sp;                                        \
764
                                                                \
765
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
766
        if (VALID_OBJ(ctx->req, REQ_MAGIC))                     \
767
                sp = ctx->req->sp;                              \
768
        else {                                                  \
769
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);      \
770
                sp = ctx->bo->sp;                               \
771
        }                                                       \
772
                                                                \
773
        CHECK_OBJ_NOTNULL(sp->listen_sock, LISTEN_SOCK_MAGIC);  \
774
        AN(sp->listen_sock->fld);                               \
775
        return (sp->listen_sock->fld);                          \
776
}
777
778 28
LOC(endpoint, endpoint)
779 28
LOC(socket, name)
780
#undef LOC
781
782
/*--------------------------------------------------------------------*/
783
784
VCL_STRING
785 40
VRT_r_server_identity(VRT_CTX)
786
{
787
788 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
789 40
        if (heritage.identity != NULL)
790 40
                return (heritage.identity);
791
        else
792 0
                return ("varnishd");
793
}
794
795
VCL_STRING
796 12
VRT_r_server_hostname(VRT_CTX)
797
{
798
799 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
800 12
        if (vrt_hostname[0] == '\0')
801 8
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
802 12
        return (vrt_hostname);
803
}
804
805
/*--------------------------------------------------------------------*/
806
807
VCL_INT
808 104
VRT_r_obj_hits(VRT_CTX)
809
{
810 104
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
811 104
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
812 104
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
813 104
        if (ctx->method == VCL_MET_HIT)
814 8
                return (ctx->req->objcore->hits);
815 96
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
816
}
817
818
VCL_BOOL
819 24
VRT_r_obj_uncacheable(VRT_CTX)
820
{
821
822 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
823 24
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
824 24
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
825 24
        return (ctx->req->objcore->flags & OC_F_PASS ? 1 : 0);
826
}
827
828
/*--------------------------------------------------------------------*/
829
830
VCL_BOOL
831 24
VRT_r_resp_is_streaming(VRT_CTX)
832
{
833 24
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
834 24
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
835 24
        if (ctx->req->objcore == NULL)
836 8
                return (0);     /* When called from vcl_synth */
837 16
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
838 16
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
839
}
840
841
/*--------------------------------------------------------------------*/
842
843
VCL_VOID
844 4
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
845
{
846
847 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
848 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
849 4
        assert(ctx->syntax >= 41);
850
        /*
851
         * Only allow you to turn of esi in the main request
852
         * else everything gets confused
853
         */
854 4
        ctx->req->disable_esi = !process_esi;
855 4
}
856
857
VCL_BOOL
858 12
VRT_r_resp_do_esi(VRT_CTX)
859
{
860
861 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
862 12
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
863 12
        assert(ctx->syntax >= 41);
864 12
        return (!ctx->req->disable_esi);
865
}
866
867
/*--------------------------------------------------------------------*/
868
869
#define VRT_BODY_L(which)                                       \
870
VCL_VOID                                                        \
871
VRT_l_##which##_body(VRT_CTX, const char *str, ...)             \
872
{                                                               \
873
        va_list ap;                                             \
874
        const char *p;                                          \
875
        struct vsb *vsb;                                        \
876
                                                                \
877
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
878
        va_start(ap, str);                                      \
879
        p = str;                                                \
880
        while (p != vrt_magic_string_end) {                     \
881
                if (p == NULL)                                  \
882
                        p = "(null)";                           \
883
                VSB_cat(vsb, p);                                \
884
                p = va_arg(ap, const char *);                   \
885
        }                                                       \
886
        va_end(ap);                                             \
887
}
888
889 552
VRT_BODY_L(beresp)
890 980
VRT_BODY_L(resp)
891
892
/*--------------------------------------------------------------------*/
893
894
VCL_BLOB
895 28
VRT_r_req_hash(VRT_CTX)
896
{
897 28
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
898 28
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
899 28
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN));
900
}
901
902
VCL_BLOB
903 48
VRT_r_bereq_hash(VRT_CTX)
904
{
905 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
906 48
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
907 48
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN));
908
}
909
910
/*--------------------------------------------------------------------*/
911
912
#define HTTP_VAR(x)                                             \
913
VCL_HTTP                                                        \
914
VRT_r_##x(VRT_CTX)                                              \
915
{                                                               \
916
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
917
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
918
        return (ctx->http_##x);                                 \
919
}
920
921 16
HTTP_VAR(req)
922 4
HTTP_VAR(resp)
923 4
HTTP_VAR(bereq)
924 0
HTTP_VAR(beresp)