varnish-cache/bin/varnishd/cache/cache_fetch.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
31
#include "config.h"
32
33
#include "cache_varnishd.h"
34
#include "cache_filter.h"
35
#include "cache_objhead.h"
36
#include "storage/storage.h"
37
#include "vcl.h"
38
#include "vtim.h"
39
#include "vcc_interface.h"
40
41
#define FETCH_STEPS \
42
        FETCH_STEP(mkbereq,           MKBEREQ) \
43
        FETCH_STEP(retry,             RETRY) \
44
        FETCH_STEP(startfetch,        STARTFETCH) \
45
        FETCH_STEP(condfetch,         CONDFETCH) \
46
        FETCH_STEP(fetch,             FETCH) \
47
        FETCH_STEP(fetchbody,         FETCHBODY) \
48
        FETCH_STEP(fetchend,          FETCHEND) \
49
        FETCH_STEP(error,             ERROR) \
50
        FETCH_STEP(fail,              FAIL) \
51
        FETCH_STEP(done,              DONE)
52
53
typedef const struct fetch_step *vbf_state_f(struct worker *, struct busyobj *);
54
55
struct fetch_step {
56
        const char      *name;
57
        vbf_state_f     *func;
58 74916
};
59 74916
60 74916
#define FETCH_STEP(l, U) \
61 74916
    static vbf_state_f vbf_stp_##l; \
62
    static const struct fetch_step F_STP_##U[1] = {{ .name = "Fetch Step " #l, .func = vbf_stp_##l, }};
63
FETCH_STEPS
64
#undef FETCH_STEP
65
66
static hdr_t const H_X_Varnish = HDR("X-Varnish");
67
68
/*--------------------------------------------------------------------
69
 * Allocate an object, with fall-back to Transient.
70
 * XXX: This somewhat overlaps the stuff in stevedore.c
71
 * XXX: Should this be merged over there ?
72
 */
73
74
static int
75 90999
vbf_allocobj(struct busyobj *bo, unsigned l)
76
{
77
        struct objcore *oc;
78
        const struct stevedore *stv;
79
        vtim_dur lifetime;
80
81 90999
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
82 90999
        oc = bo->fetch_objcore;
83 90999
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
84
85 90999
        lifetime = oc->ttl + oc->grace + oc->keep;
86
87 90999
        if (bo->uncacheable) {
88 35960
                stv = stv_transient;
89 35960
                bo->wrk->stats->beresp_uncacheable++;
90 35960
        }
91 55039
        else if (lifetime < cache_param->shortlived) {
92 5080
                stv = stv_transient;
93 5080
                bo->wrk->stats->beresp_shortlived++;
94 5080
        }
95
        else
96 49959
                stv = bo->storage;
97
98 90999
        bo->storage = NULL;
99
100 90999
        if (stv == NULL)
101 40
                return (0);
102
103 90959
        if (STV_NewObject(bo->wrk, oc, stv, l))
104 90679
                return (1);
105
106 280
        if (stv == stv_transient)
107 160
                return (0);
108
109
        /*
110
         * Try to salvage the transaction by allocating a shortlived object
111
         * on Transient storage.
112
         */
113
114 120
        oc->ttl = vmin_t(float, oc->ttl, cache_param->shortlived);
115 120
        oc->grace = 0.0;
116 120
        oc->keep = 0.0;
117 120
        return (STV_NewObject(bo->wrk, oc, stv_transient, l));
118 90999
}
119
120
static void
121 81915
vbf_cleanup(struct busyobj *bo)
122
{
123
        struct vfp_ctx *vfc;
124
125 81915
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
126 81915
        vfc = bo->vfc;
127 81915
        CHECK_OBJ_NOTNULL(vfc, VFP_CTX_MAGIC);
128
129 81915
        bo->acct.beresp_bodybytes += VFP_Close(vfc);
130 81915
        bo->vfp_filter_list = NULL;
131
132 81915
        if (bo->director_state != DIR_S_NULL)
133 81593
                VDI_Finish(bo);
134 81915
}
135
136
void
137 360
Bereq_Rollback(VRT_CTX)
138
{
139
        struct busyobj *bo;
140
141 360
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
142 360
        bo = ctx->bo;
143 360
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
144
145 360
        if (bo->htc != NULL) {
146 320
                assert(bo->htc->body_status != BS_TAKEN);
147 320
                if (bo->htc->body_status != BS_NONE)
148 40
                        bo->htc->doclose = SC_RESP_CLOSE;
149 320
        }
150
151 360
        vbf_cleanup(bo);
152 360
        VCL_TaskLeave(ctx, bo->privs);
153 360
        VCL_TaskEnter(bo->privs);
154 360
        HTTP_Clone(bo->bereq, bo->bereq0);
155 360
        bo->vfp_filter_list = NULL;
156 360
        bo->err_reason = NULL;
157 360
        AN(bo->ws_bo);
158 360
        WS_Rollback(bo->ws, bo->ws_bo);
159 360
}
160
161
/*--------------------------------------------------------------------
162
 * Turn the beresp into a obj
163
 */
164
165
static int
166 90996
vbf_beresp2obj(struct busyobj *bo)
167
{
168
        unsigned l, l2;
169
        const char *b;
170
        uint8_t *bp;
171 90996
        struct vsb *vary = NULL;
172 90996
        int varyl = 0;
173
        struct objcore *oc;
174
175 90996
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
176 90996
        oc = bo->fetch_objcore;
177 90996
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
178
179 90996
        l = 0;
180
181
        /* Create Vary instructions */
182 90996
        if (!(oc->flags & OC_F_PRIVATE)) {
183 59119
                varyl = VRY_Create(bo, &vary);
184 59119
                if (varyl > 0) {
185 8600
                        AN(vary);
186 8600
                        assert(varyl == VSB_len(vary));
187 8600
                        l += PRNDUP((intptr_t)varyl);
188 59119
                } else if (varyl < 0) {
189
                        /*
190
                         * Vary parse error
191
                         * Complain about it, and make this a pass.
192
                         */
193 200
                        VSLb(bo->vsl, SLT_Error,
194
                            "Illegal 'Vary' header from backend, "
195
                            "making this a pass.");
196 200
                        bo->uncacheable = 1;
197 200
                        AZ(vary);
198 200
                } else
199
                        /* No vary */
200 50319
                        AZ(vary);
201 59119
        }
202
203 181992
        l2 = http_EstimateWS(bo->beresp,
204 90996
            bo->uncacheable ? HTTPH_A_PASS : HTTPH_A_INS);
205 90996
        l += l2;
206
207 90996
        if (bo->uncacheable)
208 35948
                oc->flags |= OC_F_HFM;
209
210 90996
        if (!vbf_allocobj(bo, l)) {
211 240
                if (vary != NULL)
212 0
                        VSB_destroy(&vary);
213 240
                AZ(vary);
214 240
                return (VFP_Error(bo->vfc, "Could not get storage"));
215
        }
216
217 90756
        if (vary != NULL) {
218 8600
                AN(ObjSetAttr(bo->wrk, oc, OA_VARY, varyl, VSB_data(vary)));
219 8600
                VSB_destroy(&vary);
220 8600
        }
221
222 90756
        AZ(ObjSetXID(bo->wrk, oc, bo->vsl->wid));
223
224
        /* for HTTP_Encode() VSLH call */
225 90756
        bo->beresp->logtag = SLT_ObjMethod;
226
227
        /* Filter into object */
228 90756
        bp = ObjSetAttr(bo->wrk, oc, OA_HEADERS, l2, NULL);
229 90756
        AN(bp);
230 181512
        HTTP_Encode(bo->beresp, bp, l2,
231 90756
            bo->uncacheable ? HTTPH_A_PASS : HTTPH_A_INS);
232
233 90756
        if (http_GetHdr(bo->beresp, H_Last_Modified, &b))
234 1720
                AZ(ObjSetDouble(bo->wrk, oc, OA_LASTMODIFIED, VTIM_parse(b)));
235
        else
236 89036
                AZ(ObjSetDouble(bo->wrk, oc, OA_LASTMODIFIED,
237
                    floor(oc->t_origin)));
238
239 90756
        return (0);
240 90996
}
241
242
/*--------------------------------------------------------------------
243
 * Copy req->bereq and release req if no body
244
 */
