vinyl-cache/bin/vinyld/cache/cache_esi_deliver.c
0
/*-
1
 * Copyright (c) 2011 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 *
29
 * VED - Vinyl Esi Delivery
30
 */
31
32
#include "config.h"
33
34
#include "cache_int.h"
35
36
#include <stdlib.h>
37
38
#include "cache_transport.h"
39
#include "cache_filter.h"
40
#include "cache_vgz.h"
41
42
#include "vct.h"
43
#include "vtim.h"
44
#include "cache_esi.h"
45
#include "vend.h"
46
#include "vgz.h"
47
48
static vtr_deliver_f ved_deliver;
49
static vtr_reembark_f ved_reembark;
50
51
static const uint8_t gzip_hdr[] = {
52
        0x1f, 0x8b, 0x08,
53
        0x00, 0x00, 0x00, 0x00,
54
        0x00,
55
        0x02, 0x03
56
};
57
58
struct ecx {
59
        unsigned        magic;
60
#define ECX_MAGIC       0x0b0f9163
61
        const uint8_t   *p;
62
        const uint8_t   *e;
63
        int             state;
64
        ssize_t         l;
65
        int             isgzip;
66
        int             woken;
67
        int             abrt;
68
69
        struct req      *preq;
70
        struct ecx      *pecx;
71
        ssize_t         l_crc;
72
        uint32_t        crc;
73
};
74
75
static int v_matchproto_(vtr_minimal_response_f)
76 0
ved_minimal_response(struct req *req, uint16_t status)
77
{
78 0
        (void)req;
79 0
        (void)status;
80 0
        WRONG("esi:includes should not try minimal responses");
81 0
}
82
83
static const struct transport VED_transport = {
84
        .magic =                TRANSPORT_MAGIC,
85
        .name =                 "ESI_INCLUDE",
86
        .deliver =              ved_deliver,
87
        .reembark =             ved_reembark,
88
        .minimal_response =     ved_minimal_response,
89
};
90
91
/*--------------------------------------------------------------------*/
92
93
static void v_matchproto_(vtr_reembark_f)
94 23
ved_reembark(struct worker *wrk, struct req *req)
95
{
96
        struct ecx *ecx;
97
98 23
        (void)wrk;
99 23
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
100 23
        CAST_OBJ_NOTNULL(ecx, req->transport_priv, ECX_MAGIC);
101 23
        Lck_Lock(&req->sp->mtx);
102 23
        ecx->woken = 1;
103 23
        PTOK(pthread_cond_signal(&ecx->preq->wrk->cond));
104 23
        Lck_Unlock(&req->sp->mtx);
105 23
}
106
107
/*--------------------------------------------------------------------*/
108
109
static void
110 9159
ved_include(struct req *preq, const char *src, const char *host,
111
    struct ecx *ecx)
112
{
113
        struct worker *wrk;
114
        struct sess *sp;
115
        struct req *req;
116
        enum req_fsm_nxt s;
117
118 9159
        CHECK_OBJ_NOTNULL(preq, REQ_MAGIC);
119 9159
        CHECK_OBJ_NOTNULL(preq->top, REQTOP_MAGIC);
120 9159
        sp = preq->sp;
121 9159
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
122 9159
        CHECK_OBJ_NOTNULL(ecx, ECX_MAGIC);
123 9159
        wrk = preq->wrk;
124
125 9159
        if (preq->esi_level >= cache_param->max_esi_depth) {
126 2772
                VSLb(preq->vsl, SLT_VCL_Error,
127
                    "ESI depth limit reached (param max_esi_depth = %u)",
128 1386
                    cache_param->max_esi_depth);
129 1386
                if (ecx->abrt)
130 21
                        preq->top->topreq->vdc->retval = -1;
131 1386
                return;
132
        }
133
134 7773
        req = Req_New(sp, preq);
135 7773
        AN(req);
136 7773
        THR_SetRequest(req);
137 7773
        assert(IS_NO_VXID(req->vsl->wid));
138 7773
        req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER);
139
140 7773
        wrk->stats->esi_req++;
141 7773
        req->esi_level = preq->esi_level + 1;
142
143 15546
        VSLb(req->vsl, SLT_Begin, "req %ju esi %u",
144 7773
            (uintmax_t)VXID(preq->vsl->wid), req->esi_level);
145 15546
        VSLb(preq->vsl, SLT_Link, "req %ju esi %u",
146 7773
            (uintmax_t)VXID(req->vsl->wid), req->esi_level);
147
148 7773
        VSLb_ts_req(req, "Start", W_TIM_real(wrk));
149
150 7773
        HTTP_Setup(req->http, req->ws, req->vsl, SLT_ReqMethod);
151 7773
        HTTP_Dup(req->http, preq->http0);
