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