245
246
static const struct fetch_step * v_matchproto_(vbf_state_f)
247 91918
vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo)
248
{
249
        const char *q;
250
        struct objcore *oc;
251
252 91918
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
253 91918
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
254 91918
        CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);
255 91918
        oc = bo->fetch_objcore;
256 91918
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
257
258 91918
        assert(oc->boc->state == BOS_INVALID);
259 91918
        AZ(bo->storage);
260
261 91918
        HTTP_Setup(bo->bereq0, bo->ws, bo->vsl, SLT_BereqMethod);
262 183836
        http_FilterReq(bo->bereq0, bo->req->http,
263 91918
            bo->uncacheable ? HTTPH_R_PASS : HTTPH_R_FETCH);
264
265 91918
        if (bo->uncacheable)
266 31838
                AZ(bo->stale_oc);
267
        else {
268 60080
                http_ForceField(bo->bereq0, HTTP_HDR_METHOD, "GET");
269 60080
                if (cache_param->http_gzip_support)
270 59880
                        http_ForceHeader(bo->bereq0, H_Accept_Encoding, "gzip");
271
        }
272 91918
        http_ForceField(bo->bereq0, HTTP_HDR_PROTO, "HTTP/1.1");
273
274 93438
        if (bo->stale_oc != NULL && !(bo->stale_oc->flags & OC_F_DYING) &&
275 6280
            ObjCheckFlag(bo->wrk, bo->stale_oc, OF_IMSCAND) &&
276 1680
            (bo->stale_oc->boc != NULL || ObjGetLen(wrk, bo->stale_oc) != 0)) {
277 1600
                AZ(bo->stale_oc->flags & (OC_F_HFM|OC_F_PRIVATE));
278 1600
                q = RFC2616_Strong_LM(NULL, wrk, bo->stale_oc);
279 1600
                if (q != NULL)
280 1040
                        http_PrintfHeader(bo->bereq0,
281 520
                            "If-Modified-Since: %s", q);
282 1600
                q = HTTP_GetHdrPack(bo->wrk, bo->stale_oc, H_ETag);
283 1600
                if (q != NULL)
284 2240
                        http_PrintfHeader(bo->bereq0,
285 1120
                            "If-None-Match: %s", q);
286 1600
        }
287
288 91918
        http_CopyHome(bo->bereq0);
289 91918
        HTTP_Setup(bo->bereq, bo->ws, bo->vsl, SLT_BereqMethod);
290 91918
        bo->ws_bo = WS_Snapshot(bo->ws);
291 91918
        HTTP_Clone(bo->bereq, bo->bereq0);
292
293 91918
        if (bo->req->req_body_status->avail == 0) {
294 88158
                VBO_SetState(bo->wrk, bo, BOS_REQ_DONE);
295 91918
        } else if (bo->req->req_body_status == BS_CACHED) {
296 920
                AN(bo->req->body_oc);
297 920
                bo->bereq_body = bo->req->body_oc;
298 920
                HSH_Ref(bo->bereq_body);
299 920
                VBO_SetState(bo->wrk, bo, BOS_REQ_DONE);
300 920
        }
301 91918
        return (F_STP_STARTFETCH);
302
}
303
304
/*--------------------------------------------------------------------
305
 * Start a new VSL transaction and try again
306
 * Prepare the busyobj and fetch processors
307
 */
308
309
static const struct fetch_step * v_matchproto_(vbf_state_f)
310 1560
vbf_stp_retry(struct worker *wrk, struct busyobj *bo)
311
{
312 1560
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
313 1560
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
314
315 1560
        assert(bo->fetch_objcore->boc->state <= BOS_REQ_DONE);
316
317 1560
        if (bo->no_retry != NULL && bo->no_retry != retry_disabled) {
318 160
                VSLb(bo->vsl, SLT_Error,
319 80
                    "Retry not possible, %s", bo->no_retry);
320 80
                return (F_STP_FAIL);
321
        }
322
323 1480
        VSLb_ts_busyobj(bo, "Retry", W_TIM_real(wrk));
324
325
        /* VDI_Finish (via vbf_cleanup) must have been called before */
326 1480
        assert(bo->director_state == DIR_S_NULL);
327
328
        /* reset other bo attributes - See VBO_GetBusyObj */
329 1480
        bo->storage = NULL;
330 1480
        bo->do_esi = 0;
331 1480
        bo->do_stream = 1;
332 1480
        bo->was_304 = 0;
333 1480
        bo->err_code = 0;
334 1480
        bo->err_reason = NULL;
335 1480
        bo->connect_timeout = NAN;
336 1480
        bo->first_byte_timeout = NAN;
337 1480
        bo->between_bytes_timeout = NAN;
338 1480
        if (bo->htc != NULL)
339 0
                bo->htc->doclose = SC_NULL;
340
341
        // XXX: BereqEnd + BereqAcct ?
342 1480
        VSL_ChgId(bo->vsl, "bereq", "retry", VXID_Get(wrk, VSL_BACKENDMARKER));
343 1480
        VSLb_ts_busyobj(bo, "Start", bo->t_prev);
344 1480
        http_VSL_log(bo->bereq);
345
346 1480
        return (F_STP_STARTFETCH);
347 1560
}
348
349
/*--------------------------------------------------------------------
350
 * 304 setup logic
351
 */
