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 "cache_director.h"
39
#include "vrt_obj.h"
40
41
static char vrt_hostname[255] = "";
42
43
/*--------------------------------------------------------------------
44
 * VRT variables relating to first line of HTTP/1.1 req/resp
45
 */
46
47
static void
48 82
vrt_do_string(VRT_CTX, struct http *hp, int fld,
49
    const char *err, const char *p, va_list ap)
50
{
51
        const char *b;
52
53 82
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
54
55 82
        b = VRT_String(hp->ws, NULL, p, ap);
56 82
        if (b == NULL) {
57 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
58 0
                WS_MarkOverflow(hp->ws);
59 0
                return;
60
        }
61 82
        if (*b == '\0') {
62 4
                VRT_fail(ctx, "Setting %s to empty string", err);
63 4
                return;
64
        }
65 78
        http_SetH(hp, fld, b);
66
}
67
68
#define VRT_HDR_L(obj, hdr, fld)                                        \
69
void                                                                    \
70
VRT_l_##obj##_##hdr(VRT_CTX, const char *p, ...)                        \
71
{                                                                       \
72
        va_list ap;                                                     \
73
                                                                        \
74
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
75
        va_start(ap, p);                                                \
76
        vrt_do_string(ctx, ctx->http_##obj, fld, #obj "." #hdr, p, ap); \
77
        va_end(ap);                                                     \
78
}
79
80
#define VRT_HDR_R(obj, hdr, fld)                                        \
81
const char *                                                            \
82
VRT_r_##obj##_##hdr(VRT_CTX)                                            \
83
{                                                                       \
84
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
85
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
86
        return (ctx->http_##obj->hd[fld].b);                            \
87
}
88
89
#define VRT_HDR_LR(obj, hdr, fld)                                       \
90
        VRT_HDR_L(obj, hdr, fld)                                        \
91
        VRT_HDR_R(obj, hdr, fld)
92
93
#define VRT_STATUS_L(obj)                                               \
94
void                                                                    \
95
VRT_l_##obj##_status(VRT_CTX, long num)                                 \
96
{                                                                       \
97
                                                                        \
98
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
99
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
100
        if (num < 0)                                                    \
101
                VRT_fail(ctx, "%s.status (%ld) is negative", #obj, num); \
102
        else if (num > 65535)                                           \
103
                VRT_fail(ctx, "%s.status (%ld) > 65535", #obj, num);    \
104
        else if ((num % 1000) < 100)                                    \
105
                VRT_fail(ctx, "illegal %s.status (%ld) (..0##)", #obj, num); \
106
        else                                                            \
107
                http_SetStatus(ctx->http_##obj, (uint16_t)num);         \
108
}
109
110
#define VRT_STATUS_R(obj)                                               \
111
long                                                                    \
112
VRT_r_##obj##_status(VRT_CTX)                                           \
113
{                                                                       \
114
                                                                        \
115
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
116
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
117
        return (ctx->http_##obj->status);                               \
118
}
119
120 9842
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
121 5232
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
122 8
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
123
124 8
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
125 8
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
126 8
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
127
128 4
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
129 1048
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
130 24
VRT_STATUS_L(resp)
131 744
VRT_STATUS_R(resp)
132
133 2692
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
134 408
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
135 6
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
136 4
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
137 542
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
138 30
VRT_STATUS_L(beresp)
139 408
VRT_STATUS_R(beresp)
140
141
/*--------------------------------------------------------------------
142
 * Pulling things out of the packed object->http
143
 */
144
145
long
146 2
VRT_r_obj_status(VRT_CTX)
147
{
148 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
149 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
150 2
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
151
152 2
        return (HTTP_GetStatusPack(ctx->req->wrk, ctx->req->objcore));
153
}
154
155
const char *
156 2
VRT_r_obj_proto(VRT_CTX)
157
{
158 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
159 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
160 2
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
161
162 2
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
163
            H__Proto));
164
}
165
166
const char *
167 2
VRT_r_obj_reason(VRT_CTX)
168
{
169 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
170 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
171 2
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
172
173 2
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
174
            H__Reason));
175
}
176
177
/*--------------------------------------------------------------------
178
 * bool-fields (.do_*)
179
 */
180
181
#define VBERESPW0(field)
182
#define VBERESPW1(field)                                                \
183
void                                                                    \
184
VRT_l_beresp_##field(VRT_CTX, unsigned a)                               \
185
{                                                                       \
186
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
187
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
188
        ctx->bo->field = a ? 1 : 0;                                     \
189
}
190
191
#define VBERESPR0(field)
192
#define VBERESPR1(field)                                                \
193
unsigned                                                                \
194
VRT_r_beresp_##field(VRT_CTX)                                           \
195
{                                                                       \
196
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
197
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
198
        return (ctx->bo->field);                                        \
199
}
200
201
#define BO_FLAG(l, r, w, d) \
202
        VBERESPR##r(l) \
203
        VBERESPW##w(l)
204
#include "tbl/bo_flags.h"
205
206
/*--------------------------------------------------------------------*/
207
208
unsigned
209 4
VRT_r_bereq_is_bgfetch(VRT_CTX)
210
{
211 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
212 4
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
213 4
        return (ctx->bo->is_bgfetch);
214
}
215
216
unsigned
217 2439
VRT_r_bereq_uncacheable(VRT_CTX)
218
{
219 2439
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
220 2439
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
221 2439
        return (ctx->bo->do_pass);
222
}
223
224
void
225 102
VRT_l_beresp_uncacheable(VRT_CTX, unsigned a)
226
{
227 102
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
228 102
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
229
230 102
        if (ctx->bo->uncacheable && !a) {
231 0
                VSLb(ctx->vsl, SLT_VCL_Error,
232
                    "Ignoring attempt to reset beresp.uncacheable");
233 102
        } else if (a) {
234 100
                ctx->bo->uncacheable = 1;
235
        }
236 102
}
237
238
unsigned
239 2
VRT_r_beresp_uncacheable(VRT_CTX)
240
{
241 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
242 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
243 2
        return (ctx->bo->uncacheable);
244
}
245
246
/*--------------------------------------------------------------------*/
247
248
const char *
249 4
VRT_r_client_identity(VRT_CTX)
250
{
251
252 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
253 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
254 4
        if (ctx->req->client_identity != NULL)
255 4
                return (ctx->req->client_identity);
256 0
        return (SES_Get_String_Attr(ctx->req->sp, SA_CLIENT_IP));
257
}
258
259
void
260 4
VRT_l_client_identity(VRT_CTX, const char *str, ...)
261
{
262
        va_list ap;
263
        const char *b;
264
265 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
266 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
267 4
        va_start(ap, str);
268 4
        b = VRT_String(ctx->req->http->ws, NULL, str, ap);
269 4
        va_end(ap);
270 4
        if (b == NULL) {
271 0
                VSLb(ctx->vsl, SLT_LostHeader, "client.identity");
272 0
                WS_MarkOverflow(ctx->req->http->ws);
273 4
                return;
274
        }
275 4
        ctx->req->client_identity = b;
276
}
277
278
/*--------------------------------------------------------------------*/
279
280
#define BEREQ_TIMEOUT(which)                                    \
281
void                                                            \
282
VRT_l_bereq_##which(VRT_CTX, double num)                        \
283
{                                                               \
284
                                                                \
285
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
286
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
287
        ctx->bo->which = (num > 0.0 ? num : 0.0);               \
288
}                                                               \
289
                                                                \
290
double                                                          \
291
VRT_r_bereq_##which(VRT_CTX)                                    \
292
{                                                               \
293
                                                                \
294
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
295
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
296
        return (ctx->bo->which);                                \
297
}
298
299 4
BEREQ_TIMEOUT(connect_timeout)
300 8
BEREQ_TIMEOUT(first_byte_timeout)
301 16
BEREQ_TIMEOUT(between_bytes_timeout)
302
303
/*--------------------------------------------------------------------*/
304
305
const char *
306 2
VRT_r_beresp_backend_name(VRT_CTX)
307
{
308
309 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
310 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
311 2
        if (ctx->bo->director_resp != NULL)
312 2
                return (ctx->bo->director_resp->vcl_name);
313 0
        return (NULL);
314
}
315
316
/*--------------------------------------------------------------------
317
 * Backends do not in general have a IP number (any more) and this
318
 * variable is really not about the backend, but the backend connection.
319
 * XXX: we may need a more general beresp.backend.{details|ident}
320
 */
321
322
VCL_IP
323 2
VRT_r_beresp_backend_ip(VRT_CTX)
324
{
325
326 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
327 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
328 2
        return (VDI_GetIP(ctx->bo->wrk, ctx->bo));
329
}
330
331
/*--------------------------------------------------------------------*/
332
333
VCL_STEVEDORE
334 2
VRT_r_req_storage(VRT_CTX)
335
{
336 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
337 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
338 2
        return (ctx->req->storage);
339
}
340
341
void
342 4
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
343
{
344 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
345 4
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
346 4
        ctx->req->storage = stv;
347 4
}
348
349
/*--------------------------------------------------------------------*/
350
351
VCL_STEVEDORE
352 14
VRT_r_beresp_storage(VRT_CTX)
353
{
354 14
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
355 14
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
356 14
        return (ctx->bo->storage);
357
}
358
359
void
360 36
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
361
{
362 36
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
363 36
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
364 36
        ctx->bo->storage = stv;
365 36
}
366
367
/*--------------------------------------------------------------------*/
368
369
#define REQ_VAR_L(nm, elem, type,extra)                                 \
370
                                                                        \
371
void                                                                    \
372
VRT_l_req_##nm(VRT_CTX, type arg)                                       \
373
{                                                                       \
374
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
375
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
376
        extra;                                                          \
377
        ctx->req->elem = arg;                                           \
378
}
379
380
#define REQ_VAR_R(nm, elem, type)                                       \
381
                                                                        \
382
type                                                                    \
383
VRT_r_req_##nm(VRT_CTX)                                                 \
384
{                                                                       \
385
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
386
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
387
        return (ctx->req->elem);                                        \
388
}
389
390 210
REQ_VAR_L(backend_hint, director_hint, const struct director *,)
391 16
REQ_VAR_R(backend_hint, director_hint, const struct director *)
392 10
REQ_VAR_L(ttl, d_ttl, double, if (!(arg>0.0)) arg = 0;)
393 12
REQ_VAR_R(ttl, d_ttl, double)
394
395
/*--------------------------------------------------------------------*/
396
397
void
398 288
VRT_l_bereq_backend(VRT_CTX, const struct director *be)
399
{
400
401 288
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
402 288
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
403 288
        ctx->bo->director_req = be;
404 288
}
405
406
const struct director *
407 50
VRT_r_bereq_backend(VRT_CTX)
408
{
409
410 50
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
411 50
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
412 50
        return (ctx->bo->director_req);
413
}
414
415
const struct director *
416 46
VRT_r_beresp_backend(VRT_CTX)
417
{
418
419 46
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
420 46
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
421 46
        return (ctx->bo->director_resp);
422
}
423
424
/*--------------------------------------------------------------------*/
425
426
void
427 2612
VRT_l_bereq_body(VRT_CTX, const char *p, ...)
428
{
429 2612
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
430 2612
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
431 2612
        assert(p == vrt_magic_string_unset);
432 2612
        if (ctx->bo->req != NULL) {
433 8
                CHECK_OBJ_NOTNULL(ctx->bo->req, REQ_MAGIC);
434 8
                ctx->bo->req = NULL;
435 8
                http_Unset(ctx->bo->bereq, H_Content_Length);
436
        }
437 2612
}
438
439
/*--------------------------------------------------------------------*/
440
441
void
442 22
VRT_l_req_esi(VRT_CTX, unsigned process_esi)
443
{
444
445 22
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
446 22
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
447
        /*
448
         * Only allow you to turn of esi in the main request
449
         * else everything gets confused
450
         */
451 22
        if (ctx->req->esi_level == 0)
452 14
                ctx->req->disable_esi = !process_esi;
453 22
}
454
455
unsigned
456 6
VRT_r_req_esi(VRT_CTX)
457
{
458
459 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
460 6
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
461 6
        return (!ctx->req->disable_esi);
462
}
463
464
long
465 42
VRT_r_req_esi_level(VRT_CTX)
466
{
467
468 42
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
469 42
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
470 42
        return (ctx->req->esi_level);
471
}
472
473
/*--------------------------------------------------------------------*/
474
475
unsigned
476 16
VRT_r_req_can_gzip(VRT_CTX)
477
{
478
479 16
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
480 16
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
481 16
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
482
}
483
484
/*--------------------------------------------------------------------*/
485
486
long
487 124
VRT_r_req_restarts(VRT_CTX)
488
{
489
490 124
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
491 124
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
492 124
        return (ctx->req->restarts);
493
}
494
495
long
496 56
VRT_r_bereq_retries(VRT_CTX)
497
{
498
499 56
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
500 56
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
501 56
        return (ctx->bo->retries);
502
}
503
504
/*--------------------------------------------------------------------
505
 * In exp.*:
506
 *      t_origin is absolute
507
 *      ttl is relative to t_origin
508
 *      grace&keep are relative to ttl
509
 * In VCL:
510
 *      ttl is relative to now
511
 *      grace&keep are relative to ttl
512
 */
513
514
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
515
                                                                \
516
void                                                            \
517
VRT_l_##which##_##fld(VRT_CTX, double a)                        \
518
{                                                               \
519
                                                                \
520
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
521
        a += (offset);                                          \
522
        if (a < 0.0)                                            \
523
                a = 0.0;                                        \
524
        oc->fld = a;                                            \
525
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f",      \
526
            oc->ttl, oc->grace, oc->keep, oc->t_origin);        \
527
}
528
529
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
530
                                                                \
531
double                                                          \
532
VRT_r_##which##_##fld(VRT_CTX)                                  \
533
{                                                               \
534
        double d;                                               \
535
                                                                \
536
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
537
        d = oc->fld;                                            \
538
        if (d <= 0.0)                                           \
539
                d = 0.0;                                        \
540
        d -= (offset);                                          \
541
        return (d);                                             \
542
}
543
544 1077
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
545
    ctx->now - ctx->req->objcore->t_origin)
546 71
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
547 14
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
548
549 210
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
550
    ctx->now - ctx->bo->fetch_objcore->t_origin)
