varnish-cache/bin/varnishd/cache/cache_vrt_var.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 * Runtime support for compiled VCL programs
31
 */
32
#include "config.h"
33
34
#include <stdio.h>
35
36
#include "cache_varnishd.h"
37
#include "cache_objhead.h"
38
#include "cache_transport.h"
39
#include "common/heritage.h"
40
41
#include "vcl.h"
42
#include "vtim.h"
43
#include "vtcp.h"
44
45
#include "vrt_obj.h"
46
47
#define VRT_TMO(tmo) (isinf(tmo) ? VRT_DECIMAL_MAX : tmo)
48
49
static char vrt_hostname[255] = "";
50
51
/*--------------------------------------------------------------------
52
 * VRT variables relating to first line of HTTP/1.1 req/resp
53
 */
54
55
static void
56 2240
vrt_do_strands(VRT_CTX, struct http *hp, int fld,
57
    const char *err, const char *str, VCL_STRANDS s)
58
{
59
        const char *b;
60
61 2240
        CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
62
63 2240
        b = VRT_StrandsWS(hp->ws, str, s);
64 2240
        if (b == NULL) {
65 0
                VRT_fail(ctx, "Workspace overflow (%s)", err);
66 0
                WS_MarkOverflow(hp->ws);
67 0
                return;
68
        }
69 2240
        if (*b == '\0') {
70 120
                VRT_fail(ctx, "Setting %s to empty string", err);
71 120
                return;
72
        }
73 2120
        http_SetH(hp, fld, b);
74 2240
}
75
76
#define VRT_HDR_L(obj, hdr, fld)                                        \
77
VCL_VOID                                                                \
78
VRT_l_##obj##_##hdr(VRT_CTX, const char *str, VCL_STRANDS s)            \
79
{                                                                       \
80
                                                                        \
81
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
82
        vrt_do_strands(ctx, ctx->http_##obj, fld, #obj "." #hdr, str, s);       \
83
}
84
85
#define VRT_HDR_R(obj, hdr, fld)                                        \
86
VCL_STRING                                                              \
87
VRT_r_##obj##_##hdr(VRT_CTX)                                            \
88
{                                                                       \
89
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
90
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
91
        return (ctx->http_##obj->hd[fld].b);                            \
92
}
93
94
#define VRT_HDR_LR(obj, hdr, fld)                                       \
95
        VRT_HDR_L(obj, hdr, fld)                                        \
96
        VRT_HDR_R(obj, hdr, fld)
97
98
#define VRT_STATUS_L(obj)                                               \
99
VCL_VOID                                                                \
100
VRT_l_##obj##_status(VRT_CTX, VCL_INT num)                              \
101
{                                                                       \
102
                                                                        \
103
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
104
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
105
        if (num < 0)                                                    \
106
                VRT_fail(ctx, "%s.status (%jd) is negative",            \
107
                    #obj, (intmax_t)num);                               \
108
        else if (num > 65535)                                           \
109
                VRT_fail(ctx, "%s.status (%jd) > 65535",                \
110
                    #obj, (intmax_t)num);                               \
111
        else if ((num % 1000) < 100)                                    \
112
                VRT_fail(ctx, "illegal %s.status (%jd) (..0##)",        \
113
                    #obj, (intmax_t)num);                               \
114
        else                                                            \
115
                http_SetStatus(ctx->http_##obj, (uint16_t)num, NULL);   \
116
}
117
118
#define VRT_STATUS_R(obj)                                               \
119
VCL_INT                                                                 \
120
VRT_r_##obj##_status(VRT_CTX)                                           \
121
{                                                                       \
122
                                                                        \
123
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
124
        CHECK_OBJ_NOTNULL(ctx->http_##obj, HTTP_MAGIC);                 \
125
        return (ctx->http_##obj->status);                               \
126
}
127
128 311488
VRT_HDR_LR(req,    method,      HTTP_HDR_METHOD)
129 184272
VRT_HDR_LR(req,    url,         HTTP_HDR_URL)
130 4000
VRT_HDR_LR(req,    proto,       HTTP_HDR_PROTO)
131
132 160
VRT_HDR_R(req_top,    method,   HTTP_HDR_METHOD)
133 160
VRT_HDR_R(req_top,    url,      HTTP_HDR_URL)
134 160
VRT_HDR_R(req_top,    proto,    HTTP_HDR_PROTO)
135
136 160
VRT_HDR_LR(resp,   proto,       HTTP_HDR_PROTO)
137 55360
VRT_HDR_LR(resp,   reason,      HTTP_HDR_REASON)
138 1720
VRT_STATUS_L(resp)
139 38120
VRT_STATUS_R(resp)
140
141 88559
VRT_HDR_LR(bereq,  method,      HTTP_HDR_METHOD)
142 21240
VRT_HDR_LR(bereq,  url,         HTTP_HDR_URL)
143 120
VRT_HDR_LR(bereq,  proto,       HTTP_HDR_PROTO)
144 80
VRT_HDR_LR(beresp, proto,       HTTP_HDR_PROTO)
145 35398
VRT_HDR_LR(beresp, reason,      HTTP_HDR_REASON)
146 4080
VRT_STATUS_L(beresp)
147 173800
VRT_STATUS_R(beresp)
148
149
/*--------------------------------------------------------------------
150
 * Pulling things out of the packed object->http
151
 */
152
153
VCL_INT
154 40
VRT_r_obj_status(VRT_CTX)
155
{
156 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
157 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
158 40
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
159
160 40
        return (HTTP_GetStatusPack(ctx->req->wrk, ctx->req->objcore));
161
}
162
163
VCL_STRING
164 40
VRT_r_obj_proto(VRT_CTX)
165
{
166 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
167 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
168 40
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
169
170 40
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
171
            H__Proto));
172
}
173
174
VCL_STRING
175 40
VRT_r_obj_reason(VRT_CTX)
176
{
177 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
178 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
179 40
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
180
181 40
        return (HTTP_GetHdrPack(ctx->req->wrk, ctx->req->objcore,
182
            H__Reason));
183
}
184
185
/*--------------------------------------------------------------------
186
 * beresp bool-fields
187
 */
188
189
static inline int
190 15040
beresp_filter_fixed(VRT_CTX, const char *s)
191
{
192 15040
        if (ctx->bo->vfp_filter_list == NULL)
193 15000
                return (0);
194 80
        VRT_fail(ctx,
195 40
            "beresp.filters are already fixed, beresp.%s is undefined", s);
196 40
        return (1);
197 15040
}
198
199
#define VBERESPWF0(ctx, str) (void) 0
200
#define VBERESPWF1(ctx, str) do {               \
201
        if (beresp_filter_fixed((ctx), str))    \
202
                return;                 \
203
        } while(0)
204
205
#define VBERESPW0(field, str, fltchk)
206
#define VBERESPW1(field, str, fltchk)                                   \
207
void                                                                    \
208
VRT_l_beresp_##field(VRT_CTX, VCL_BOOL a)                               \
209
{                                                                       \
210
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
211
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
212
        VBERESPWF##fltchk(ctx, str);                                    \
213
        ctx->bo->field = a ? 1 : 0;                                     \
214
}
215
216
#define VBERESPRF0(ctx, str) (void) 0
217
#define VBERESPRF1(ctx, str) do {               \
218
        if (beresp_filter_fixed((ctx), str))    \
219
                return (0);                     \
220
        } while(0)
221
222
#define VBERESPR1(field, str, fltchk)                                   \
223
VCL_BOOL                                                                \
224
VRT_r_beresp_##field(VRT_CTX)                                           \
225
{                                                                       \
226
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
227
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
228
        VBERESPRF##fltchk(ctx, str);                                    \
229
        return (ctx->bo->field);                                        \
230
}
231
232
#define BERESP_FLAG(l, r, w, f, d)              \
233
        VBERESPR##r(l, #l, f)                   \
234
        VBERESPW##w(l, #l, f)
235
#include "tbl/beresp_flags.h"
236
237
#undef VBERESPWF0
238
#undef VBERESPWF1
239
#undef VBERESPW0
240
#undef VBERESPW1
241
242
#undef VBERESPRF0
243
#undef VBERESPRF1
244
#undef VBERESPR1
245
246
/*--------------------------------------------------------------------
247
 * bereq bool-fields
248
 */
249
250
#define VBEREQR0(field, str)
251
#define VBEREQR1(field, str)                                            \
252
VCL_BOOL                                                                \
253
VRT_r_bereq_##field(VRT_CTX)                                            \
254
{                                                                       \
255
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
256
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);                      \
257
        return (ctx->bo->field);                                        \
258
}
259
260
#define BEREQ_FLAG(l, r, w, d)          \
261
        VBEREQR##r(l, #l)
262
#include "tbl/bereq_flags.h"
263
264
#undef VBEREQR0
265
#undef VBEREQR1
266
/*--------------------------------------------------------------------*/
267
268
VCL_BOOL
269 74960
VRT_r_bereq_uncacheable(VRT_CTX)
270
{
271 74960
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
272 74960
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
273 74960
        return (ctx->bo->uncacheable);
274
}
275
276
VCL_VOID
277 3280
VRT_l_beresp_uncacheable(VRT_CTX, VCL_BOOL a)
278
{
279
        struct objcore *oc;
280
281 3280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
282 3280
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
283 3280
        CHECK_OBJ_NOTNULL(ctx->bo->fetch_objcore, OBJCORE_MAGIC);
284
285 3280
        if (ctx->bo->uncacheable && !a) {
286 0
                VSLb(ctx->vsl, SLT_VCL_Error,
287
                    "Ignoring attempt to reset beresp.uncacheable");
288 3280
        } else if (a) {
289 3240
                ctx->bo->uncacheable = 1;
290 3240
        }
291 3280
        oc = ctx->bo->fetch_objcore;
292
293 6560
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
294 3280
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
295 6560
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
296
}
297
298
VCL_BOOL
299 40
VRT_r_beresp_uncacheable(VRT_CTX)
300
{
301 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
302 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
303 40
        return (ctx->bo->uncacheable);
304
}
305
306
VCL_VOID
307 40
VRT_l_req_trace(VRT_CTX, VCL_BOOL a)
308
{
309 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
310 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
311 40
        ctx->req->trace = a;
312 40
        VRT_trace(ctx, a);
313 40
}
314
VCL_VOID
315 0
VRT_l_bereq_trace(VRT_CTX, VCL_BOOL a)
316
{
317 0
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
318 0
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
319 0
        ctx->bo->trace = a;
320 0
        VRT_trace(ctx, a);
321 0
}
322
323
/*--------------------------------------------------------------------*/
324
325
VCL_BYTES
326 0
VRT_r_beresp_transit_buffer(VRT_CTX)
327
{
328
    struct objcore *oc;
329
330 0
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
331 0
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
332
333 0
    oc = ctx->bo->fetch_objcore;
334 0
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
335
336 0
    return oc->boc->transit_buffer;
337
}
338
339
VCL_VOID
340 80
VRT_l_beresp_transit_buffer(VRT_CTX, VCL_BYTES value)
341
{
342
    struct objcore *oc;
343
344 80
    CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
345 80
    CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
346
347 80
    oc = ctx->bo->fetch_objcore;
348 80
    CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
349
350 80
    oc->boc->transit_buffer = value;
351 80
}
352
353
/*--------------------------------------------------------------------*/
354
355
VCL_STRING
356 240
VRT_r_client_identity(VRT_CTX)
357
{
358
        const char *id;
359
360 240
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
361 240
        if (ctx->req != NULL) {
362 160
                CHECK_OBJ(ctx->req, REQ_MAGIC);
363 160
                id = ctx->req->client_identity;
364 160
        } else {
365 80
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
366 80
                id = ctx->bo->client_identity;
367
        }
368 240
        if (id != NULL)
369 160
                return (id);
370 80
        return (SES_Get_String_Attr(ctx->sp, SA_CLIENT_IP));
371 240
}
372
373
VCL_VOID
374 120
VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s)
375
{
376
        const char *b;
377
378 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
379 120
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
380 120
        b = VRT_StrandsWS(ctx->req->http->ws, str, s);
381 120
        if (b == NULL) {
382 0
                VSLb(ctx->vsl, SLT_LostHeader, "client.identity");
383 0
                WS_MarkOverflow(ctx->req->http->ws);
384 0
                return;
385
        }
386 120
        ctx->req->client_identity = b;
387 120
}
388
389
/*--------------------------------------------------------------------*/
390
391
#define BEREQ_TIMEOUT(prefix, which)                            \
392
VCL_VOID                                                        \
393
VRT_l_bereq_##which(VRT_CTX, VCL_DURATION num)                  \
394
{                                                               \
395
                                                                \
396
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
397
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
398
        ctx->bo->which = num;                                   \
399
}                                                               \
400
                                                                \
401
VCL_DURATION                                                    \
402
VRT_r_bereq_##which(VRT_CTX)                                    \
403
{                                                               \
404
        vtim_dur res;                                           \
405
                                                                \
406
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
407
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
408
        res = BUSYOBJ_TMO(ctx->bo, prefix, which);              \
409
        return (VRT_TMO(res));                                  \
410
}                                                               \
411
                                                                \
412
VCL_VOID                                                        \
413
VRT_u_bereq_##which(VRT_CTX)                                    \
414
{                                                               \
415
                                                                \
416
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
417
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);              \
418
        ctx->bo->which = NAN;                                   \
419
}
420
421 280
BEREQ_TIMEOUT(, connect_timeout)
422 360
BEREQ_TIMEOUT(, first_byte_timeout)
423 560
BEREQ_TIMEOUT(, between_bytes_timeout)
424 360
BEREQ_TIMEOUT(pipe_, task_deadline)
425
426
427
/*--------------------------------------------------------------------*/
428
429
VCL_STRING
430 40
VRT_r_beresp_backend_name(VRT_CTX)
431
{
432
433 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
434 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
435 40
        if (ctx->bo->director_resp != NULL)
436 40
                return (ctx->bo->director_resp->vcl_name);
437 0
        return (NULL);
438 40
}
439
440
/*--------------------------------------------------------------------
441
 * Backends do not in general have a IP number (any more) and this
442
 * variable is really not about the backend, but the backend connection.
443
 * XXX: we may need a more general beresp.backend.{details|ident}
444
 */
445
446
VCL_IP
447 40
VRT_r_beresp_backend_ip(VRT_CTX)
448
{
449
450 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
451 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
452 40
        return (VDI_GetIP(ctx->bo));
453
}
454
455
/*--------------------------------------------------------------------*/
456
457
VCL_STEVEDORE
458 40
VRT_r_req_storage(VRT_CTX)
459
{
460 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
461 40
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
462 40
        return (ctx->req->storage);
463
}
464
465
VCL_VOID
466 240
VRT_l_req_storage(VRT_CTX, VCL_STEVEDORE stv)
467
{
468 240
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
469 240
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
470 240
        ctx->req->storage = stv;
471 240
}
472
473
/*--------------------------------------------------------------------*/
474
475
VCL_STEVEDORE
476 400
VRT_r_beresp_storage(VRT_CTX)
477
{
478 400
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
479 400
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
480 400
        return (ctx->bo->storage);
481
}
482
483
VCL_VOID
484 960
VRT_l_beresp_storage(VRT_CTX, VCL_STEVEDORE stv)
485
{
486 960
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
487 960
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
488 960
        ctx->bo->storage = stv;
489 960
}
490
491
/*--------------------------------------------------------------------
492
 * VCL <= 4.0 ONLY
493
 */
494
495
#include "storage/storage.h"
496
497
VCL_STRING
498 280
VRT_r_beresp_storage_hint(VRT_CTX)
499
{
500 280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
501 280
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
502 280
        if (ctx->bo->storage == NULL)
503 40
                return (NULL);
504 240
        CHECK_OBJ_NOTNULL(ctx->bo->storage, STEVEDORE_MAGIC);
505 240
        return (ctx->bo->storage->vclname);
506 280
}
507
508
VCL_VOID
509 40
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, VCL_STRANDS s)
510
{
511
        const char *p;
512
        VCL_STEVEDORE stv;
513
514 40
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
515 40
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
516
517 40
        p = VRT_StrandsWS(ctx->ws, str, s);
518
519 40
        if (p == NULL) {
520 0
                VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
521 0
                WS_MarkOverflow(ctx->ws);
522 0
                return;
523
        }
524
525 40
        stv = VRT_stevedore(p);
526 40
        if (stv != NULL)
527 40
                ctx->bo->storage = stv;
528 40
}
529
530
/*--------------------------------------------------------------------*/
531
532
VCL_STEVEDORE
533 160
VRT_r_obj_storage(VRT_CTX)
534
{
535 160
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
536 160
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
537 160
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
538 160
        AN(ctx->req->objcore->stobj);
539 160
        CHECK_OBJ_NOTNULL(ctx->req->objcore->stobj->stevedore,
540
            STEVEDORE_MAGIC);
541 160
        return (ctx->req->objcore->stobj->stevedore);
542
}
543
544
/*--------------------------------------------------------------------*/
545
546
VCL_BOOL
547 320
VRT_r_obj_can_esi(VRT_CTX)
548
{
549 320
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
550 320
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
551 320
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
552 320
        return (ObjHasAttr(ctx->req->wrk, ctx->req->objcore, OA_ESIDATA));
553
}
554
555
/*--------------------------------------------------------------------*/
556
557
#define REQ_VAR_L(nm, elem, type, extra)                                \
558
                                                                        \