352
353
static void
354 1280
vbf_304_logic(struct busyobj *bo)
355
{
356
357 1280
        AZ(bo->stale_oc->flags & (OC_F_HFM|OC_F_PRIVATE));
358 1280
        if (ObjCheckFlag(bo->wrk, bo->stale_oc, OF_CHGCE)) {
359
                /*
360
                 * If a VFP changed C-E in the stored
361
                 * object, then don't overwrite C-E from
362
                 * the IMS fetch, and we must weaken any
363
                 * new ETag we get.
364
                 */
365 80
                RFC2616_Weaken_Etag(bo->beresp);
366 80
        }
367 1280
        http_Unset(bo->beresp, H_Content_Encoding);
368 1280
        http_Unset(bo->beresp, H_Content_Length);
369 1280
        HTTP_Merge(bo->wrk, bo->stale_oc, bo->beresp);
370 1280
}
371
372
/*--------------------------------------------------------------------
373
 * Setup bereq from bereq0, run vcl_backend_fetch
374
 */
375
376
static const struct fetch_step * v_matchproto_(vbf_state_f)
377 93397
vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
378
{
379
        int i;
380
        const char *q;
381
        vtim_real now;
382 93397
        unsigned handling, skip_vbr = 0;
383
        struct objcore *oc;
384
385 93397
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
386 93397
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
387 93397
        oc = bo->fetch_objcore;
388 93397
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
389
390
        // this complements the stale_oc handling in vbf_stp_mkbereq():
391
        // Conditions might have changed since we made the bereq (retry)
392 93397
        if (! bo->uncacheable && bo->stale_oc != NULL &&
393 6399
            bo->stale_oc->flags & OC_F_DYING) {
394 80
                http_Unset(bo->bereq, H_If_Modified_Since);
395 80
                http_Unset(bo->bereq, H_If_None_Match);
396 80
        }
397
398 93397
        AZ(bo->storage);
399 93397
        bo->storage = bo->uncacheable ? stv_transient : STV_next();
400
401 93397
        if (bo->retries > 0)
402 1480
                http_Unset(bo->bereq, H_X_Varnish);
403
404 93397
        http_PrintfHeader(bo->bereq, "X-Varnish: %ju", VXID(bo->vsl->wid));
405
406 93397
        if (bo->bereq_body == NULL && bo->req == NULL) {
407 89637
                if (http_method_among(bo->bereq->wkm, (WKM_GET | WKM_HEAD | WKM_DELETE |
408
                    WKM_OPTIONS | WKM_TRACE)))
409 88837
                        http_Unset(bo->bereq, H_Content_Length);
410
                else
411 800
                        http_ForceHeader(bo->bereq, H_Content_Length, "0");
412 89637
        }
413
414 93397
        VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, NULL);
415
416 93397
        if (wrk->vpi->handling == VCL_RET_ABANDON ||
417 93276
            wrk->vpi->handling == VCL_RET_FAIL)
418 276
                return (F_STP_FAIL);
419
420 93121
        assert (wrk->vpi->handling == VCL_RET_FETCH ||
421
            wrk->vpi->handling == VCL_RET_ERROR);
422
423 93121
        HTTP_Setup(bo->beresp, bo->ws, bo->vsl, SLT_BerespMethod);
424
425 93121
        assert(oc->boc->state <= BOS_REQ_DONE);
426
427 93121
        AZ(bo->htc);
428
429 93121
        VFP_Setup(bo->vfc, wrk);
430 93121
        bo->vfc->oc = oc;
431 93121
        bo->vfc->resp = bo->beresp;
432 93121
        bo->vfc->req = bo->bereq;
433
434 93121
        if (wrk->vpi->handling == VCL_RET_ERROR)
435 440
                return (F_STP_ERROR);
436
437 92681
        VSLb_ts_busyobj(bo, "Fetch", W_TIM_real(wrk));
438 92681
        i = VDI_GetHdr(bo);
439 92681
        if (bo->htc != NULL)
440 81878
                CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC);
441
442 92681
        bo->t_resp = now = W_TIM_real(wrk);
443 92681
        VSLb_ts_busyobj(bo, "Beresp", now);
444
445 92681
        if (i) {
446 10758
                assert(bo->director_state == DIR_S_NULL);
447 10758
                return (F_STP_ERROR);
448
        }
449
450 81923
        if (bo->htc != NULL && bo->htc->body_status == BS_ERROR) {
451 240
                bo->htc->doclose = SC_RX_BODY;
452 240
                vbf_cleanup(bo);
453 240
                VSLb(bo->vsl, SLT_Error, "Body cannot be fetched");
454 240
                assert(bo->director_state == DIR_S_NULL);
455 240
                return (F_STP_ERROR);
456
        }
457
458 81683
        if (!http_GetHdr(bo->beresp, H_Date, NULL)) {
459
                /*
460
                 * RFC 2616 14.18 Date: The Date general-header field
461
                 * represents the date and time at which the message was
462
                 * originated, having the same semantics as orig-date in
463
                 * RFC 822. ... A received message that does not have a
464
                 * Date header field MUST be assigned one by the recipient
465
                 * if the message will be cached by that recipient or
466
                 * gatewayed via a protocol which requires a Date.
467
                 *
468
                 * If we didn't get a Date header, we assign one here.
469
                 */
470 3320
                http_TimeHeader(bo->beresp, "Date: ", now);
471 3320
        }
472
473
        /*
474
         * These two headers can be spread over multiple actual headers
475
         * and we rely on their content outside of VCL, so collect them
476
         * into one line here.
477
         */
478 81681
        http_CollectHdr(bo->beresp, H_Cache_Control);
479 81681
        http_CollectHdr(bo->beresp, H_Vary);
480
481
        /* What does RFC2616 think about TTL ? */
482 163362
        RFC2616_Ttl(bo, now,
483 81681
            &oc->t_origin,
484 81681
            &oc->ttl,
485 81681
            &oc->grace,
486 81681
            &oc->keep);
487
488 81681
        AZ(bo->do_esi);
489 81681
        AZ(bo->was_304);
