vinyl-cache/bin/vinyld/http1/cache_http1_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/cache_int.h"
34
#include "cache/cache_filter.h"
35
36
#include <stdio.h>
37
#include <stdlib.h>
38
39
#include "vtcp.h"
40
#include "vtim.h"
41
42
#include "cache_http1.h"
43
44
static int
45 48699
v1f_stackv1l(struct vdp_ctx *vdc, struct busyobj *bo, struct v1l *v1l)
46
{
47
        struct vrt_ctx ctx[1];
48
49 48699
        INIT_OBJ(ctx, VRT_CTX_MAGIC);
50 48699
        VCL_Bo2Ctx(ctx, bo);
51 48699
        return (VDP_Push(ctx, vdc, ctx->ws, VDP_v1l, v1l));
52
}
53
54
/*--------------------------------------------------------------------
55
 * Send request to backend, including any (cached) req.body
56
 *
57
 * Return value:
58
 *       0 success
59
 *       1 failure
60
 */
61
62
int
63 48740
V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes,
64
    uint64_t *ctr_bodybytes)
65
{
66
        struct http *hp;
67
        stream_close_t sc;
68
        ssize_t i;
69
        uint64_t bytes, hdrbytes;
70
        struct http_conn *htc;
71 48740
        struct vdp_ctx vdc[1] = {{ 0 }};
72
        intmax_t cl, ocl;
73 48740
        const char *err = NULL;
74 48740
        struct v1l *v1l = NULL;
75
76 48740
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
77 48740
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
78 48740
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
79 48740
        CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC);
80 48740
        AN(ctr_hdrbytes);
81 48740
        AN(ctr_bodybytes);
82
83 48740
        htc = bo->htc;
84 48740
        assert(*htc->rfd > 0);
85 48740
        hp = bo->bereq;
86
87 48740
        if (bo->bereq_body != NULL)
88 503
                cl = ObjGetLen(wrk, bo->bereq_body);
89 48237
        else if (bo->req != NULL && !bo->req->req_body_status->length_known)
90 1995
                cl = -1;
91 46242
        else if (bo->req != NULL) {
92 2562
                cl = http_GetContentLength(bo->req->http);
93 2562
                if (cl < 0)
94 420
                        cl = 0;
95 2562
        }
96
        else
97 43680
                cl = 0;
98 48740
        ocl = cl;
99 48740
        VDP_Init(vdc, wrk, bo->vsl, NULL, bo, &cl);
100 48740
        if (bo->vdp_filter_list != NULL &&
101 378
            VCL_StackVDP(vdc, bo->vcl, bo->vdp_filter_list, NULL, bo))
102 21
                err = "Failure to push processors";
103 48719
        else if ((v1l = V1L_Open(wrk->aws, htc->rfd, bo->vsl, nan(""), 0)) == NULL) {
104
                /*      ^^^^^^^^
105
                 * XXX: need a send_timeout for the backend side
106
                 * XXX: use cache_param->http1_iovs ?
107
                 */
108 21
                err = "Failure to open V1L (workspace_thread overflow)";
109 21
        }
110 48698
        else if (v1f_stackv1l(vdc, bo, v1l))
111 336
                err = "Failure to push V1L";
112
113 48740
        if (err != NULL) {
114 379
                if (v1l != NULL)
115 336
                        (void) V1L_Close(&v1l, &bytes);
116 379
                if (VALID_OBJ(vdc, VDP_CTX_MAGIC))
117 378
                        (void) VDP_Close(vdc, NULL, NULL);
118 381
                VSLbs(bo->vsl, SLT_FetchError, TOSTRAND(err));
119 381
                VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
120 381
                htc->doclose = SC_OVERLOAD;
121 381
                return (-1);
122
        }
123
124
125 48361
        assert(cl >= -1);
126 48361
        if (cl < 0) {
127 2037
                http_Unset(hp, H_Content_Length);
128 2037
                http_ForceHeader(hp, H_Transfer_Encoding, "chunked");
129 48361
        } else if (ocl != cl) {
130 84
                assert(cl >= 0);
131 84
                http_Unset(hp, H_Transfer_Encoding);
132 84
                http_Unset(hp, H_Content_Length);
133 84
                http_PrintfHeader(hp, "Content-Length: %ju", cl);
134 84
        }
135
136 48361
        VTCP_blocking(*htc->rfd);       /* XXX: we should timeout instead */
137 48361
        hdrbytes = HTTP1_Write(v1l, hp, HTTP1_Req);
138
139
        /* Deal with any message-body the request might (still) have */
140 48361
        i = 0;