152
153 7773
        http_SetH(req->http, HTTP_HDR_URL, src);
154 7773
        if (host != NULL && *host != '\0')  {
155 42
                http_Unset(req->http, H_Host);
156 42
                http_SetHeader(req->http, host);
157 42
        }
158
159 7773
        http_ForceField(req->http, HTTP_HDR_METHOD, "GET");
160 7773
        http_ForceField(req->http, HTTP_HDR_PROTO, "HTTP/1.1");
161
162
        /* Don't allow conditionals, we can't use a 304 */
163 7773
        http_Unset(req->http, H_If_Modified_Since);
164 7773
        http_Unset(req->http, H_If_None_Match);
165
166
        /* Don't allow Range */
167 7773
        http_Unset(req->http, H_Range);
168
169
        /* Set Accept-Encoding according to what we want */
170 7773
        if (ecx->isgzip)
171 2709
                http_ForceHeader(req->http, H_Accept_Encoding, "gzip");
172
        else
173 5064
                http_Unset(req->http, H_Accept_Encoding);
174
175
        /* Client content already taken care of */
176 7773
        http_Unset(req->http, H_Content_Length);
177 7773
        http_Unset(req->http, H_Transfer_Encoding);
178 7773
        req->req_body_status = BS_NONE;
179
180 7773
        AZ(req->vcl);
181 7773
        assert(req->top == preq->top);
182 7773
        if (req->top->vcl0)
183 42
                req->vcl = req->top->vcl0;
184
        else
185 7731
                req->vcl = preq->vcl;
186 7773
        VCL_Ref(req->vcl);
187
188 7773
        assert(req->req_step == R_STP_TRANSPORT);
189 7773
        req->t_req = preq->t_req;
190
191 7773
        req->transport = &VED_transport;
192 7773
        req->transport_priv = ecx;
193
194 7773
        VCL_TaskEnter(req->privs);
195
196 7796
        while (1) {
197 7796
                CNT_Embark(wrk, req);
198 7796
                ecx->woken = 0;
199 7796
                s = CNT_Request(req);
200 7796
                if (s == REQ_FSM_DONE)
201 7773
                        break;
202 23
                DSL(DBG_WAITINGLIST, req->vsl->wid,
203
                    "waiting for ESI (%d)", (int)s);
204 23
                assert(s == REQ_FSM_DISEMBARK);
205 23
                Lck_Lock(&sp->mtx);
206 23
                if (!ecx->woken)
207 23
                        (void)Lck_CondWait(&ecx->preq->wrk->cond, &sp->mtx);
208 23
                Lck_Unlock(&sp->mtx);
209 23
                AZ(req->wrk);
210
        }
211
212 7773
        VCL_Rel(&req->vcl);
213
214 7773
        req->wrk = NULL;
215 7773
        THR_SetRequest(preq);
216
217 7773
        Req_Cleanup(sp, wrk, req);
218 7773
        Req_Release(req);
219 9159
}
220
221
/*--------------------------------------------------------------------*/
222
223
//#define Debug(fmt, ...) printf(fmt, __VA_ARGS__)
224
#define Debug(fmt, ...) /**/
225
226
static ssize_t
227 32218
ved_decode_len(struct vsl_log *vsl, const uint8_t **pp)
228
{
229
        const uint8_t *p;
230
        ssize_t l;
231
232 32218
        p = *pp;
233 32218
        switch (*p & 15) {
234
        case 1:
235 28165
                l = p[1];
236 28165
                p += 2;
237 28165
                break;
238
        case 2:
239 4011
                l = vbe16dec(p + 1);
240 4011
                p += 3;
241 4011
                break;
242
        case 8:
243 42
                l = vbe64dec(p + 1);
244 42
                p += 9;
245 42
                break;
246
        default:
247 0
                VSLb(vsl, SLT_Error,
248 0
                    "ESI-corruption: Illegal Length %d %d\n", *p, (*p & 15));
249 0
                WRONG("ESI-codes: illegal length");
250 0
        }
251 32218
        *pp = p;
252 32218
        assert(l > 0);
253 32218
        return (l);
254
}
255
256
/*---------------------------------------------------------------------
257
 */