490
491 81681
        if (http_IsStatus(bo->beresp, 304) && !bo->uncacheable) {
492 1640
                if (bo->stale_oc == NULL){
493 0
                        VSLb(bo->vsl, SLT_Error,
494
                            "304 response but not conditional fetch");
495 0
                        bo->htc->doclose = SC_RX_BAD;
496 0
                        vbf_cleanup(bo);
497 0
                        return (F_STP_ERROR);
498
                }
499 1640
                bo->was_304 = 1;
500 1640
                VCL_backend_refresh_method(bo->vcl, wrk, NULL, bo, NULL);
501 1640
                switch (wrk->vpi->handling) {
502
                case VCL_RET_MERGE:
503 1280
                        vbf_304_logic(bo);
504 1280
                        break;
505
                case VCL_RET_BERESP:
506 80
                        http_SetStatus(bo->beresp, 200, NULL);
507 80
                        http_Unset(bo->beresp, H_Content_Length);
508 80
                        http_Unset(bo->beresp, H_Content_Encoding);
509 160
                        q = HTTP_GetHdrPack(wrk, bo->stale_oc,
510 80
                            H_Content_Length);
511 80
                        if (q != NULL) {
512 80
                                http_ForceHeader(bo->beresp,
513 40
                                    H_Content_Length, q);
514 40
                        }
515 160
                        q = HTTP_GetHdrPack(wrk, bo->stale_oc,
516 80
                            H_Content_Encoding);
517 80
                        if (q != NULL) {
518 0
                                http_ForceHeader(bo->beresp,
519 0
                                    H_Content_Encoding, q);
520 0
                        }
521 160
                        q = HTTP_GetHdrPack(wrk, bo->stale_oc,
522 80
                            H_Last_Modified);
523 80
                        if (q != NULL) {
524 0
                                http_ForceHeader(bo->beresp,
525 0
                                    H_Last_Modified, q);
526 0
                        }
527 80
                        q = HTTP_GetHdrPack(wrk, bo->stale_oc, H_ETag);
528 80
                        if (q != NULL)
529 80
                                http_ForceHeader(bo->beresp, H_ETag, q);
530 80
                        break;
531
                case VCL_RET_OBJ_STALE:
532 80
                        if (HTTP_Decode(bo->beresp, ObjGetAttr(bo->wrk,
533 40
                                bo->stale_oc, OA_HEADERS, NULL))) {
534 0
                                bo->htc->doclose = SC_RX_OVERFLOW;
535 0
                                vbf_cleanup(bo);
536 0
                                return (F_STP_ERROR);
537
                        }
538 40
                        break;
539
                case VCL_RET_RETRY:
540
                case VCL_RET_ERROR:
541
                case VCL_RET_ABANDON:
542
                case VCL_RET_FAIL:
543 240
                        skip_vbr = 1;
544 240
                        break;
545
                default:
546 0
                        WRONG("Illegal return from vcl_backend_refresh{}");
547 0
                }
548 1640
        }
549
550 81681
        if (bo->htc != NULL && bo->htc->doclose == SC_NULL &&
551 77992
            http_GetHdrField(bo->bereq, H_Connection, "close", NULL))
552 520
                bo->htc->doclose = SC_REQ_CLOSE;
553 81681
        if (!skip_vbr)
554 81398
                VCL_backend_response_method(bo->vcl, wrk, NULL, bo, NULL);
555
556 81597
        if (bo->htc != NULL && bo->htc->doclose == SC_NULL &&
557 77113
            http_GetHdrField(bo->beresp, H_Connection, "close", NULL))
558 40
                bo->htc->doclose = SC_RESP_CLOSE;
559
560 81597
        if (VRG_CheckBo(bo) < 0) {
561 280
                if (bo->director_state != DIR_S_NULL)
562 240
                        VDI_Finish(bo);
563 280
                return (F_STP_ERROR);
564
        }
565
566 162430
        if (wrk->vpi->handling == VCL_RET_ABANDON ||
567 81193
            wrk->vpi->handling == VCL_RET_FAIL ||
568 81113
            wrk->vpi->handling == VCL_RET_ERROR) {
569
                /* do not count deliberately ending the backend connection as
570
                 * fetch failure
571
                 */
572 600
                handling = wrk->vpi->handling;
573 600
                if (bo->htc)
574 600
                        bo->htc->doclose = SC_RESP_CLOSE;
575 600
                vbf_cleanup(bo);
576 600
                wrk->vpi->handling = handling;
577
578 600
                if (wrk->vpi->handling == VCL_RET_ERROR)
579 400
                        return (F_STP_ERROR);
580
                else
581 200
                        return (F_STP_FAIL);
582
        }
583
584 80717
        if (wrk->vpi->handling == VCL_RET_RETRY) {
585 1160
                if (bo->htc && bo->htc->body_status != BS_NONE)
586 280
                        bo->htc->doclose = SC_RESP_CLOSE;
587 1160
                vbf_cleanup(bo);
588
589 1160
                if (bo->retries++ < bo->max_retries)
590 1080
                        return (F_STP_RETRY);
591
592 80
                VSLb(bo->vsl, SLT_VCL_Error,
593
                    "Too many retries, delivering 503");
594 80
                assert(bo->director_state == DIR_S_NULL);
595 80
                return (F_STP_ERROR);
596
        }
597
598 79557
        VSLb_ts_busyobj(bo, "Process", W_TIM_real(wrk));
599 79557
        assert(oc->boc->state <= BOS_REQ_DONE);
600 79557
        if (oc->boc->state != BOS_REQ_DONE)
601 1640
                VBO_SetState(wrk, bo, BOS_REQ_DONE);
602
603 79557
        if (bo->do_esi)
604 12400
                bo->do_stream = 0;
605 79557
        if (wrk->vpi->handling == VCL_RET_PASS) {
606 880
                oc->flags |= OC_F_HFP;
607 880
                bo->uncacheable = 1;
608 880
                wrk->vpi->handling = VCL_RET_DELIVER;
609 880
        }
610 79557
        if (!bo->uncacheable || !bo->do_stream)
611 54960
                oc->boc->transit_buffer = 0;
612 79557
        if (bo->uncacheable)
613 30117
                oc->flags |= OC_F_HFM;
614
615 79557
        assert(wrk->vpi->handling == VCL_RET_DELIVER);
616
617 79557
        return (bo->was_304 ? F_STP_CONDFETCH : F_STP_FETCH);
618 93311
}
619
620
/*--------------------------------------------------------------------
621
 */