551 1887
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
552
    ctx->now - ctx->bo->fetch_objcore->t_origin)
553 94
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
554 10
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
555 70
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
556 2
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
557
558
/*--------------------------------------------------------------------
559
 */
560
561
#define VRT_DO_AGE_R(which, oc)                                 \
562
                                                                \
563
double                                                          \
564
VRT_r_##which##_##age(VRT_CTX)                                  \
565
{                                                               \
566
                                                                \
567
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
568
        return (ctx->now - oc->t_origin);                       \
569
}
570
571 16
VRT_DO_AGE_R(obj, ctx->req->objcore)
572 2
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
573
574
/*--------------------------------------------------------------------
575
 * [be]req.xid
576
 */
577
578
const char *
579 342
VRT_r_req_xid(VRT_CTX)
580
{
581
582 342
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
583 342
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
584
585 342
        return (WS_Printf(ctx->req->http->ws, "%u",
586 342
            VXID(ctx->req->vsl->wid)));
587
}
588
589
const char *
590 188
VRT_r_bereq_xid(VRT_CTX)
591
{
592
593 188
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
594 188
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
595
596 188
        return (WS_Printf(ctx->bo->bereq->ws, "%u",
597 188
            VXID(ctx->bo->vsl->wid)));
598
}
599
600
/*--------------------------------------------------------------------
601
 * req fields
602
 */
