varnish-cache/bin/varnishd/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_varnishd.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 83480
v1f_stackv1l(struct vdp_ctx *vdc, struct busyobj *bo)
46
{
47
        struct vrt_ctx ctx[1];
48
49 83480
        INIT_OBJ(ctx, VRT_CTX_MAGIC);
50 83480
        VCL_Bo2Ctx(ctx, bo);
51 83480
        return (VDP_Push(ctx, vdc, ctx->ws, VDP_v1l, NULL));
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 83560
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 83560
        struct vdp_ctx vdc[1] = {{ 0 }};
72
        intmax_t cl;
73 83560
        const char *err = NULL;
74
75 83560
        CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
76 83560
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
77 83560
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
78 83560
        CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC);
79 83560
        AN(ctr_hdrbytes);
80 83560
        AN(ctr_bodybytes);
81
82 83560
        htc = bo->htc;
83 83560
        assert(*htc->rfd > 0);
84 83560
        hp = bo->bereq;
85
86 83560
        if (bo->bereq_body != NULL)
87 720
                cl = ObjGetLen(wrk, bo->bereq_body);
88 82840
        else if (bo->req != NULL && !bo->req->req_body_status->length_known)
89 400
                cl = -1;
90 82440
        else if (bo->req != NULL) {
91 2800
                cl = http_GetContentLength(bo->req->http);
92 2800
                if (cl < 0)
93 840
                        cl = 0;
94 2800
        }
95
        else
96 79640
                cl = 0;
97
98 83560
        VDP_Init(vdc, wrk, bo->vsl, NULL, bo, &cl);
99 83560
        if (bo->vdp_filter_list != NULL &&
100 280
            VCL_StackVDP(vdc, bo->vcl, bo->vdp_filter_list, NULL, bo))
101 40
                err = "Failure to push processors";
102 167040
        else if (V1L_Open(wrk, wrk->aws, htc->rfd, bo->vsl, nan(""), 0),
103 83520
            wrk->v1l == NULL) {
104
                /* ^^^^^^
105
                 * XXX: need a send_timeout for the backend side
106
                 * XXX: use cache_param->http1_iovs ?
107
                 */
108 40
                err = "Failure to open V1L (workspace_thread overflow)";
109 40
        }
110 83480
        else if (v1f_stackv1l(vdc, bo))
111 640
                err = "Failure to push V1L";
112
113 83560
        if (err != NULL) {
114 721
                if (wrk->v1l != NULL)
115 640
                        (void) V1L_Close(wrk, &bytes);
116 721
                if (VALID_OBJ(vdc, VDP_CTX_MAGIC))
117 720
                        (void) VDP_Close(vdc, NULL, NULL);
118 721
                VSLb(bo->vsl, SLT_FetchError, "%s", err);
119 721
                VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
120 721
                htc->doclose = SC_OVERLOAD;
121 721
                return (-1);
122
        }
123
124 82839
        assert(cl >= -1);
125 82839
        if (cl < 0)
126 400
                http_PrintfHeader(hp, "Transfer-Encoding: chunked");
127
128 82839
        VTCP_blocking(*htc->rfd);       /* XXX: we should timeout instead */
129 82839
        hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req);
130
131
        /* Deal with any message-body the request might (still) have */
132 82839
        i = 0;
133
134 82839
        if (bo->bereq_body != NULL) {
135 720
                AZ(bo->req);
136 720
                assert(cl >= 0);
137 1440
                (void)ObjIterate(bo->wrk, bo->bereq_body,
138 720
                    vdc, VDP_ObjIterate, 0);
139 82839
        } else if (bo->req != NULL &&
140 3120
            bo->req->req_body_status != BS_NONE) {
141 2200
                if (cl < 0)
142 400
                        V1L_Chunked(wrk);
143 2200
                i = VRB_Iterate(wrk, bo->vsl, bo->req, VDP_ObjIterate, vdc);
144
145 2200
                if (bo->req->req_body_status != BS_CACHED)
146 2160
                        bo->no_retry = "req.body not cached";
147
148 2200
                if (bo->req->req_body_status == BS_ERROR) {
149
                        /*
150
                         * XXX: (#2332) We should test to see if the backend
151
                         * XXX: sent us some headers explaining why.
152
                         * XXX: This is hard because of the mistaken API split
153
                         * XXX: between cache_backend.c and V1F, and therefore
154
                         * XXX: Parked in this comment, pending renovation of
155
                         * XXX: the VDI/backend-protocol API to allow non-H1
156
                         * XXX: backends.
157
                         */
158 440
                        assert(i < 0);
159 880
                        VSLb(bo->vsl, SLT_FetchError,
160
                            "req.body read error: %d (%s)",
161 440
                            errno, VAS_errtxt(errno));
162 440
                        bo->req->doclose = SC_RX_BODY;
163 440
                }
164 2200
                if (cl < 0)
165 400
                        V1L_EndChunk(wrk);
166 2200
        }