622
623
static const struct fetch_step * v_matchproto_(vbf_state_f)
624 44570
vbf_stp_fetchbody(struct worker *wrk, struct busyobj *bo)
625
{
626
        ssize_t l;
627
        uint8_t *ptr;
628 44570
        enum vfp_status vfps = VFP_ERROR;
629
        ssize_t est;
630
        struct vfp_ctx *vfc;
631
        struct objcore *oc;
632
633 44570
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
634 44570
        vfc = bo->vfc;
635 44570
        CHECK_OBJ_NOTNULL(vfc, VFP_CTX_MAGIC);
636 44570
        oc = bo->fetch_objcore;
637 44570
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
638
639 44570
        AN(vfc->vfp_nxt);
640
641 44570
        est = bo->htc->content_length;
642 44570
        if (est < 0)
643 5960
                est = 0;
644
645 44570
        do {
646 2238662
                if (oc->flags & OC_F_CANCEL) {
647
                        /*
648
                         * A pass object and delivery was terminated
649
                         * We don't fail the fetch, in order for HitMiss
650
                         * objects to be created.
651
                         */
652 111
                        AN(oc->flags & OC_F_HFM);
653 111
                        VSLb(wrk->vsl, SLT_Debug,
654
                            "Fetch: Pass delivery abandoned");
655 111
                        bo->htc->doclose = SC_RX_BODY;
656 111
                        break;
657
                }
658 2238551
                AZ(vfc->failed);
659 2238551
                l = est;
660 2238551
                assert(l >= 0);
661 2238551
                if (VFP_GetStorage(vfc, &l, &ptr) != VFP_OK) {
662 199
                        bo->htc->doclose = SC_RX_BODY;
663 199
                        break;
664
                }
665
666 2238352
                AZ(vfc->failed);
667 2238352
                vfps = VFP_Suck(vfc, ptr, &l);
668 2238352
                if (l >= 0 && vfps != VFP_ERROR) {
669 2237058
                        VFP_Extend(vfc, l, vfps);
670 2237058
                        if (est >= l)
671 113537
                                est -= l;
672
                        else
673 2123521
                                est = 0;
674 2237058
                }
675 2238352
        } while (vfps == VFP_OK);
676
677 44554
        if (vfc->failed) {
678 1479
                (void)VFP_Error(vfc, "Fetch pipeline failed to process");
679 1479
                bo->htc->doclose = SC_RX_BODY;
680 1479
                vbf_cleanup(bo);
681 1479
                if (!bo->do_stream) {
682 840
                        assert(oc->boc->state < BOS_STREAM);
683
                        // XXX: doclose = ?
684 840
                        return (F_STP_ERROR);
685
                } else {
686 639
                        wrk->stats->fetch_failed++;
687 639
                        return (F_STP_FAIL);
688
                }
689
        }
690
691 43075
        return (F_STP_FETCHEND);
692 44554
}
693
694
static const struct fetch_step * v_matchproto_(vbf_state_f)
695 78196
vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
696
{
697
        struct vrt_ctx ctx[1];
698
        struct objcore *oc;
699
700 78196
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
701 78196
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
702 78196
        oc = bo->fetch_objcore;
703 78196
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
704
705 78196
        assert(wrk->vpi->handling == VCL_RET_DELIVER);
706
707 78196
        if (bo->htc == NULL) {
708 80
                (void)VFP_Error(bo->vfc, "No backend connection (rollback?)");
709 80
                vbf_cleanup(bo);
710 80
                return (F_STP_ERROR);
711
        }
712
713
        /* No body -> done */
714 78116
        if (bo->htc->body_status == BS_NONE || bo->htc->content_length == 0) {
715 30440
                http_Unset(bo->beresp, H_Content_Encoding);
716 30440
                bo->do_gzip = bo->do_gunzip = 0;
717 30440
                bo->do_stream = 0;
718 30440
                bo->vfp_filter_list = "";
719 78118
        } else if (bo->vfp_filter_list == NULL) {
720 47439
                bo->vfp_filter_list = VBF_Get_Filter_List(bo);
721 47439
        }
722
723 78118
        if (bo->vfp_filter_list == NULL ||
724 78119
            VCL_StackVFP(bo->vfc, bo->vcl, bo->vfp_filter_list)) {
725 964
                (bo)->htc->doclose = SC_OVERLOAD;
726 964
                vbf_cleanup(bo);
727 964
                return (F_STP_ERROR);
728
        }
729
730 77156
        if (oc->flags & OC_F_PRIVATE)
731 25437
                AN(bo->uncacheable);
732
733 77156
        oc->boc->fetched_so_far = 0;
734
735 77156
        INIT_OBJ(ctx, VRT_CTX_MAGIC);
736 77156
        VCL_Bo2Ctx(ctx, bo);
737
738 77156
        if (VFP_Open(ctx, bo->vfc)) {
739 2120
                (void)VFP_Error(bo->vfc, "Fetch pipeline failed to open");
740 2120
                bo->htc->doclose = SC_RX_BODY;
741 2120
                vbf_cleanup(bo);
742 2120
                return (F_STP_ERROR);
743
        }
744
745 75036
        if (vbf_beresp2obj(bo)) {
746 120
                bo->htc->doclose = SC_RX_BODY;
747 120
                vbf_cleanup(bo);
748 120
                return (F_STP_ERROR);
749
        }
750
751
#define OBJ_FLAG(U, l, v)                                               \
752
        if (bo->vfc->obj_flags & OF_##U)                                \
753
                ObjSetFlag(bo->wrk, oc, OF_##U, 1);
754
#include "tbl/obj_attr.h"
755
756 74916
        if (!(oc->flags & OC_F_HFM) &&
757 47760
            http_IsStatus(bo->beresp, 200) && (
758 46960
              RFC2616_Strong_LM(bo->beresp, NULL, NULL) != NULL ||
759 46005
              http_GetHdr(bo->beresp, H_ETag, NULL)))
760 2435
                ObjSetFlag(bo->wrk, oc, OF_IMSCAND, 1);
761
762 74916
        assert(oc->boc->refcount >= 1);
763
764 74916
        assert(oc->boc->state == BOS_REQ_DONE);
765
766 74916
        if (bo->do_stream)
767 33315
                VBO_SetState(wrk, bo, BOS_STREAM);
768
769
        VSLb(bo->vsl, SLT_Fetch_Body, "%u %s %s",
770
            bo->htc->body_status->nbr, bo->htc->body_status->name,
771
            bo->do_stream ? "stream" : "-");
772
773 74916
        if (bo->htc->body_status != BS_NONE) {
774 44556
                assert(bo->htc->body_status != BS_ERROR);
775 44556
                return (F_STP_FETCHBODY);
776
        }
777 30360
        AZ(bo->vfc->failed);
778
        return (F_STP_FETCHEND);
779
}
780
781
static const struct fetch_step * v_matchproto_(vbf_state_f)
782 74638
vbf_stp_fetchend(struct worker *wrk, struct busyobj *bo)
783
{
784
785
        struct objcore *oc;
786
787 74638
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
788 74638
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
789 74638
        oc = bo->fetch_objcore;
790 74638
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
791
792 74638
        AZ(bo->vfc->failed);
793
794
        /* Recycle the backend connection before setting BOS_FINISHED to
795
           give predictable backend reuse behavior for varnishtest */
796 74638
        vbf_cleanup(bo);
797
798 74638
        AZ(ObjSetU64(wrk, oc, OA_LEN, oc->boc->fetched_so_far));
799
800 74638
        if (bo->do_stream)
801 33838
                assert(oc->boc->state == BOS_STREAM);
802
        else
803 40800
                assert(oc->boc->state == BOS_REQ_DONE);
804
805 74638
        VBO_SetState(wrk, bo, BOS_FINISHED);
806 74638
        VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk));
807 74638
        if (bo->stale_oc != NULL) {
808 6400
                VSL(SLT_ExpKill, NO_VXID, "VBF_Superseded x=%ju n=%ju",
809 3200
                    VXID(ObjGetXID(wrk, bo->stale_oc)),
810 3200
                    VXID(ObjGetXID(wrk, bo->fetch_objcore)));
811 3200
                HSH_Replace(bo->stale_oc, bo->fetch_objcore);
812 3200
        }
813 74638
        return (F_STP_DONE);
814
}
815
816
/*--------------------------------------------------------------------
817
 */