258
259
static int v_matchproto_(vdp_init_f)
260 4495
ved_vdp_esi_init(VRT_CTX, struct vdp_ctx *vdc, void **priv)
261
{
262
        struct ecx *ecx;
263
264 4495
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
265 4495
        CHECK_OBJ_ORNULL(ctx->req, REQ_MAGIC);
266 4495
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
267 4495
        CHECK_OBJ_ORNULL(vdc->oc, OBJCORE_MAGIC);
268 4495
        CHECK_OBJ_NOTNULL(vdc->hp, HTTP_MAGIC);
269 4495
        AN(vdc->clen);
270 4495
        AN(priv);
271
272 4495
        AZ(*priv);
273 4495
        if (vdc->oc == NULL || !ObjHasAttr(vdc->wrk, vdc->oc, OA_ESIDATA))
274 0
                return (1);
275
276 4495
        if (ctx->req == NULL) {
277 0
                VSLb(vdc->vsl, SLT_Error,
278
                     "esi can only be used on the client side");
279 0
                return (1);
280
        }
281
282 4495
        ALLOC_OBJ(ecx, ECX_MAGIC);
283 4495
        AN(ecx);
284 4495
        assert(sizeof gzip_hdr == 10);
285 4495
        ecx->preq = ctx->req;
286 4495
        *priv = ecx;
287 4495
        RFC2616_Weaken_Etag(vdc->hp);
288
289 4495
        ctx->req->res_esi = 1;
290 4495
        if (*vdc->clen != 0)
291 4495
                *vdc->clen = -1;
292 4495
        if (ctx->req->esi_level > 0) {
293 1807
                assert(ctx->req->transport == &VED_transport);
294 1807
                CAST_OBJ_NOTNULL(ecx->pecx, ctx->req->transport_priv, ECX_MAGIC);
295 1807
                if (!ecx->pecx->isgzip)
296 379
                        ecx->pecx = NULL;
297 1807
        }
298
299 4495
        return (0);
300 4495
}
301
302
static int v_matchproto_(vdp_fini_f)
303 4495
ved_vdp_esi_fini(struct vdp_ctx *vdc, void **priv)
304
{
305
        struct ecx *ecx;
306
307 4495
        (void)vdc;
308 4495
        TAKE_OBJ_NOTNULL(ecx, priv, ECX_MAGIC);
309 4495
        FREE_OBJ(ecx);
310 4495
        return (0);
311
}
312
313
static int v_matchproto_(vdp_bytes_f)
314 5671
ved_vdp_esi_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv,
315
    const void *ptr, ssize_t len)