141
142 48361
        if (cl != 0 && bo->bereq_body != NULL) {
143 483
                AZ(bo->req);
144 483
                if (cl < 0)
145 63
                        V1L_Chunked(v1l);
146 966
                (void)ObjIterate(bo->wrk, bo->bereq_body,
147 483
                    vdc, VDP_ObjIterate, 0);
148 483
                if (cl < 0)
149 63
                        V1L_EndChunk(v1l);
150 48361
        } else if (cl != 0 && bo->req != NULL &&
151 4074
            bo->req->req_body_status != BS_NONE) {
152 4032
                if (cl < 0)
153 1974
                        V1L_Chunked(v1l);
154 4032
                i = VRB_Iterate(wrk, bo->vsl, bo->req, VDP_ObjIterate, vdc);
155
156 4032
                if (bo->req->req_body_status != BS_CACHED)
157 4011
                        bo->no_retry = "req.body not cached";
158
159 4032
                if (bo->req->req_body_status == BS_ERROR) {
160
                        /*
161
                         * XXX: (#2332) We should test to see if the backend
162
                         * XXX: sent us some headers explaining why.
163
                         * XXX: This is hard because of the mistaken API split
164
                         * XXX: between cache_backend.c and V1F, and therefore
165
                         * XXX: Parked in this comment, pending renovation of
166
                         * XXX: the VDI/backend-protocol API to allow non-H1
167
                         * XXX: backends.
168
                         */
169 315
                        assert(i < 0);
170 630
                        VSLb(bo->vsl, SLT_FetchError,
171
                            "req.body read error: %d (%s)",
172 315
                            errno, VAS_errtxt(errno));
173 315
                        bo->req->doclose = SC_RX_BODY;
174 315
                        bo->err_code = 400;
175 315
                }
176 4032
                if (cl < 0)
177 1974
                        V1L_EndChunk(v1l);
178 4032
        }
179
180 48361
        sc = V1L_Close(&v1l, &bytes);
181 48361
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
182
183
        /* Bytes accounting */
184 48361
        *ctr_hdrbytes += hdrbytes;
185 48361
        *ctr_bodybytes += VDP_Close(vdc, NULL, NULL);
186
187 48361
        if (sc == SC_NULL && i < 0)
188 315
                sc = SC_TX_ERROR;
189
190 48363
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
191 48363
        if (sc != SC_NULL) {
192 632
                VSLb(bo->vsl, SLT_FetchError,
193
                    "backend write error: %d (%s) (%s)",
194 316
                    errno, VAS_errtxt(errno), sc->desc);
195 316
                VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
196 316
                htc->doclose = sc;
197 316
                return (-1);
198
        }
199 48047
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
200 48047
        VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
201 48047
        return (0);
202 48744
}
203
204
int
205 47666
V1F_FetchRespHdr(struct busyobj *bo)
206
{
207
208
        struct http *hp;
209
        int i;
210
        double t;
211
        struct http_conn *htc;
212
        enum htc_status_e hs;
213
        const char *name, *desc;
214
215 47666
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
216 47666
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
217 47666
        CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC);
218
219 47666
        htc = bo->htc;
220 47666
        assert(*htc->rfd > 0);
221
222 47666
        VSC_C_main->backend_req++;
223
224
        /* Receive response */
225
226 47666
        HTC_RxInit(htc, bo->ws);
227 47666
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
228 47666
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
229
230 47666
        t = VTIM_real() + htc->first_byte_timeout;
231 95332
        hs = HTC_RxStuff(htc, HTTP1_Complete, NULL, NULL,
232 47666
            t, NAN, htc->between_bytes_timeout, cache_param->http_resp_size);
233 47666
        if (hs != HTC_S_COMPLETE) {
234 987
                bo->acct.beresp_hdrbytes +=
235 987
                    htc->rxbuf_e - htc->rxbuf_b;
236 987
                switch (hs) {
237
                case HTC_S_JUNK:
238 0
                        VSLb(bo->vsl, SLT_FetchError, "Received junk");
239 0
                        htc->doclose = SC_RX_JUNK;
240 0
                        break;
241
                case HTC_S_EOF:
242 441
                        VSLb(bo->vsl, SLT_FetchError, "backend closed");
243 441
                        htc->doclose = SC_REM_CLOSE;
244 441
                        break;
245
                case HTC_S_MORE:
246 21
                        VSLb(bo->vsl, SLT_FetchError, "timeout");
247 21
                        htc->doclose = SC_RX_TIMEOUT;
248 21
                        break;
249
                case HTC_S_OVERFLOW:
250 420
                        VSLb(bo->vsl, SLT_FetchError, "overflow");
251 420
                        htc->doclose = SC_RX_OVERFLOW;
252 420
                        break;
253
                case HTC_S_EMPTY:
254 105
                        VSLb(bo->vsl, SLT_FetchError, "first byte timeout");
255 105
                        htc->doclose = SC_RX_TIMEOUT;
256 105
                        break;
257
                default:
258 0
                        HTC_Status(hs, &name, &desc);
259 0
                        VSLb(bo->vsl, SLT_FetchError, "HTC %s (%s)",
260 0
                             name, desc);
261 0
                        htc->doclose = SC_RX_BAD;
262 0
                        break;
263
                }
264 987
                return (htc->rxbuf_e == htc->rxbuf_b ? 1 : -1);
265
        }