559
VCL_VOID                                                                \
560
VRT_l_req_##nm(VRT_CTX, type arg)                                       \
561
{                                                                       \
562
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
563
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
564
        extra;                                                          \
565
        ctx->req->elem = arg;                                           \
566
}
567
568
#define REQ_VAR_R(nm, elem, type)                                       \
569
                                                                        \
570
type                                                                    \
571
VRT_r_req_##nm(VRT_CTX)                                                 \
572
{                                                                       \
573
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
574
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
575
        return (ctx->req->elem);                                        \
576
}
577
578
#define REQ_VAR_U(nm, elem, val)                                        \
579
                                                                        \
580
VCL_VOID                                                                \
581
VRT_u_req_##nm(VRT_CTX)                                                 \
582
{                                                                       \
583
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
584
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
585
        ctx->req->elem = val;                                           \
586
}
587
588 640
REQ_VAR_R(backend_hint, director_hint, VCL_BACKEND)
589
590 200
REQ_VAR_L(ttl, d_ttl, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
591 240
REQ_VAR_R(ttl, d_ttl, VCL_DURATION)
592 0
REQ_VAR_U(ttl, d_ttl, -1)
593 120
REQ_VAR_L(grace, d_grace, VCL_DURATION, if (!(arg>0.0)) arg = 0;)
594 360
REQ_VAR_R(grace, d_grace, VCL_DURATION)
595 40
REQ_VAR_U(grace, d_grace, -1)
596
597
VCL_VOID
598 5920
VRT_l_req_backend_hint(VRT_CTX, VCL_BACKEND be)
599
{
600
601 5920
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
602 5920
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
603 5920
        VRT_Assign_Backend(&ctx->req->director_hint, be);
604 5920
}
605
606
/*--------------------------------------------------------------------*/
607
608
VCL_VOID
609 10319
VRT_l_bereq_backend(VRT_CTX, VCL_BACKEND be)
610
{
611
612 10319
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
613 10319
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
614 10319
        VRT_Assign_Backend(&ctx->bo->director_req, be);
615 10319
}
616
617
VCL_BACKEND
618 1840
VRT_r_bereq_backend(VRT_CTX)
619
{
620
621 1840
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
622 1840
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
623 1840
        return (ctx->bo->director_req);
624
}
625
626
VCL_BACKEND
627 1560
VRT_r_beresp_backend(VRT_CTX)
628
{
629
630 1560
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
631 1560
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
632 1560
        return (ctx->bo->director_resp);
633
}
634
635
/*--------------------------------------------------------------------*/
636
637
VCL_VOID
638 84758
VRT_u_bereq_body(VRT_CTX)
639
{
640 84758
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
641 84758
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
642 84758
        if (ctx->bo->bereq_body != NULL) {
643 200
                (void)HSH_DerefObjCore(ctx->bo->wrk, &ctx->bo->bereq_body, 0);
644 200
                http_Unset(ctx->bo->bereq, H_Content_Length);
645 200
        }
646
647 84758
        if (ctx->bo->req != NULL) {
648 237
                CHECK_OBJ(ctx->bo->req, REQ_MAGIC);
649 237
                ctx->bo->req = NULL;
650 474
                ObjSetState(ctx->bo->wrk,
651 237
                    ctx->bo->fetch_objcore, BOS_REQ_DONE);
652 237
                http_Unset(ctx->bo->bereq, H_Content_Length);
653 237
        }
654 84758
}
655
656
/*--------------------------------------------------------------------*/
657
658
VCL_VOID
659 440
VRT_l_req_esi(VRT_CTX, VCL_BOOL process_esi)
660
{
661
662 440
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
663 440
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
664 440
        assert(ctx->syntax <= 40);
665
        /*
666
         * Only allow you to turn of esi in the main request
667
         * else everything gets confused
668
         * NOTE: this is not true, but we do not change behavior
669
         * for vcl 4.0. For 4.1, see VRT_l_resp_do_esi()
670
         */
671 440
        if (IS_TOPREQ(ctx->req))
672 280
                ctx->req->disable_esi = !process_esi;
673 440
}
674
675
VCL_BOOL
676 120
VRT_r_req_esi(VRT_CTX)
677
{
678
679 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
680 120
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
681 120
        assert(ctx->syntax <= 40);
682 120
        return (!ctx->req->disable_esi);
683
}
684
685
VCL_INT
686 8279
VRT_r_req_esi_level(VRT_CTX)
687
{
688
689 8279
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
690 8279
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
691 8279
        return (ctx->req->esi_level);
692
}
693
694
/*--------------------------------------------------------------------*/
695
696
VCL_BOOL
697 320
VRT_r_req_can_gzip(VRT_CTX)
698
{
699
700 320
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
701 320
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
702 320
        return (RFC2616_Req_Gzip(ctx->req->http));      // XXX ?
703
}
704
705
/*--------------------------------------------------------------------*/
706
707
VCL_INT
708 4760
VRT_r_req_restarts(VRT_CTX)
709
{
710
711 4760
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
712 4760
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
713 4760
        return (ctx->req->restarts);
714
}
715
716
VCL_INT
717 2480
VRT_r_bereq_retries(VRT_CTX)
718
{
719
720 2480
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
721 2480
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
722 2480
        return (ctx->bo->retries);
723
}
724
725
/*--------------------------------------------------------------------*/
726
727
VCL_STRING
728 400
VRT_r_req_transport(VRT_CTX)
729
{
730 400
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
731
732 400
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
733 400
        CHECK_OBJ_NOTNULL(ctx->req->transport, TRANSPORT_MAGIC);
734 400
        return (ctx->req->transport->name);
735
}
736
737
/*--------------------------------------------------------------------
738
 * In exp.*:
739
 *      t_origin is absolute
740
 *      ttl is relative to t_origin
741
 *      grace&keep are relative to ttl
742
 * In VCL:
743
 *      ttl is relative to "ttl_now", which is t_req on the client
744
 *      side, except in vcl_deliver, where it is ctx->now. On the
745
 *      fetch side "ttl_now" is ctx->now (which is bo->t_prev).
746
 *      grace&keep are relative to ttl
747
 */
748
749
static double
750 58120
ttl_now(VRT_CTX)
751
{
752 58120
        if (ctx->bo) {
753 57240
                return (ctx->now);
754
        } else {
755 880
                CHECK_OBJ(ctx->req, REQ_MAGIC);
756 880
                return (ctx->method == VCL_MET_DELIVER
757 880
                    ? ctx->now : ctx->req->t_req);
758
        }
759 58120
}
760
761
#define VRT_DO_EXP_L(which, oc, fld, offset)                    \
762
                                                                \
763
VCL_VOID                                                        \
764
VRT_l_##which##_##fld(VRT_CTX, VCL_DURATION a)                  \
765
{                                                               \
766
                                                                \
767
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
768
        a += (offset);                                          \
769
        if (a < 0.0)                                            \
770
                a = 0.0;                                        \
771
        oc->fld = a;                                            \
772
        VSLb(ctx->vsl, SLT_TTL, "VCL %.0f %.0f %.0f %.0f %s",   \
773
            oc->ttl, oc->grace, oc->keep, oc->t_origin,         \
774
            ctx->bo->uncacheable ? "uncacheable" : "cacheable");\
775
}
776
777
#define VRT_DO_EXP_R(which, oc, fld, offset)                    \
778
                                                                \
779
VCL_DURATION                                                    \
780
VRT_r_##which##_##fld(VRT_CTX)                                  \
781
{                                                               \
782
        double d;                                               \
783
                                                                \
784
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
785
        d = oc->fld;                                            \
786
        if (d <= 0.0)                                           \
787
                d = 0.0;                                        \
788
        d -= (offset);                                          \
789
        return (d);                                             \
790
}
791
792
/*lint -save -e835 */   // Zero right hand arg to '-'
793
794 560
VRT_DO_EXP_R(obj, ctx->req->objcore, ttl,
795
    ttl_now(ctx) - ctx->req->objcore->t_origin)
796 400
VRT_DO_EXP_R(obj, ctx->req->objcore, grace, 0)
797 280
VRT_DO_EXP_R(obj, ctx->req->objcore, keep, 0)
798 8320
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, ttl,
799
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
800 48880
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, ttl,
801
    ttl_now(ctx) - ctx->bo->fetch_objcore->t_origin)