818
819
struct vbf_objiter_priv {
820
        unsigned                magic;
821
#define VBF_OBITER_PRIV_MAGIC   0x3c272a17
822
        struct busyobj          *bo;
823
        // not yet allocated
824
        ssize_t         l;
825
        // current allocation
826
        uint8_t         *p;
827
        ssize_t         pl;
828
};
829
830
static int v_matchproto_(objiterate_f)
831 1360
vbf_objiterate(void *priv, unsigned flush, const void *ptr, ssize_t len)
832
{
833
        struct vbf_objiter_priv *vop;
834
        ssize_t l;
835 1360
        const uint8_t *ps = ptr;
836
837 1360
        CAST_OBJ_NOTNULL(vop, priv, VBF_OBITER_PRIV_MAGIC);
838 1360
        CHECK_OBJ_NOTNULL(vop->bo, BUSYOBJ_MAGIC);
839
840 1360
        flush &= OBJ_ITER_END;
841
842 2680
        while (len > 0) {
843 1360
                if (vop->pl == 0) {
844 1320
                        vop->p = NULL;
845 1320
                        AN(vop->l);
846 1320
                        vop->pl = vop->l;
847 2640
                        if (VFP_GetStorage(vop->bo->vfc, &vop->pl, &vop->p)
848 1320
                            != VFP_OK)
849 40
                                return (1);
850 1280
                        if (vop->pl < vop->l)
851 80
                                vop->l -= vop->pl;
852
                        else
853 1200
                                vop->l = 0;
854 1280
                }
855 1320
                AN(vop->pl);
856 1320
                AN(vop->p);
857
858 1320
                l = vmin(vop->pl, len);
859 1320
                memcpy(vop->p, ps, l);
860 2520
                VFP_Extend(vop->bo->vfc, l,
861 1320
                           flush && l == len ? VFP_END : VFP_OK);
862 1320
                ps += l;
863 1320
                vop->p += l;
864 1320
                len -= l;
865 1320
                vop->pl -= l;
866
        }
867 1320
        if (flush && vop->bo->vfc->failed == 0)
868 1200
                AZ(vop->l);
869 1320
        return (0);
870 1360
}
871
872
static const struct fetch_step * v_matchproto_(vbf_state_f)
873 1360
vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
874
{
875
        struct boc *stale_boc;
876
        enum boc_state_e stale_state;
877
        struct objcore *oc, *stale_oc;
878
        struct vbf_objiter_priv vop[1];
879
880 1360
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
881 1360
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
882 1360
        oc = bo->fetch_objcore;
883 1360
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
884 1360
        stale_oc = bo->stale_oc;
885 1360
        CHECK_OBJ_NOTNULL(stale_oc, OBJCORE_MAGIC);
886
887 1360
        stale_boc = HSH_RefBoc(stale_oc);
888 1360
        CHECK_OBJ_ORNULL(stale_boc, BOC_MAGIC);
889 1360
        if (stale_boc) {
890
                /* Wait for the stale object to become fully fetched, so
891
                 * that we can catch fetch errors, before we unbusy the
892
                 * new object. This serves two purposes. First it helps
893
                 * with request coalescing, and stops long chains of
894
                 * IMS-updated short-TTL objects all streaming from a
895
                 * single slow body fetch. Second it makes sure that all
896
                 * the object attributes are complete when we copy them
897
                 * (this would be an issue for ie OA_GZIPBITS). */
898 160
                VSLb(bo->vsl, SLT_Notice,
899
                    "vsl: Conditional fetch wait for streaming object");
900
                /* XXX: We should have a VCL controlled timeout here */
901 160
                stale_state = ObjWaitState(stale_oc, BOS_FINISHED);
902 160
                HSH_DerefBoc(bo->wrk, stale_oc);
903 160
                stale_boc = NULL;
904 160
                if (stale_state != BOS_FINISHED) {
905 80
                        assert(stale_state == BOS_FAILED);
906 80
                        AN(stale_oc->flags & OC_F_FAILED);
907 80
                }
908 160
        }
909
910 1360
        AZ(stale_boc);
911 1360
        if (stale_oc->flags & OC_F_FAILED) {
912 80
                (void)VFP_Error(bo->vfc, "Template object failed");
913 80
                vbf_cleanup(bo);
914 80
                wrk->stats->fetch_failed++;
915 80
                return (F_STP_FAIL);
916
        }
917
918 1280
        if (vbf_beresp2obj(bo)) {
919 40
                vbf_cleanup(bo);
920 40
                wrk->stats->fetch_failed++;
921 40
                return (F_STP_FAIL);
922
        }
923
924 1240
        if (ObjHasAttr(bo->wrk, stale_oc, OA_ESIDATA))
925 40
                AZ(ObjCopyAttr(bo->wrk, oc, stale_oc, OA_ESIDATA));
926
927 1240
        AZ(ObjCopyAttr(bo->wrk, oc, stale_oc, OA_FLAGS));
928 1240
        if (oc->flags & OC_F_HFM)
929 80
                ObjSetFlag(bo->wrk, oc, OF_IMSCAND, 0);
930 1240
        AZ(ObjCopyAttr(bo->wrk, oc, stale_oc, OA_GZIPBITS));
931
932 1240
        if (bo->do_stream)
933 1200
                VBO_SetState(wrk, bo, BOS_STREAM);
934
935 1240
        INIT_OBJ(vop, VBF_OBITER_PRIV_MAGIC);
936 1240
        vop->bo = bo;
937 1240
        vop->l = ObjGetLen(bo->wrk, stale_oc);
938 1240
        if (ObjIterate(wrk, stale_oc, vop, vbf_objiterate, 0))
939 40
                (void)VFP_Error(bo->vfc, "Template object failed");
940
941 1240
        if (bo->vfc->failed) {
942 40
                vbf_cleanup(bo);
943 40
                wrk->stats->fetch_failed++;
944 40
                return (F_STP_FAIL);
945
        }
946 1200
        return (F_STP_FETCHEND);
947 1360
}
948
949
/*--------------------------------------------------------------------
950
 * Create synth object
951
 *
952
 * replaces a stale object unless
953
 * - abandoning the bereq or
954
 * - leaving vcl_backend_error with return (deliver)
955
 *
956
 * We do want the stale replacement to avoid an object pileup with short ttl and
957
 * long grace/keep, yet there could exist cases where a cache object is
958
 * deliberately created to momentarily override a stale object.
959
 *
960
 * If this case exists, we should add a vcl veto (e.g. beresp.replace_stale with
961
 * default true)
962
 */
963
964
static const struct fetch_step * v_matchproto_(vbf_state_f)
965 16320
vbf_stp_error(struct worker *wrk, struct busyobj *bo)
966
{
967
        ssize_t l, ll, o;
968
        vtim_real now;
969
        uint8_t *ptr;
970
        struct vsb *synth_body;
971
        struct objcore *stale, *oc;
972
973 16320
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
974 16320
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
975 16320
        oc = bo->fetch_objcore;
976 16320
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
977 16320
        CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC);
978 16320
        assert(oc->boc->state < BOS_STREAM);
979 16320
        assert(bo->director_state == DIR_S_NULL);
980
981 16320
        if (wrk->vpi->handling != VCL_RET_ERROR)