316
{
317
        const uint8_t *q, *r;
318 5671
        ssize_t l = 0;
319 5671
        uint32_t icrc = 0;
320
        uint8_t tailbuf[8 + 5];
321
        const uint8_t *pp;
322
        struct ecx *ecx;
323 5671
        int retval = 0;
324
325 5671
        if (act == VDP_END)
326 4474
                act = VDP_FLUSH;
327
328 5671
        AN(priv);
329 5671
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
330 5671
        CAST_OBJ_NOTNULL(ecx, *priv, ECX_MAGIC);
331 5671
        pp = ptr;
332
333 76264
        while (1) {
334 76264
                switch (ecx->state) {
335
                case 0:
336 4474
                        ecx->p = ObjGetAttr(vdc->wrk, ecx->preq->objcore,
337
                            OA_ESIDATA, &l);
338 4474
                        AN(ecx->p);
339 4474
                        assert(l > 0);
340 4474
                        ecx->e = ecx->p + l;
341
342 4474
                        if (*ecx->p == VEC_GZ) {
343 2247
                                if (ecx->pecx == NULL)
344 861
                                        retval = VDP_bytes(vdc, VDP_NULL,
345
                                            gzip_hdr, 10);
346 2247
                                ecx->l_crc = 0;
347 2247
                                ecx->crc = crc32(0L, Z_NULL, 0);
348 2247
                                ecx->isgzip = 1;
349 2247
                                ecx->p++;
350 2247
                        }
351 4474
                        ecx->state = 1;
352 4474
                        break;
353
                case 1:
354 39886
                        if (ecx->p >= ecx->e) {
355 4264
                                ecx->state = 2;
356 4264
                                break;
357
                        }
358 35622
                        switch (*ecx->p) {
359
                        case VEC_V1:
360
                        case VEC_V2:
361
                        case VEC_V8:
362 12454
                                ecx->l = ved_decode_len(vdc->vsl, &ecx->p);
363 12454
                                if (ecx->l < 0)
364 0
                                        return (-1);
365 12454
                                if (ecx->isgzip) {
366 5775
                                        assert(*ecx->p == VEC_C1 ||
367
                                            *ecx->p == VEC_C2 ||
368
                                            *ecx->p == VEC_C8);
369 5775
                                        l = ved_decode_len(vdc->vsl, &ecx->p);
370 5775
                                        if (l < 0)
371 0
                                                return (-1);
372 5775
                                        icrc = vbe32dec(ecx->p);
373 5775
                                        ecx->p += 4;
374 5775
                                        ecx->crc = crc32_combine(
375 5775
                                            ecx->crc, icrc, l);
376 5775
                                        ecx->l_crc += l;
377 5775
                                }
378 12454
                                ecx->state = 3;
379 12454
                                break;
380
                        case VEC_S1:
381
                        case VEC_S2:
382
                        case VEC_S8:
383 13989
                                ecx->l = ved_decode_len(vdc->vsl, &ecx->p);
384 13989
                                if (ecx->l < 0)
385 0
                                        return (-1);
386
                                Debug("SKIP1(%d)\n", (int)ecx->l);
387 13989
                                ecx->state = 4;
388 13989
                                break;
389
                        case VEC_IA:
390 6386
                                ecx->abrt =
391 6386
                                    ecx->preq->esi_include_onerror;
392
                                /* FALLTHROUGH */
393
                        case VEC_IC:
394 9179
                                ecx->p++;
395 9179
                                q = (const void*)strchr((const char*)ecx->p, '\0');
396 9179
                                AN(q);
397 9179
                                q++;
398 9179
                                r = (const void*)strchr((const char*)q, '\0');
399 9179
                                AN(r);
400 9179
                                if (VDP_bytes(vdc, VDP_FLUSH, NULL, 0)) {
401 20
                                        ecx->p = ecx->e;
402 20
                                        break;
403
                                }
404
                                Debug("INCL [%s][%s] BEGIN\n", q, ecx->p);
405 18318
                                ved_include(ecx->preq,
406 9159
                                    (const char*)q, (const char*)ecx->p, ecx);
407
                                Debug("INCL [%s][%s] END\n", q, ecx->p);
408 9159
                                ecx->p = r + 1;
409 9159
                                break;
410
                        default:
411 0
                                VSLb(vdc->vsl, SLT_Error,
412
                                    "ESI corruption line %d 0x%02x [%s]\n",
413 0
                                    __LINE__, *ecx->p, ecx->p);
414 0
                                WRONG("ESI-codes: Illegal code");
415 0
                        }
416 35622
                        break;
417
                case 2:
418 4264
                        ptr = NULL;
419 4264
                        len = 0;
420 4264
                        if (ecx->isgzip && ecx->pecx == NULL) {
421
                                /*
422
                                 * We are bytealigned here, so simply emit
423
                                 * a gzip literal block with finish bit set.
424
                                 */
425 861
                                tailbuf[0] = 0x01;
426 861
                                tailbuf[1] = 0x00;
427 861
                                tailbuf[2] = 0x00;
428 861
                                tailbuf[3] = 0xff;
429 861
                                tailbuf[4] = 0xff;
430
431
                                /* Emit CRC32 */
432 861
                                vle32enc(tailbuf + 5, ecx->crc);
433
434
                                /* MOD(2^32) length */
435 861
                                vle32enc(tailbuf + 9, ecx->l_crc);
436
437 861
                                ptr = tailbuf;
438 861
                                len = 13;
439 4264
                        } else if (ecx->pecx != NULL) {
440 2856
                                ecx->pecx->crc = crc32_combine(ecx->pecx->crc,
441 1428
                                    ecx->crc, ecx->l_crc);
442 1428
                                ecx->pecx->l_crc += ecx->l_crc;
443 1428
                        }
444 4264
                        retval = VDP_bytes(vdc, VDP_END, ptr, len);
445 4264
                        ecx->state = 99;
446 4264
                        return (retval);
447
                case 3:
448
                case 4:
449
                        /*
450
                         * There is no guarantee that the 'l' bytes are all
451
                         * in the same storage segment, so loop over storage
452
                         * until we have processed them all.
453
                         */
454 27430
                        if (ecx->l <= len) {
455 26443
                                if (ecx->state == 3)
456 24908
                                        retval = VDP_bytes(vdc, act,
457 12454
                                            pp, ecx->l);
458 26443
                                len -= ecx->l;
459 26443
                                pp += ecx->l;
460 26443
                                ecx->state = 1;
461 26443
                                break;
462
                        }
463 987
                        if (ecx->state == 3 && len > 0)
464 357
                                retval = VDP_bytes(vdc, act, pp, len);
465 987
                        ecx->l -= len;
466 987
                        return (retval);
467
                case 99:
468
                        /*
469
                         * VEP does not account for the PAD+CRC+LEN
470
                         * so we can see up to approx 15 bytes here.
471
                         */
472 210
                        return (retval);
473
                default:
474 0
                        WRONG("FOO");
475 0
                        break;
476
                }
477 70803
                if (retval)
478 210
                        return (retval);
479
        }
480 5671
}
481
482
const struct vdp VDP_esi = {
483
        .name =         "esi",
484
        .init =         ved_vdp_esi_init,
485
        .bytes =        ved_vdp_esi_bytes,
486
        .fini =         ved_vdp_esi_fini,
487
};
488
489
/*
490
 * Account body bytes on req
491
 * Push bytes to preq
492
 */