802
803 4400
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, grace, 0)
804 240
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, grace, 0)
805 2560
VRT_DO_EXP_L(beresp, ctx->bo->fetch_objcore, keep, 0)
806 40
VRT_DO_EXP_R(beresp, ctx->bo->fetch_objcore, keep, 0)
807
808
/*lint -restore */
809
810
// XXX more assertions?
811
#define VRT_DO_TIME_R(which, where, field)                              \
812
                                                                        \
813
VCL_TIME                                                                \
814
VRT_r_##which##_time(VRT_CTX)                                           \
815
{                                                                       \
816
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
817
        AN((ctx)->where);                                               \
818
                                                                        \
819
        return ((ctx)->where->field);                                   \
820
}
821
822 320
VRT_DO_TIME_R(req, req, t_req)
823 160
VRT_DO_TIME_R(req_top, req->top->topreq, t_req)
824 120
VRT_DO_TIME_R(resp, req, t_resp)
825 280
VRT_DO_TIME_R(bereq, bo, t_first)
826 80
VRT_DO_TIME_R(beresp, bo, t_resp)
827 80
VRT_DO_TIME_R(obj, req->objcore, t_origin)
828
829
/*--------------------------------------------------------------------
830
 */
831
832
#define VRT_DO_AGE_R(which, oc)                                 \
833
                                                                \