982 15479
                wrk->stats->fetch_failed++;
983
984 16320
        now = W_TIM_real(wrk);
985 16320
        VSLb_ts_busyobj(bo, "Error", now);
986
987 16320
        if (oc->stobj->stevedore != NULL) {
988
                // replacing an already fetched object with a "synth" one
989 840
                assert(oc->boc->state < BOS_STREAM);
990 840
                oc->boc->fetched_so_far = 0;
991 840
                ObjFreeObj(bo->wrk, oc);
992 840
        }
993
994 16320
        if (bo->storage == NULL)
995 960
                bo->storage = STV_next();
996
997
        // XXX: reset all beresp flags ?
998
999 16320
        HTTP_Setup(bo->beresp, bo->ws, bo->vsl, SLT_BerespMethod);
1000 16320
        if (bo->err_code > 0)
1001 2640
                http_PutResponse(bo->beresp, "HTTP/1.1", bo->err_code,
1002 1320
                    bo->err_reason);
1003
        else
1004 15000
                http_PutResponse(bo->beresp, "HTTP/1.1", 503,
1005
                    "Backend fetch failed");
1006
1007 16320
        http_TimeHeader(bo->beresp, "Date: ", now);
1008 16320
        http_SetHeader(bo->beresp, "Server: Varnish");
1009
1010 16320
        stale = bo->stale_oc;
1011 16320
        oc->t_origin = now;
1012 16320
        oc->ttl = 0;
1013 16320
        oc->grace = 0;
1014 16320
        oc->keep = 0;
1015
1016 16320
        synth_body = VSB_new_auto();
1017 16320
        AN(synth_body);
1018
1019 16320
        VCL_backend_error_method(bo->vcl, wrk, NULL, bo, synth_body);
1020
1021 16320
        AZ(VSB_finish(synth_body));
1022
1023 16320
        if (wrk->vpi->handling == VCL_RET_ABANDON || wrk->vpi->handling == VCL_RET_FAIL) {
1024 1120
                VSB_destroy(&synth_body);
1025 1120
                return (F_STP_FAIL);
1026
        }
1027
1028 15200
        if (wrk->vpi->handling == VCL_RET_RETRY) {
1029 520
                VSB_destroy(&synth_body);
1030 520
                if (bo->retries++ < bo->max_retries)
1031 480
                        return (F_STP_RETRY);
1032 40
                VSLb(bo->vsl, SLT_VCL_Error, "Too many retries, failing");
1033 40
                return (F_STP_FAIL);
1034
        }
1035
1036 14680
        assert(wrk->vpi->handling == VCL_RET_DELIVER);
1037
1038 14680
        assert(bo->vfc->wrk == bo->wrk);
1039 14680
        assert(bo->vfc->oc == oc);
1040 14680
        assert(bo->vfc->resp == bo->beresp);
1041 14680
        assert(bo->vfc->req == bo->bereq);
1042
1043 14680
        if (vbf_beresp2obj(bo)) {
1044 80
                VSB_destroy(&synth_body);
1045 80
                return (F_STP_FAIL);
1046
        }
1047
1048 14600
        oc->boc->transit_buffer = 0;
1049
1050 14600
        ll = VSB_len(synth_body);
1051 14600
        o = 0;
1052 27240
        while (ll > 0) {
1053 12680
                l = ll;
1054 12680
                if (VFP_GetStorage(bo->vfc, &l, &ptr) != VFP_OK) {
1055 40
                        VSB_destroy(&synth_body);
1056 40
                        return (F_STP_FAIL);
1057
                }
1058 12640
                l = vmin(l, ll);
1059 12640
                memcpy(ptr, VSB_data(synth_body) + o, l);
1060 12640
                VFP_Extend(bo->vfc, l, l == ll ? VFP_END : VFP_OK);
1061 12640
                ll -= l;
1062 12640
                o += l;
1063
        }
1064 14560
        assert(o == VSB_len(synth_body));
1065 14560
        AZ(ObjSetU64(wrk, oc, OA_LEN, o));
1066 14560
        VSB_destroy(&synth_body);
1067 14560
        if (stale != NULL && oc->ttl > 0)
1068 880
                HSH_Kill(stale);
1069 14560
        VBO_SetState(wrk, bo, BOS_FINISHED);
1070 14560
        return (F_STP_DONE);
1071 16320
}
1072
1073
/*--------------------------------------------------------------------
1074
 */
1075
1076
static const struct fetch_step * v_matchproto_(vbf_state_f)
1077 2719
vbf_stp_fail(struct worker *wrk, struct busyobj *bo)
1078
{
1079
        struct objcore *oc;
1080
1081 2719
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1082 2719
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
1083 2719
        oc = bo->fetch_objcore;
1084 2719
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1085
1086 2719
        assert(oc->boc->state < BOS_FINISHED);
1087 2719
        VBO_SetState(wrk, bo, BOS_FAILED);
1088 2719
        HSH_Kill(oc);
1089 2719
        return (F_STP_DONE);
1090
}
1091
1092
/*--------------------------------------------------------------------
1093
 */
1094
1095
static const struct fetch_step * v_matchproto_(vbf_state_f)
1096 0
vbf_stp_done(struct worker *wrk, struct busyobj *bo)
1097
{
1098
1099 0
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1100 0
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
1101 0
        WRONG("Just plain wrong");
1102 0
        NEEDLESS(return (F_STP_DONE));
1103
}
1104
1105
static void v_matchproto_(task_func_t)
1106 91920
vbf_fetch_thread(struct worker *wrk, void *priv)
1107
{
1108
        struct vrt_ctx ctx[1];
1109
        struct busyobj *bo;
1110
        struct objcore *oc;
1111
        const struct fetch_step *stp;
1112
1113 91920
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1114 91920
        CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC);
1115 91920
        CHECK_OBJ_NOTNULL(bo->req, REQ_MAGIC);
1116 91920
        oc = bo->fetch_objcore;
1117 91920
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1118
1119 91920
        THR_SetBusyobj(bo);
1120 91920
        stp = F_STP_MKBEREQ;
1121 91920
        assert(isnan(bo->t_first));
1122 91920
        assert(isnan(bo->t_prev));
1123 91920
        VSLb_ts_busyobj(bo, "Start", W_TIM_real(wrk));
1124
1125 91920
        bo->wrk = wrk;
1126 91920
        wrk->vsl = bo->vsl;
1127
1128
#if 0
1129
        if (bo->stale_oc != NULL) {
1130
                CHECK_OBJ_NOTNULL(bo->stale_oc, OBJCORE_MAGIC);
1131
                /* We don't want the oc/stevedore ops in fetching thread */
1132
                if (!ObjCheckFlag(wrk, bo->stale_oc, OF_IMSCAND))
1133
                        (void)HSH_DerefObjCore(wrk, &bo->stale_oc, 0);
1134
        }
1135
#endif
1136
1137 91920
        VCL_TaskEnter(bo->privs);