167
168 82839
        sc = V1L_Close(wrk, &bytes);
169 82839
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
170
171
        /* Bytes accounting */
172 82839
        *ctr_hdrbytes += hdrbytes;
173 82839
        *ctr_bodybytes += VDP_Close(vdc, NULL, NULL);
174
175 82839
        if (sc == SC_NULL && i < 0)
176 440
                sc = SC_TX_ERROR;
177
178 82839
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
179 82839
        if (sc != SC_NULL) {
180 880
                VSLb(bo->vsl, SLT_FetchError,
181
                    "backend write error: %d (%s) (%s)",
182 440
                    errno, VAS_errtxt(errno), sc->desc);
183 440
                VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
184 440
                htc->doclose = sc;
185 440
                return (-1);
186
        }
187 82399
        CHECK_OBJ_NOTNULL(sc, STREAM_CLOSE_MAGIC);
188 82399
        VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk));
189 82399
        return (0);
190 83560
}
191
192
int
193 81555
V1F_FetchRespHdr(struct busyobj *bo)
194
{
195
196
        struct http *hp;
197
        int i;
198
        double t;
199
        struct http_conn *htc;
200
        enum htc_status_e hs;
201
        const char *name, *desc;
202
203 81555
        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
204 81555
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
205 81555
        CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC);
206
207 81555
        htc = bo->htc;
208 81555
        assert(*htc->rfd > 0);
209
210 81555
        VSC_C_main->backend_req++;
211
212
        /* Receive response */
213
214 81555
        HTC_RxInit(htc, bo->ws);
215 81555
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
216 81555
        CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC);
217
218 81555
        t = VTIM_real() + htc->first_byte_timeout;
219 163110
        hs = HTC_RxStuff(htc, HTTP1_Complete, NULL, NULL,
220 81555
            t, NAN, htc->between_bytes_timeout, cache_param->http_resp_size);
221 81555
        if (hs != HTC_S_COMPLETE) {
222 1600
                bo->acct.beresp_hdrbytes +=
223 1600
                    htc->rxbuf_e - htc->rxbuf_b;
224 1600
                switch (hs) {
225
                case HTC_S_JUNK:
226 0
                        VSLb(bo->vsl, SLT_FetchError, "Received junk");
227 0
                        htc->doclose = SC_RX_JUNK;
228 0
                        break;
229
                case HTC_S_CLOSE:
230 0
                        VSLb(bo->vsl, SLT_FetchError, "backend closed");
231 0
                        htc->doclose = SC_RESP_CLOSE;
232 0
                        break;
233
                case HTC_S_TIMEOUT:
234 40
                        VSLb(bo->vsl, SLT_FetchError, "timeout");
235 40
                        htc->doclose = SC_RX_TIMEOUT;
236 40
                        break;
237
                case HTC_S_OVERFLOW:
238 800
                        VSLb(bo->vsl, SLT_FetchError, "overflow");
239 800
                        htc->doclose = SC_RX_OVERFLOW;
240 800
                        break;
241
                case HTC_S_IDLE:
242 200
                        VSLb(bo->vsl, SLT_FetchError, "first byte timeout");
243 200
                        htc->doclose = SC_RX_TIMEOUT;
244 200
                        break;
245
                default:
246 560
                        HTC_Status(hs, &name, &desc);
247 1120
                        VSLb(bo->vsl, SLT_FetchError, "HTC %s (%s)",
248 560
                             name, desc);
249 560
                        htc->doclose = SC_RX_BAD;
250 560
                        break;
251
                }
252 1600
                return (htc->rxbuf_e == htc->rxbuf_b ? 1 : -1);
253
        }