834
VCL_DURATION                                                    \
835
VRT_r_##which##_##age(VRT_CTX)                                  \
836
{                                                               \
837
                                                                \
838
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
839
        return (ttl_now(ctx) - oc->t_origin);                   \
840
}
841
842 320
VRT_DO_AGE_R(obj, ctx->req->objcore)
843 40
VRT_DO_AGE_R(beresp, ctx->bo->fetch_objcore)
844
845
/*--------------------------------------------------------------------
846
 * [[be]req|sess].xid
847
 */
848
849
VCL_INT
850 26480
VRT_r_req_xid(VRT_CTX)
851
{
852
853 26480
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
854 26480
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
855 26480
        CHECK_OBJ_NOTNULL(ctx->req->http, HTTP_MAGIC);
856 26480
        AN(ctx->req->vsl);
857 26480
        return (VXID(ctx->req->vsl->wid));
858
}
859
860
VCL_INT
861 21720
VRT_r_bereq_xid(VRT_CTX)
862
{
863
864 21720
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
865 21720
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
866 21720
        AN(ctx->bo->vsl);
867
868 21720
        return (VXID(ctx->bo->vsl->wid));
869
}
870
871
VCL_INT
872 280
VRT_r_sess_xid(VRT_CTX)
873
{
874
        struct sess *sp;
875
876 280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
877
878 280
        if (ctx->req) {
879 160
                CHECK_OBJ(ctx->req, REQ_MAGIC);
880 160
                sp = ctx->req->sp;
881 160
        } else {
882 120
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
883 120
                sp = ctx->bo->sp;
884
        }
885
886 280
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
887 280
        return (VXID(sp->vxid));
888
}
889
890
/*--------------------------------------------------------------------
891
 * req fields
892
 */