493
static inline int
494 46564
ved_bytes(struct ecx *ecx, enum vdp_action act,
495
    const void *ptr, ssize_t len)
496
{
497 46564
        if (act == VDP_END)
498 7794
                act = VDP_FLUSH;
499 46564
        return (VDP_bytes(ecx->preq->vdc, act, ptr, len));
500
}
501
502
/*---------------------------------------------------------------------
503
 * If a gzipped ESI object includes a ungzipped object, we need to make
504
 * it looked like a gzipped data stream.  The official way to do so would
505
 * be to fire up libvgz and gzip it, but we don't, we fake it.
506
 *
507
 * First, we cannot know if it is ungzipped on purpose, the admin may
508
 * know something we don't.
509
 *
510
 * What do you mean "BS ?"
511
 *
512
 * All right then...
513
 *
514
 * The matter of the fact is that we simply will not fire up a gzip in
515
 * the output path because it costs too much memory and CPU, so we simply
516
 * wrap the data in very convenient "gzip copy-blocks" and send it down
517
 * the stream with a bit more overhead.
518
 */
519
520
static int v_matchproto_(vdp_fini_f)
521 378
ved_pretend_gzip_fini(struct vdp_ctx *vdc, void **priv)
522
{
523 378
        (void)vdc;
524 378
        *priv = NULL;
525 378
        return (0);
526
}
527
528
static int v_matchproto_(vdp_bytes_f)
529 1050
ved_pretend_gzip_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv,
530
    const void *pv, ssize_t l)
531
{
532
        uint8_t buf1[5], buf2[5];
533
        const uint8_t *p;
534
        uint16_t lx;
535
        struct ecx *ecx;
536
537 1050
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
538 1050
        CAST_OBJ_NOTNULL(ecx, *priv, ECX_MAGIC);
539
540 1050
        (void)priv;
541 1050
        if (l == 0)
542 210
                return (ved_bytes(ecx, act, pv, l));
543
544 840
        p = pv;
545
546 840
        AN (ecx->isgzip);
547 840
        ecx->crc = crc32(ecx->crc, p, l);
548 840
        ecx->l_crc += l;
549
550
        /*
551
         * buf1 can safely be emitted multiple times for objects longer
552
         * than 64K-1 bytes.
553
         */
554 840
        lx = 65535;
555 840
        buf1[0] = 0;
556 840
        vle16enc(buf1 + 1, lx);
557 840
        vle16enc(buf1 + 3, ~lx);
558
559 1680
        while (l > 0) {
560 840
                if (l >= 65535) {
561 0
                        lx = 65535;
562 0
                        if (ved_bytes(ecx, VDP_NULL, buf1, sizeof buf1))
563 0
                                return (-1);
564 0
                } else {
565 840
                        lx = (uint16_t)l;
566 840
                        buf2[0] = 0;
567 840
                        vle16enc(buf2 + 1, lx);
568 840
                        vle16enc(buf2 + 3, ~lx);
569 840
                        if (ved_bytes(ecx, VDP_NULL, buf2, sizeof buf2))
570 0
                                return (-1);
571
                }
572 840
                if (ved_bytes(ecx, VDP_NULL, p, lx))
573 0
                        return (-1);
574 840
                l -= lx;
575 840
                p += lx;
576
        }
577
        /* buf1 & buf2 are local, so we have to flush */
578 840
        return (ved_bytes(ecx, VDP_FLUSH, NULL, 0));
579 1050
}
580
581
static const struct vdp ved_pretend_gz = {
582
        .name =         "PGZ",
583
        .bytes =        ved_pretend_gzip_bytes,
584
        .fini =         ved_pretend_gzip_fini,
585
};
586
587
/*---------------------------------------------------------------------
588
 * Include a gzipped object in a gzipped ESI object delivery
589
 *
590
 * This is the interesting case: Deliver all the deflate blocks, stripping
591
 * the "LAST" bit of the last one and padding it, as necessary, to a byte
592
 * boundary.
593
 *
594
 */