1138 496527
        while (stp != F_STP_DONE) {
1139 404607
                CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
1140 404607
                assert(oc->boc->refcount >= 1);
1141 404607
                if (oc->boc->state < BOS_REQ_DONE)
1142 95717
                        AN(bo->req);
1143
                else
1144 308890
                        AZ(bo->req);
1145 404607
                AN(stp);
1146 404607
                AN(stp->name);
1147 404607
                AN(stp->func);
1148 404607
                stp = stp->func(wrk, bo);
1149
        }
1150
1151 91920
        assert(bo->director_state == DIR_S_NULL);
1152
1153 91920
        INIT_OBJ(ctx, VRT_CTX_MAGIC);
1154 91920
        VCL_Bo2Ctx(ctx, bo);
1155 91920
        VCL_TaskLeave(ctx, bo->privs);
1156 91920
        http_Teardown(bo->bereq);
1157 91920
        http_Teardown(bo->beresp);
1158
        // cannot make assumptions about the number of references here #3434
1159 91920
        if (bo->bereq_body != NULL)
1160 720
                (void)HSH_DerefObjCore(bo->wrk, &bo->bereq_body);
1161
1162 91920
        if (oc->boc->state == BOS_FINISHED) {
1163 89200
                AZ(oc->flags & OC_F_FAILED);
1164 178400
                VSLb(bo->vsl, SLT_Length, "%ju",
1165 89200
                    (uintmax_t)ObjGetLen(bo->wrk, oc));
1166 89200
        }
1167
        // AZ(oc->boc); // XXX
1168
1169 91920
        if (bo->stale_oc != NULL)
1170 6320
                (void)HSH_DerefObjCore(wrk, &bo->stale_oc);
1171
1172 91920
        wrk->vsl = NULL;
1173 91920
        HSH_DerefBoc(wrk, oc);
1174 91920
        SES_Rel(bo->sp);
1175 91920
        VBO_ReleaseBusyObj(wrk, &bo);
1176 91920
        THR_SetBusyobj(NULL);
1177 91920
}
1178
1179
/*--------------------------------------------------------------------
1180
 */
1181
1182
void
1183 91960
VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
1184
    struct objcore *oldoc, enum vbf_fetch_mode_e mode)
1185
{
1186
        enum boc_state_e state;
1187
        struct boc *boc;
1188
        struct busyobj *bo;
1189
        enum task_prio prio;
1190
        const char *how;
1191
1192 91960
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
1193 91960
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
1194 91960
        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
1195 91960
        CHECK_OBJ_ORNULL(oldoc, OBJCORE_MAGIC);
1196
1197 91960
        bo = VBO_GetBusyObj(wrk, req);
1198 91960
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
1199 91960
        AN(bo->vcl);
1200
1201 91960
        boc = HSH_RefBoc(oc);
1202 91960
        CHECK_OBJ_NOTNULL(boc, BOC_MAGIC);
1203 91960
        assert(boc->state < BOS_STREAM);
1204 91960
        boc->transit_buffer = cache_param->transit_buffer;
1205
1206 91960
        switch (mode) {
1207
        case VBF_PASS:
1208 31840
                prio = TASK_QUEUE_BO;
1209 31840
                how = "pass";
1210 31840
                bo->uncacheable = 1;
1211 31840
                break;
1212
        case VBF_NORMAL:
1213 56600
                prio = TASK_QUEUE_BO;
1214 56600
                how = "fetch";
1215 56600
                break;
1216
        case VBF_BACKGROUND:
1217 3520
                prio = TASK_QUEUE_BG;
1218 3520
                how = "bgfetch";
1219 3520
                bo->is_bgfetch = 1;
1220 3520
                break;
1221
        default:
1222 0
                WRONG("Wrong fetch mode");
1223 0
        }
1224
1225
#define REQ_BEREQ_FLAG(l, r, w, d) bo->l = req->l;
1226
#include "tbl/req_bereq_flags.h"
1227
1228
        VSLb(bo->vsl, SLT_Begin, "bereq %ju %s", VXID(req->vsl->wid), how);
1229
        VSLbs(bo->vsl, SLT_VCL_use, TOSTRAND(VCL_Name(bo->vcl)));
1230
        VSLb(req->vsl, SLT_Link, "bereq %ju %s", VXID(bo->vsl->wid), how);
1231
1232
        THR_SetBusyobj(bo);
1233
1234
        bo->sp = req->sp;
1235
        SES_Ref(bo->sp);
1236
1237
        oc->boc->vary = req->vary_b;
1238
        req->vary_b = NULL;
1239
1240
        HSH_Ref(oc);
1241 91960
        AZ(bo->fetch_objcore);
1242
        bo->fetch_objcore = oc;
1243
1244 91960
        AZ(bo->stale_oc);
1245 91960
        if (oldoc != NULL) {
1246 6360
                assert(oldoc->refcnt > 0);
1247 6360
                HSH_Ref(oldoc);
1248 6360
                bo->stale_oc = oldoc;
1249 6360
        }
1250
1251 91960
        AZ(bo->req);
1252
        bo->req = req;
1253
1254
        bo->fetch_task->priv = bo;
1255
        bo->fetch_task->func = vbf_fetch_thread;
1256
1257 91960
        if (Pool_Task(wrk->pool, bo->fetch_task, prio)) {
1258 92
                wrk->stats->bgfetch_no_thread++;
1259 92
                VSLb(bo->vsl, SLT_FetchError,
1260
                    "No thread available for bgfetch");
1261 92
                (void)vbf_stp_fail(req->wrk, bo);
1262 92
                if (bo->stale_oc != NULL)
1263 40
                        (void)HSH_DerefObjCore(wrk, &bo->stale_oc);
1264 92
                HSH_DerefBoc(wrk, oc);
1265 92
                SES_Rel(bo->sp);
1266 92
                THR_SetBusyobj(NULL);
1267 92
                VBO_ReleaseBusyObj(wrk, &bo);
1268 92
        } else {
1269 91868
                THR_SetBusyobj(NULL);
1270 91868
                bo = NULL; /* ref transferred to fetch thread */
1271 91868
                if (mode == VBF_BACKGROUND) {
1272 3480
                        (void)ObjWaitState(oc, BOS_REQ_DONE);
1273 3480
                        (void)VRB_Ignore(req);
1274 3480
                } else {
1275 88388
                        state = ObjWaitState(oc, BOS_STREAM);
1276 88388
                        AZ(oc->flags & OC_F_BUSY);
1277 88388
                        if (state == BOS_FAILED)
1278 1080
                                AN(oc->flags & OC_F_FAILED);
1279
                }
1280
        }
1281 91960
        AZ(bo);
1282
        VSLb_ts_req(req, "Fetch", W_TIM_real(wrk));
1283 91960
        assert(oc->boc == boc);
1284
        HSH_DerefBoc(wrk, oc);
1285 91960
        if (mode == VBF_BACKGROUND)
1286 3520
                (void)HSH_DerefObjCore(wrk, &oc);
1287
}