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