595
596
struct ved_foo {
597
        unsigned                magic;
598
#define VED_FOO_MAGIC           0x6a5a262d
599
        struct ecx              *ecx;
600
        struct objcore          *objcore;
601
        uint64_t                start, last, stop, lpad;
602
        ssize_t                 ll;
603
        uint64_t                olen;
604
        uint8_t                 dbits[8];
605
        uint8_t                 tailbuf[8];
606
};
607
608
static int v_matchproto_(vdp_init_f)
609 861
ved_gzgz_init(VRT_CTX, struct vdp_ctx *vdc, void **priv)
610
{
611
        ssize_t l;
612
        const char *p;
613
        struct ved_foo *foo;
614
615 861
        CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
616 861
        CHECK_OBJ_NOTNULL(vdc, VDP_CTX_MAGIC);
617 861
        AN(priv);
618
619 861
        CAST_OBJ_NOTNULL(foo, *priv, VED_FOO_MAGIC);
620 861
        CHECK_OBJ_NOTNULL(foo->objcore, OBJCORE_MAGIC);
621
622 861
        memset(foo->tailbuf, 0xdd, sizeof foo->tailbuf);
623
624 861
        AN(ObjCheckFlag(vdc->wrk, foo->objcore, OF_GZIPED));
625
626 861
        p = ObjGetAttr(vdc->wrk, foo->objcore, OA_GZIPBITS, &l);
627 861
        AN(p);
628 861
        assert(l == 32);
629 861
        foo->start = vbe64dec(p);
630 861
        foo->last = vbe64dec(p + 8);
631 861
        foo->stop = vbe64dec(p + 16);
632 861
        foo->olen = ObjGetLen(vdc->wrk, foo->objcore);
633 861
        assert(foo->start > 0 && foo->start < foo->olen * 8);
634 861
        assert(foo->last > 0 && foo->last < foo->olen * 8);
635 861
        assert(foo->stop > 0 && foo->stop < foo->olen * 8);
636 861
        assert(foo->last >= foo->start);
637 861
        assert(foo->last < foo->stop);
638
639
        /* The start bit must be byte aligned. */
640 861
        AZ(foo->start & 7);
641 861
        return (0);
642
}
643
644
/*
645
 * XXX: for act == VDP_END || act == VDP_FLUSH, we send a flush more often than
646
 * we need. The VDP_END case would trip our "at most one VDP_END call" assertion
647
 * in VDP_bytes(), but ved_bytes() covers it.
648
 *
649
 * To avoid unnecessary chunks downstream, it would be nice to re-structure the
650
 * code to identify the last block, send VDP_END/VDP_FLUSH for that one and
651
 * VDP_NULL for anything before it.
652
 */
653
654
static int v_matchproto_(vdp_bytes_f)
655 1260
ved_gzgz_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv,
656
    const void *ptr, ssize_t len)