893
894
#define VREQW0(field)
895
#define VREQW1(field)                                                   \
896
VCL_VOID                                                                \
897
VRT_l_req_##field(VRT_CTX, VCL_BOOL a)                                  \
898
{                                                                       \
899
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
900
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
901
        ctx->req->field = a ? 1 : 0;                                    \
902
}
903
904
#define VREQR0(field)
905
#define VREQR1(field)                                                   \
906
VCL_BOOL                                                                \
907
VRT_r_req_##field(VRT_CTX)                                              \
908
{                                                                       \
909
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                          \
910
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);                         \
911
        return (ctx->req->field);                                       \
912
}
913
914
#define REQ_FLAG(l, r, w, d) \
915
        VREQR##r(l) \
916
        VREQW##w(l)
917
#include "tbl/req_flags.h"
918
919
/*--------------------------------------------------------------------*/
920
921
#define GIP(fld)                                                \
922
        VCL_IP                                                  \
923
        VRT_r_##fld##_ip(VRT_CTX)                               \
924
        {                                                       \
925
                struct suckaddr *sa;                            \
926
                                                                \
927
                CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
928
                CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
929
                AZ(SES_Get_##fld##_addr(ctx->sp, &sa));         \
930
                return (sa);                                    \
931
        }
932
933 1408
GIP(local)
934 1448
GIP(remote)
935 3207
GIP(client)
936 6907
GIP(server)
937
#undef GIP
938
939
/*--------------------------------------------------------------------
940
 * local.[endpoint|socket]
941
 */
942
943
#define LOC(var,fld)                                            \
944
VCL_STRING                                                      \
945
VRT_r_local_##var(VRT_CTX)                                      \
946
{                                                               \
947
        struct sess *sp;                                        \
948
                                                                \
949
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
950
        if (ctx->req) {                                         \
951
                CHECK_OBJ(ctx->req, REQ_MAGIC);                 \
952
                sp = ctx->req->sp;                              \
953
        } else {                                                \
954
                CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);      \
955
                sp = ctx->bo->sp;                               \
956
        }                                                       \
957
                                                                \
958
        CHECK_OBJ_NOTNULL(sp->listen_sock, LISTEN_SOCK_MAGIC);  \
959
        AN(sp->listen_sock->fld);                               \
960
        return (sp->listen_sock->fld);                          \
961
}
962
963 280
LOC(endpoint, endpoint)
964 280
LOC(socket, name)
965
#undef LOC
966
967
/*--------------------------------------------------------------------*/
968
969
VCL_STRING
970 400
VRT_r_server_identity(VRT_CTX)
971
{
972
973 400
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
974 400
        if (heritage.identity != NULL)
975 400
                return (heritage.identity);
976
        else
977 0
                return ("varnishd");
978 400
}
979
980
VCL_STRING
981 120
VRT_r_server_hostname(VRT_CTX)
982
{
983
984 120
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
985 120
        if (vrt_hostname[0] == '\0')
986 80
                AZ(gethostname(vrt_hostname, sizeof(vrt_hostname)));
987 120
        return (vrt_hostname);
988
}
989
990
/*--------------------------------------------------------------------*/
991
992
VCL_INT
993 1200
VRT_r_obj_hits(VRT_CTX)
994
{
995 1200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
996 1200
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
997 1200
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
998 1200
        if (ctx->method == VCL_MET_HIT)
999 80
                return (ctx->req->objcore->hits);
1000 1120
        return (ctx->req->is_hit ? ctx->req->objcore->hits : 0);
1001 1200
}
1002
1003
VCL_BOOL
1004 280
VRT_r_obj_uncacheable(VRT_CTX)
1005
{
1006
1007 280
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1008 280
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1009 280
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1010 280
        return (ctx->req->objcore->flags & OC_F_HFM ? 1 : 0);
1011
}
1012
1013
/*--------------------------------------------------------------------*/
1014
1015
VCL_BOOL
1016 200
VRT_r_resp_is_streaming(VRT_CTX)
1017
{
1018 200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1019 200
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1020 200
        if (ctx->req->objcore == NULL)
1021 40
                return (0);     /* When called from vcl_synth */
1022 160
        CHECK_OBJ_NOTNULL(ctx->req->objcore, OBJCORE_MAGIC);
1023 160
        return (ctx->req->objcore->boc == NULL ? 0 : 1);
1024 200
}
1025
1026
/*--------------------------------------------------------------------*/
1027
1028
static inline int
1029 560
resp_filter_fixed(VRT_CTX, const char *s)
1030
{
1031 560
        if (ctx->req->vdp_filter_list == NULL)
1032 520
                return (0);
1033 40
        VRT_fail(ctx, "resp.filters are already fixed, %s is undefined", s);
1034 40
        return (1);
1035 560
}
1036
1037
VCL_VOID
1038 200
VRT_l_resp_do_esi(VRT_CTX, VCL_BOOL process_esi)
1039
{
1040
1041 200
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1042 200
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1043 200
        assert(ctx->syntax >= 41);
1044 200
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1045 40
                return;
1046 160
        ctx->req->disable_esi = !process_esi;
1047 200
}
1048
1049
VCL_BOOL
1050 360
VRT_r_resp_do_esi(VRT_CTX)
1051
{
1052
1053 360
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1054 360
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1055 360
        assert(ctx->syntax >= 41);
1056 360
        if (resp_filter_fixed(ctx, "resp.do_esi"))
1057 0
                return (0);
1058 360
        return (!ctx->req->disable_esi);
1059 360
}
1060
1061
/*--------------------------------------------------------------------*/
1062
1063
#define VRT_BODY_L(which)                                       \
1064
VCL_VOID                                                        \
1065
VRT_l_##which##_body(VRT_CTX, enum lbody_e type,                \
1066
    const char *str, VCL_BODY body)                             \