254 79955
        VTCP_set_read_timeout(*htc->rfd, htc->between_bytes_timeout);
255
256 79955
        hp = bo->beresp;
257
258 79955
        i = HTTP1_DissectResponse(htc, hp, bo->bereq);
259 79955
        bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b;
260 79955
        if (i) {
261 720
                VSLb(bo->vsl, SLT_FetchError, "http format error");
262 720
                htc->doclose = SC_RX_JUNK;
263 720
                return (-1);
264
        }
265
266 79235
        htc->doclose = http_DoConnection(hp, SC_RESP_CLOSE);
267
268
        /*
269
         * Figure out how the fetch is supposed to happen, before the
270
         * headers are adulterated by VCL
271
         */
272 79235
        if (http_method_eq(http_GetMethod(bo->bereq), HEAD)) {
273
                /*
274
                 * A HEAD request can never have a body in the reply,
275
                 * no matter what the headers might say.
276
                 * [RFC7231 4.3.2 p25]
277
                 */
278 80
                bo->wrk->stats->fetch_head++;
279 80
                bo->htc->body_status = BS_NONE;
280 79235
        } else if (http_GetStatus(bo->beresp) <= 199) {
281
                /*
282
                 * 1xx responses never have a body.
283
                 * [RFC7230 3.3.2 p31]
284
                 * ... but we should never see them.
285
                 */
286 0
                bo->wrk->stats->fetch_1xx++;
287 0
                bo->htc->body_status = BS_ERROR;
288 79155
        } else if (http_IsStatus(bo->beresp, 204)) {
289
                /*
290
                 * 204 is "No Content", obviously don't expect a body.
291
                 * [RFC7230 3.3.1 p29 and 3.3.2 p31]
292
                 */
293 360
                bo->wrk->stats->fetch_204++;
294 360
                if ((http_GetHdr(bo->beresp, H_Content_Length, NULL) &&
295 160
                    bo->htc->content_length != 0) ||
296 200
                    http_GetHdr(bo->beresp, H_Transfer_Encoding, NULL))
297 240
                        bo->htc->body_status = BS_ERROR;
298
                else
299 120
                        bo->htc->body_status = BS_NONE;
300 78995
        } else if (http_IsStatus(bo->beresp, 304)) {
301
                /*
302
                 * 304 is "Not Modified" it has no body.
303
                 * [RFC7230 3.3 p28]
304
                 */
305 1320
                bo->wrk->stats->fetch_304++;
306 1320
                bo->htc->body_status = BS_NONE;
307 78795
        } else if (bo->htc->body_status == BS_CHUNKED) {
308 5600
                bo->wrk->stats->fetch_chunked++;
309 77475
        } else if (bo->htc->body_status == BS_LENGTH) {
310 41075
                assert(bo->htc->content_length > 0);
311 41075
                bo->wrk->stats->fetch_length++;
312 71875
        } else if (bo->htc->body_status == BS_EOF) {
313 920
                bo->wrk->stats->fetch_eof++;
314 30800
        } else if (bo->htc->body_status == BS_ERROR) {
315 160
                bo->wrk->stats->fetch_bad++;
316 29880
        } else if (bo->htc->body_status == BS_NONE) {
317 29720
                bo->wrk->stats->fetch_none++;
318 29720
        } else {
319 0
                WRONG("wrong bodystatus");
320
        }
321
322 79075
        assert(bo->vfc->resp == bo->beresp);
323 79075
        if (bo->htc->body_status != BS_NONE &&
324 47832
            bo->htc->body_status != BS_ERROR)
325 47595
                if (V1F_Setup_Fetch(bo->vfc, bo->htc)) {
326 640
                        VSLb(bo->vsl, SLT_FetchError, "overflow");
327 640
                        htc->doclose = SC_RX_OVERFLOW;
328 640
                        return (-1);
329
                }
330
331 78435
        return (0);
332 81395
}