657
{
658
        struct ved_foo *foo;
659
        const uint8_t *pp;
660
        ssize_t dl;
661
        ssize_t l;
662
663 1260
        (void)vdc;
664 1260
        CAST_OBJ_NOTNULL(foo, *priv, VED_FOO_MAGIC);
665 1260
        pp = ptr;
666 1260
        if (len > 0) {
667
                /* Skip over the GZIP header */
668 1260
                dl = foo->start / 8 - foo->ll;
669 1260
                if (dl > 0) {
670
                        /* Before foo.start, skip */
671 924
                        if (dl > len)
672 63
                                dl = len;
673 924
                        foo->ll += dl;
674 924
                        len -= dl;
675 924
                        pp += dl;
676 924
                }
677 1260
        }
678 1260
        if (len > 0) {
679
                /* The main body of the object */
680 1197
                dl = foo->last / 8 - foo->ll;
681 1197
                if (dl > 0) {
682 378
                        dl = vmin(dl, len);
683 378
                        if (ved_bytes(foo->ecx, act, pp, dl))
684 0
                                return (-1);
685 378
                        foo->ll += dl;
686 378
                        len -= dl;
687 378
                        pp += dl;
688 378
                }
689 1197
        }
690 1260
        if (len > 0 && foo->ll == foo->last / 8) {
691
                /* Remove the "LAST" bit */
692 861
                foo->dbits[0] = *pp;
693 861
                foo->dbits[0] &= ~(1U << (foo->last & 7));
694 861
                if (ved_bytes(foo->ecx, act, foo->dbits, 1))
695 0
                        return (-1);
696 861
                foo->ll++;
697 861
                len--;
698 861
                pp++;
699 861
        }
700 1260
        if (len > 0) {
701
                /* Last block */
702 1155
                dl = foo->stop / 8 - foo->ll;
703 1155
                if (dl > 0) {
704 567
                        dl = vmin(dl, len);
705 567
                        if (ved_bytes(foo->ecx, act, pp, dl))
706 0
                                return (-1);
707 567
                        foo->ll += dl;
708 567
                        len -= dl;
709 567
                        pp += dl;
710 567
                }
711 1155
        }
712 1260
        if (len > 0 && (foo->stop & 7) && foo->ll == foo->stop / 8) {
713
                /* Add alignment to byte boundary */
714 693
                foo->dbits[1] = *pp;
715 693
                foo->ll++;
716 693
                len--;
717 693
                pp++;
718 693
                switch ((int)(foo->stop & 7)) {
719
                case 1: /*
720
                         * x000....
721
                         * 00000000 00000000 11111111 11111111
722
                         */
723
                case 3: /*
724
                         * xxx000..
725
                         * 00000000 00000000 11111111 11111111
726
                         */
727
                case 5: /*
728
                         * xxxxx000
729
                         * 00000000 00000000 11111111 11111111
730
                         */
731 126
                        foo->dbits[2] = 0x00; foo->dbits[3] = 0x00;
732 126
                        foo->dbits[4] = 0xff; foo->dbits[5] = 0xff;
733 126
                        foo->lpad = 5;
734 126
                        break;
735
                case 2: /* xx010000 00000100 00000001 00000000 */
736 399
                        foo->dbits[1] |= 0x08;
737 399
                        foo->dbits[2] = 0x20;
738 399
                        foo->dbits[3] = 0x80;
739 399
                        foo->dbits[4] = 0x00;
740 399
                        foo->lpad = 4;
741 399
                        break;
742
                case 4: /* xxxx0100 00000001 00000000 */
743 42
                        foo->dbits[1] |= 0x20;
744 42
                        foo->dbits[2] = 0x80;
745 42
                        foo->dbits[3] = 0x00;
746 42
                        foo->lpad = 3;
747 42
                        break;
748
                case 6: /* xxxxxx01 00000000 */
749 84
                        foo->dbits[1] |= 0x80;
750 84
                        foo->dbits[2] = 0x00;
751 84
                        foo->lpad = 2;
752 84
                        break;
753
                case 7: /*
754
                         * xxxxxxx0
755
                         * 00......
756
                         * 00000000 00000000 11111111 11111111
757
                         */
758 42
                        foo->dbits[2] = 0x00;
759 42
                        foo->dbits[3] = 0x00; foo->dbits[4] = 0x00;
760 42
                        foo->dbits[5] = 0xff; foo->dbits[6] = 0xff;
761 42
                        foo->lpad = 6;
762 42
                        break;
763 0
                case 0: /* xxxxxxxx */
764
                default:
765 0
                        WRONG("compiler must be broken");
766 0
                }
767 693
                if (ved_bytes(foo->ecx, act, foo->dbits + 1, foo->lpad))
768 0
                        return (-1);
769 693
        }
770 1260
        if (len > 0) {
771
                /* Recover GZIP tail */
772 1029
                dl = foo->olen - foo->ll;
773 1029
                assert(dl >= 0);
774 1029
                if (dl > len)
775 168
                        dl = len;
776 1029
                if (dl > 0) {
777 1029
                        assert(dl <= 8);
778 1029
                        l = foo->ll - (foo->olen - 8);
779 1029
                        assert(l >= 0);
780 1029
                        assert(l <= 8);
781 1029
                        assert(l + dl <= 8);
782 1029
                        vmemcpy(foo->tailbuf + l, pp, dl);
783 1029
                        foo->ll += dl;
784 1029
                        len -= dl;
785 1029
                }
786 1029
        }
787 1260
        assert(len == 0);
788 1260
        return (0);
789 1260
}
790
791
static int v_matchproto_(vdp_fini_f)
792 861
ved_gzgz_fini(struct vdp_ctx *vdc, void **priv)
793
{
794
        uint32_t icrc;
795
        uint32_t ilen;
796
        struct ved_foo *foo;
797
798 861
        (void)vdc;
799 861
        TAKE_OBJ_NOTNULL(foo, priv, VED_FOO_MAGIC);
800
801
        /* XXX
802
         * this works due to the esi layering, a VDP pushing bytes from _fini
803
         * will otherwise have its own _bytes method called.
804
         *
805
         * Could rewrite use VDP_END
806
         */
807 861
        (void)ved_bytes(foo->ecx, VDP_FLUSH, NULL, 0);
808
809 861
        icrc = vle32dec(foo->tailbuf);
810 861
        ilen = vle32dec(foo->tailbuf + 4);
811 861
        foo->ecx->crc = crc32_combine(foo->ecx->crc, icrc, ilen);
812 861
        foo->ecx->l_crc += ilen;
813
814 861
        return (0);
815
}
816
817
static const struct vdp ved_gzgz = {
818
        .name =         "VZZ",
819
        .init =         ved_gzgz_init,
820
        .bytes =        ved_gzgz_bytes,
821
        .fini =         ved_gzgz_fini,
822
};
823
824
/*--------------------------------------------------------------------
825
 * Straight through without processing.
826
 */
827
828
static int v_matchproto_(vdp_fini_f)
829 6114
ved_vdp_fini(struct vdp_ctx *vdc, void **priv)
830
{
831 6114
        (void)vdc;
832 6114
        *priv = NULL;
833 6114
        return (0);
834
}
835
836
static int v_matchproto_(vdp_bytes_f)
837 40474
ved_vdp_bytes(struct vdp_ctx *vdc, enum vdp_action act, void **priv,
838
    const void *ptr, ssize_t len)