1067
{                                                               \
1068
        int n;                                                  \
1069
        struct vsb *vsb;                                        \
1070
        VCL_STRANDS s;                                          \
1071
        VCL_BLOB b;                                             \
1072
                                                                \
1073
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1074
        AN(body);                                               \
1075
        CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);        \
1076
        if (type == LBODY_SET_STRING || type == LBODY_SET_BLOB) \
1077
                VSB_clear(vsb);                                 \
1078
        if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) { \
1079
                AZ(str);                                        \
1080
                b = body;                                       \
1081
                VSB_bcat(vsb, b->blob, b->len);                 \
1082
                return;                                         \
1083
        }                                                       \
1084
        if (str != NULL)                                        \
1085
                VSB_cat(vsb, str);                              \
1086
        assert(type == LBODY_SET_STRING ||                      \
1087
            type == LBODY_ADD_STRING);                          \
1088
        s = body;                                               \
1089
        for (n = 0; s != NULL && n < s->n; n++)                 \
1090
                if (s->p[n] != NULL)                            \
1091
                        VSB_cat(vsb, s->p[n]);                  \
1092
}
1093
1094 164055
VRT_BODY_L(beresp)
1095 257080
VRT_BODY_L(resp)
1096
1097
/*--------------------------------------------------------------------*/
1098
1099
                        /* digest */