266 46679
        VTCP_set_read_timeout(*htc->rfd, htc->between_bytes_timeout);
267
268 46679
        hp = bo->beresp;
269
270 46679
        i = HTTP1_DissectResponse(htc, hp, bo->bereq);
271 46679
        bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b;
272 46679
        htc->rxbuf_b = NULL;
273 46679
        htc->rxbuf_e = NULL;
274 46679
        if (i) {
275 483
                VSLb(bo->vsl, SLT_FetchError, "http format error");
276 483
                htc->doclose = SC_RX_JUNK;
277 483
                return (-1);
278
        }
279
280 46196
        htc->doclose = http_DoConnection(hp, SC_RESP_CLOSE);
281
282
        /*
283
         * Figure out how the fetch is supposed to happen, before the
284
         * headers are adulterated by VCL
285
         */
286 46196
        if (http_method_eq(bo->bereq->wkm, WKM_HEAD)) {
287
                /*
288
                 * A HEAD request can never have a body in the reply,
289
                 * no matter what the headers might say.
290
                 * [RFC7231 4.3.2 p25]
291
                 */
292 126
                bo->wrk->stats->fetch_head++;
293 126
                bo->htc->body_status = BS_NONE;
294 46196
        } else if (http_GetStatus(bo->beresp) <= 199) {
295
                /*
296
                 * 1xx responses never have a body.
297
                 * [RFC7230 3.3.2 p31]
298
                 * ... but we should never see them.
299
                 */
300 0
                bo->wrk->stats->fetch_1xx++;
301 0
                bo->htc->body_status = BS_ERROR;
302 46070
        } else if (http_IsStatus(bo->beresp, 204)) {
303
                /*
304
                 * 204 is "No Content", obviously don't expect a body.
305
                 * [RFC7230 3.3.1 p29 and 3.3.2 p31]
306
                 */
307 252
                bo->wrk->stats->fetch_204++;
308 252
                if ((http_GetHdr(bo->beresp, H_Content_Length, NULL) &&
309 105
                    bo->htc->content_length != 0) ||
310 147
                    http_GetHdr(bo->beresp, H_Transfer_Encoding, NULL))
311 168
                        bo->htc->body_status = BS_ERROR;
312
                else
313 84
                        bo->htc->body_status = BS_NONE;
314 45944
        } else if (http_IsStatus(bo->beresp, 304)) {
315
                /*
316
                 * 304 is "Not Modified" it has no body.
317
                 * [RFC7230 3.3 p28]
318
                 */
319 945
                bo->wrk->stats->fetch_304++;
320 945
                bo->htc->body_status = BS_NONE;
321 45818
        } else if (bo->htc->body_status == BS_CHUNKED) {
322 3128
                bo->wrk->stats->fetch_chunked++;
323 44873
        } else if (bo->htc->body_status == BS_LENGTH) {
324 23160
                assert(bo->htc->content_length > 0);
325 23160
                bo->wrk->stats->fetch_length++;
326 41745
        } else if (bo->htc->body_status == BS_EOF) {
327 483
                bo->wrk->stats->fetch_eof++;
328 18585
        } else if (bo->htc->body_status == BS_ERROR) {
329 0
                bo->wrk->stats->fetch_bad++;
330 18102
        } else if (bo->htc->body_status == BS_NONE) {
331 18102
                bo->wrk->stats->fetch_none++;
332 18102
        } else {
333 0
                WRONG("wrong bodystatus");
334
        }
335
336 46070
        assert(bo->vfc->resp == bo->beresp);
337 46070
        if (bo->htc->body_status != BS_NONE &&
338 26812
            bo->htc->body_status != BS_ERROR)
339 26775
                if (V1F_Setup_Fetch(bo->vfc, bo->htc)) {
340 336
                        VSLb(bo->vsl, SLT_FetchError, "overflow");
341 336
                        htc->doclose = SC_RX_OVERFLOW;
342 336
                        return (-1);
343
                }
344
345 45734
        return (0);
346 47540
}