839
{
840
        struct ecx *ecx;
841
842 40474
        (void)vdc;
843 40474
        CAST_OBJ_NOTNULL(ecx, *priv, ECX_MAGIC);
844 40474
        return (ved_bytes(ecx, act, ptr, len));
845
}
846
847
static const struct vdp ved_ved = {
848
        .name =         "VED",
849
        .bytes =        ved_vdp_bytes,
850
        .fini =         ved_vdp_fini,
851
};
852
853
static void
854 7773
ved_close(struct req *req, int error)
855
{
856 7773
        req->acct.resp_bodybytes += VDP_Close(req->vdc, req->objcore, req->boc);
857
858 7773
        if (! error)
859 7689
                return;
860 84
        req->top->topreq->vdc->retval = -1;
861 84
        req->top->topreq->doclose = req->doclose;
862 7773
}
863
864
/*--------------------------------------------------------------------*/
865
866
static enum vtr_deliver_e v_matchproto_(vtr_deliver_f)
867 7773
ved_deliver(struct req *req, int wantbody)
868
{
869 7773
        int i = 0;
870
        const char *p;
871
        uint16_t status;
872
        struct ecx *ecx;
873
        struct ved_foo foo[1];
874
        struct vrt_ctx ctx[1];
875
876 7773
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
877 7773
        CHECK_OBJ_ORNULL(req->boc, BOC_MAGIC);
878 7773
        CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
879
880 7773
        CAST_OBJ_NOTNULL(ecx, req->transport_priv, ECX_MAGIC);
881
882 7773
        status = req->resp->status % 1000;
883
884 7878
        if (FEATURE(FEATURE_ESI_INCLUDE_ONERROR) &&
885 1512
            status != 200 && status != 204) {
886 105
                ved_close(req, ecx->abrt);
887 105
                return (VTR_D_DONE);
888
        }
889
890 7668
        if (wantbody == 0) {
891 273
                ved_close(req, 0);
892 273
                return (VTR_D_DONE);
893
        }
894
895 7395
        if (req->boc == NULL && ObjGetLen(req->wrk, req->objcore) == 0) {
896 0
                ved_close(req, 0);
897 0
                return (VTR_D_DONE);
898
        }
899
900 7395
        if (http_GetHdr(req->resp, H_Content_Encoding, &p))
901 2268
                i = http_coding_eq(p, gzip);
902 7395
        if (i)
903 2268
                i = ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED);
904
905 7395
        INIT_OBJ(ctx, VRT_CTX_MAGIC);
906 7395
        VCL_Req2Ctx(ctx, req);
907
908 7395
        if (ecx->isgzip && i && !req->res_esi) {
909
                /* A gzipped include which is not ESI processed */
910
911
                /* OA_GZIPBITS are not valid until BOS_FINISHED */
912 882
                if (req->boc != NULL)
913 294
                        (void)ObjWaitState(req->objcore, BOS_FINISHED);
914
915 882
                if (req->objcore->flags & OC_F_FAILED) {
916
                        /* No way of signalling errors in the middle of
917
                         * the ESI body. Omit this ESI fragment.
918
                         * XXX change error argument to 1
919
                         */
920 21
                        ved_close(req, 0);
921 21
                        return (VTR_D_DONE);
922
                }
923
924 861
                INIT_OBJ(foo, VED_FOO_MAGIC);
925 861
                foo->ecx = ecx;
926 861
                foo->objcore = req->objcore;
927 861
                i = VDP_Push(ctx, req->vdc, req->ws, &ved_gzgz, foo);
928 7374
        } else if (ecx->isgzip && !i) {
929
                /* Non-Gzip'ed include in gzipped parent */
930 378
                i = VDP_Push(ctx, req->vdc, req->ws, &ved_pretend_gz, ecx);
931 378
        } else {
932
                /* Anything else goes straight through */
933 6135
                i = VDP_Push(ctx, req->vdc, req->ws, &ved_ved, ecx);
934
        }
935
936 7374
        if (i == 0) {
937 7353
                i = VDP_DeliverObj(req->vdc, req->objcore);
938 7353
        } else {
939 21
                VSLb(req->vsl, SLT_Error, "Failure to push ESI processors");
940 21
                req->doclose = SC_OVERLOAD;
941
        }
942
943 7374
        if (i && req->doclose == SC_NULL)
944 127
                req->doclose = SC_REM_CLOSE;
945
946 7374
        ved_close(req, i && ecx->abrt ? 1 : 0);
947 7374
        return (VTR_D_DONE);
948 7773
}