1100
#define BLOB_HASH_TYPE 0x00d16357
1101
1102
VCL_BLOB
1103 160
VRT_r_req_hash(VRT_CTX)
1104
{
1105 160
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1106 160
        CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
1107 160
        return (VRT_blob(ctx, "req.hash", ctx->req->digest, DIGEST_LEN,
1108
            BLOB_HASH_TYPE));
1109
}
1110
1111
VCL_BLOB
1112 480
VRT_r_bereq_hash(VRT_CTX)
1113
{
1114 480
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
1115 480
        CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
1116 480
        return (VRT_blob(ctx, "bereq.hash", ctx->bo->digest, DIGEST_LEN,
1117
            BLOB_HASH_TYPE));
1118
}
1119
1120
/*--------------------------------------------------------------------*/
1121
1122
#define HTTP_VAR(x)                                             \
1123
VCL_HTTP                                                        \
1124
VRT_r_##x(VRT_CTX)                                              \
1125
{                                                               \
1126
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);                  \
1127
        CHECK_OBJ_NOTNULL(ctx->http_##x, HTTP_MAGIC);           \
1128
        return (ctx->http_##x);                                 \
1129
}
1130
1131 600
HTTP_VAR(req)
1132 40
HTTP_VAR(resp)
1133 360
HTTP_VAR(bereq)
1134 0
HTTP_VAR(beresp)
1135
1136
/*--------------------------------------------------------------------*/
1137
1138
static inline void
1139 120
set_idle_send_timeout(const struct sess *sp, VCL_DURATION d)
1140
{
1141 120
        struct timeval tv = VTIM_timeval_sock(d);
1142 120
        VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO,
1143
            &tv, sizeof tv));