603
604
#define VREQW0(field)
605
#define VREQW1(field)                                                   \
606
void                                                                    \
607
VRT_l_req_##field(VRT_CTX, unsigned a)                                  \
608
{                                                                       \
609
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
610
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
611
        ctx->req->field = a ? 1 : 0;                                    \
612
}
613
614
#define VREQR0(field)
615
#define VREQR1(field)                                                   \
616
unsigned                                                                \
617
VRT_r_req_##field(VRT_CTX)                                              \
618
{                                                                       \
619
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
620
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
621
        return (ctx->req->field);                                       \
622
}
623
624
#define REQ_FLAG(l, r, w, d) \
625
        VREQR##r(l) \
626
        VREQW##w(l)
627
#include "tbl/req_flags.h"
628
629
/*--------------------------------------------------------------------*/
630
631
#define GIP(fld)                                                \
632
        VCL_IP                                                  \
633
        VRT_r_##fld##_ip(VRT_CTX)                               \
634
        {                                                       \
635
                struct suckaddr *sa;                            \
636
                                                                \
637
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
638
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
639
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
640
                return (sa);                                    \
641
        }
642
643 62
GIP(local)
644 64
GIP(remote)
645 124
GIP(client)
646 3863
GIP(server)
647
#undef GIP
648
649
/*--------------------------------------------------------------------*/
650
651
const char*
652 16
VRT_r_server_identity(VRT_CTX)
653
{
654
655 16
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
656 16
        if (heritage.identity != NULL)
657 16
                return (heritage.identity);
658
        else
659 0
                return ("varnishd");
660
}
661
662
const char*
663 4
VRT_r_server_hostname(VRT_CTX)
664
{
665
666 4
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
667 4
        if (vrt_hostname[0] == '\0')
668 2
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
669 4
        return (vrt_hostname);
670
}
671
672
/*--------------------------------------------------------------------*/
673
674
long
675 48
VRT_r_obj_hits(VRT_CTX)
676
{
677 48
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
678 48
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
679 48
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
680 48
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
681
}
682
683
unsigned
684 12
VRT_r_obj_uncacheable(VRT_CTX)
685
{
686
687 12
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
688 12
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
689 12
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
690 12
        return (ctx->req->objcore->flags & OC_F_PASS ? 1 : 0);
691
}
692
693
/*--------------------------------------------------------------------*/
694
695
unsigned
696 6
VRT_r_resp_is_streaming(VRT_CTX)
697
{
698 6
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
699 6
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
700 6
        if (ctx->req->objcore == NULL)
701 2
                return (0);     /* When called from vcl_synth */
702 4
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
703 4
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
704
}
705
706
/*--------------------------------------------------------------------*/
707
708
#define VRT_BODY_L(which)                                       \
709
void                                                            \
710
VRT_l_##which##_body(VRT_CTX, const char *str, ...)             \
711
{                                                               \
712
        va_list ap;                                             \
713
        const char *p;                                          \
714
        struct vsb *vsb;                                        \
715
                                                                \
716
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
717
        va_start(ap, str);                                      \
718
        p = str;                                                \
719
        while (p != vrt_magic_string_end) {                     \
720
                if (p == NULL)                                  \
721
                        p = "(null)";                           \
722
                VSB_cat(vsb, p);                                \
723
                p = va_arg(ap, const char *);                   \
724
        }                                                       \
725
        va_end(ap);                                             \
726
}
727
728 176
VRT_BODY_L(beresp)
729 342
VRT_BODY_L(resp)
730
731
/*--------------------------------------------------------------------*/
732
733
VCL_BLOB
734 2
VRT_r_req_hash(VRT_CTX)
735
{
736 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
737 2
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
738 2
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN));
739
}
740
741
VCL_BLOB
742 2
VRT_r_bereq_hash(VRT_CTX)
743
{
744 2
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
745 2
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
746 2
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN));
747
}
748
749
/*--------------------------------------------------------------------*/
750
751
#define HTTP_VAR(x)                                             \
752
struct http *                                                   \
753
VRT_r_##x(VRT_CTX)                                              \
754
{                                                               \
755
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
756
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
757
        return (ctx->http_##x);                                 \
758
}
759
760 8
HTTP_VAR(req)
761 2
HTTP_VAR(resp)
762 2
HTTP_VAR(bereq)
763 0
HTTP_VAR(beresp)