1144 120
}
1145
1146
#define SESS_VAR_DUR(x, setter)                         \
1147
VCL_VOID                                                \
1148
VRT_l_sess_##x(VRT_CTX, VCL_DURATION d)                 \
1149
{                                                       \
1150
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1151
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1152
        d = vmax(d, 0.0);                               \
1153
        setter;                                         \
1154
        ctx->sp->x = d;                                 \
1155
}                                                       \
1156
                                                        \
1157
VCL_DURATION                                            \
1158
VRT_r_sess_##x(VRT_CTX)                                 \
1159
{                                                       \
1160
        vtim_dur res;                                   \
1161
                                                        \
1162
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1163
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1164
        res = SESS_TMO(ctx->sp, x);                     \
1165
        return (VRT_TMO(res));                          \
1166
}                                                       \
1167
                                                        \
1168
VCL_VOID                                                \
1169
VRT_u_sess_##x(VRT_CTX)                                 \
1170
{                                                       \
1171
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);          \
1172
        CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC);         \
1173
        ctx->sp->x = NAN;                               \
1174
}
1175
1176 320
SESS_VAR_DUR(timeout_idle, )
1177 440
SESS_VAR_DUR(timeout_linger, )
1178 280
SESS_VAR_DUR(send_timeout, )
1179 320
SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d))