varnish-cache/bin/varnishd/cache/cache_req_body.c
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2015 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
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
 */
30
31
#include "config.h"
32
33
#include <stdlib.h>
34
35
#include "cache_varnishd.h"
36
#include "cache_filter.h"
37
#include "cache_objhead.h"
38
#include "cache_transport.h"
39
40
#include "vtim.h"
41
#include "storage/storage.h"
42
#include "hash/hash_slinger.h"
43
44
/*----------------------------------------------------------------------
45
 * Pull the req.body in via/into a objcore
46
 *
47
 * This can be called only once per request
48
 *
49
 */
50
51
static ssize_t
52 552
vrb_pull(struct req *req, ssize_t maxsize, objiterate_f *func, void *priv)
53
{
54 552
        ssize_t l, r = 0, yet;
55
        struct vfp_ctx *vfc;
56
        uint8_t *ptr;
57 552
        enum vfp_status vfps = VFP_ERROR;
58
        const struct stevedore *stv;
59
60 552
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
61
62 552
        CHECK_OBJ_NOTNULL(req->htc, HTTP_CONN_MAGIC);
63 552
        CHECK_OBJ_NOTNULL(req->vfc, VFP_CTX_MAGIC);
64 552
        vfc = req->vfc;
65
66 552
        req->body_oc = HSH_Private(req->wrk);
67 552
        AN(req->body_oc);
68
69 552
        if (req->storage != NULL)
70 12
                stv = req->storage;
71
        else
72 540
                stv = stv_transient;
73
74 552
        req->storage = NULL;
75
76 552
        XXXAN(STV_NewObject(req->wrk, req->body_oc, stv, 8));
77
78 552
        vfc->oc = req->body_oc;
79
80 552
        if (VFP_Open(vfc) < 0) {
81 0
                req->req_body_status = REQ_BODY_FAIL;
82 0
                HSH_DerefBoc(req->wrk, req->body_oc);
83 0
                AZ(HSH_DerefObjCore(req->wrk, &req->body_oc, 0));
84 0
                return (-1);
85
        }
86
87 552
        AZ(req->req_bodybytes);
88 552
        AN(req->htc);
89 552
        yet = req->htc->content_length;
90 552
        if (yet != 0 && req->want100cont) {
91 36
                req->want100cont = 0;
92 36
                (void)req->transport->minimal_response(req, 100);
93
        }
94 552
        if (yet < 0)
95 48
                yet = 0;
96
        do {
97 696
                AZ(vfc->failed);
98 696
                if (maxsize >= 0 && req->req_bodybytes > maxsize) {
99 12
                        (void)VFP_Error(vfc, "Request body too big to cache");
100 12
                        break;
101
                }
102 684
                l = yet;
103 684
                if (VFP_GetStorage(vfc, &l, &ptr) != VFP_OK)
104 0
                        break;
105 684
                AZ(vfc->failed);
106 684
                AN(ptr);
107 684
                AN(l);
108 684
                vfps = VFP_Suck(vfc, ptr, &l);
109 684
                if (l > 0 && vfps != VFP_ERROR) {
110 564
                        req->req_bodybytes += l;
111 564
                        req->acct.req_bodybytes += l;
112 564
                        if (yet >= l)
113 360
                                yet -= l;
114 564
                        if (func != NULL) {
115 432
                                r = func(priv, 1, ptr, l);
116 432
                                if (r)
117 0
                                        break;
118
                        } else {
119 132
                                ObjExtend(req->wrk, req->body_oc, l);
120
                        }
121
                }
122
123 684
        } while (vfps == VFP_OK);
124 552
        VFP_Close(vfc);
125 552
        VSLb_ts_req(req, "ReqBody", VTIM_real());
126 552
        if (func != NULL) {
127 456
                HSH_DerefBoc(req->wrk, req->body_oc);
128 456
                AZ(HSH_DerefObjCore(req->wrk, &req->body_oc, 0));
129 456
                if (vfps != VFP_END) {
130 84
                        req->req_body_status = REQ_BODY_FAIL;
131 84
                        if (r == 0)
132 84
                                r = -1;
133
                }
134 456
                return (r);
135
        }
136
137 96
        ObjTrimStore(req->wrk, req->body_oc);
138 96
        AZ(ObjSetU64(req->wrk, req->body_oc, OA_LEN, req->req_bodybytes));
139 96
        HSH_DerefBoc(req->wrk, req->body_oc);
140
141 96
        if (vfps != VFP_END) {
142 24
                req->req_body_status = REQ_BODY_FAIL;
143 24
                AZ(HSH_DerefObjCore(req->wrk, &req->body_oc, 0));
144 24
                return (-1);
145
        }
146
147 72
        assert(req->req_bodybytes >= 0);
148 72
        if (req->req_bodybytes != req->htc->content_length) {
149
                /* We must update also the "pristine" req.* copy */
150 12
                http_Unset(req->http0, H_Content_Length);
151 12
                http_Unset(req->http0, H_Transfer_Encoding);
152 12
                http_PrintfHeader(req->http0, "Content-Length: %ju",
153 12
                    (uintmax_t)req->req_bodybytes);
154
155 12
                http_Unset(req->http, H_Content_Length);
156 12
                http_Unset(req->http, H_Transfer_Encoding);
157 12
                http_PrintfHeader(req->http, "Content-Length: %ju",
158 12
                    (uintmax_t)req->req_bodybytes);
159
        }
160
161 72
        req->req_body_status = REQ_BODY_CACHED;
162 72
        return (req->req_bodybytes);
163
}
164
165
/*----------------------------------------------------------------------
166
 * Iterate over the req.body.
167
 *
168
 * This can be done exactly once if uncached, and multiple times if the
169
 * req.body is cached.
170
 *
171
 * return length or -1 on error
172
 */
173
174
ssize_t
175 588
VRB_Iterate(struct req *req, objiterate_f *func, void *priv)
176
{
177
        int i;
178
179 588
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
180 588
        AN(func);
181
182 588
        switch (req->req_body_status) {
183
        case REQ_BODY_CACHED:
184 168
                if (req->req_bodybytes > 0 &&
185 84
                    ObjIterate(req->wrk, req->body_oc, priv, func, 0))
186 0
                        return (-1);
187 84
                return (0);
188
        case REQ_BODY_NONE:
189 0
                return (0);
190
        case REQ_BODY_WITH_LEN:
191
        case REQ_BODY_WITHOUT_LEN:
192 456
                break;
193
        case REQ_BODY_TAKEN:
194 0
                VSLb(req->vsl, SLT_VCL_Error,
195
                    "Uncached req.body can only be consumed once.");
196 0
                return (-1);
197
        case REQ_BODY_FAIL:
198 48
                VSLb(req->vsl, SLT_FetchError,
199
                    "Had failed reading req.body before.");
200 48
                return (-1);
201
        default:
202 0
                WRONG("Wrong req_body_status in VRB_Iterate()");
203
        }
204 456
        Lck_Lock(&req->sp->mtx);
205 576
        if (req->req_body_status == REQ_BODY_WITH_LEN ||
206 120
            req->req_body_status == REQ_BODY_WITHOUT_LEN) {
207 456
                req->req_body_status = REQ_BODY_TAKEN;
208 456
                i = 0;
209
        } else
210 0
                i = -1;
211 456
        Lck_Unlock(&req->sp->mtx);
212 456
        if (i) {
213 0
                VSLb(req->vsl, SLT_VCL_Error,
214
                    "Multiple attempts to access non-cached req.body");
215 0
                return (i);
216
        }
217 456
        return (vrb_pull(req, -1, func, priv));
218
}
219
220
/*----------------------------------------------------------------------
221
 * VRB_Ignore() is a dedicated function, because we might
222
 * be able to disuade or terminate its transmission in some protocols.
223
 *
224
 * For HTTP1, we do nothing if we are going to close the connection anyway or
225
 * just iterate it into oblivion.
226
 */
227
228
static int v_matchproto_(objiterate_f)
229 144
httpq_req_body_discard(void *priv, int flush, const void *ptr, ssize_t len)
230
{
231
232
        (void)priv;
233
        (void)flush;
234
        (void)ptr;
235
        (void)len;
236 144
        return (0);
237
}
238
239
int
240 29736
VRB_Ignore(struct req *req)
241
{
242
243 29736
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
244
245 29736
        if (req->doclose)
246 1656
                return (0);
247 56028
        if (req->req_body_status == REQ_BODY_WITH_LEN ||
248 27948
            req->req_body_status == REQ_BODY_WITHOUT_LEN)
249 168
                (void)VRB_Iterate(req, httpq_req_body_discard, NULL);
250 28080
        return(0);
251
}
252
253
/*----------------------------------------------------------------------
254
 */
255
256
void
257 28824
VRB_Free(struct req *req)
258
{
259
260 28824
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
261
262 28824
        if (req->body_oc != NULL)
263 72
                AZ(HSH_DerefObjCore(req->wrk, &req->body_oc, 0));
264 28824
}
265
266
/*----------------------------------------------------------------------
267
 * Cache the req.body if it is smaller than the given size
268
 *
269
 * This function must be called before any backend fetches are kicked
270
 * off to prevent parallelism.
271
 */
272
273
ssize_t
274 132
VRB_Cache(struct req *req, ssize_t maxsize)
275
{
276
277 132
        CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
278 132
        assert(maxsize >= 0);
279
280
        /*
281
         * We only allow caching to happen the first time through vcl_recv{}
282
         * where we know we will have no competition or conflicts for the
283
         * updates to req.http.* etc.
284
         */
285 132
        if (req->restarts > 0 && req->req_body_status != REQ_BODY_CACHED)
286 0
                return (-1);
287
288 132
        assert (req->req_step == R_STP_RECV);
289 132
        switch (req->req_body_status) {
290
        case REQ_BODY_CACHED:
291 12
                return (req->req_bodybytes);
292
        case REQ_BODY_FAIL:
293 0
                return (-1);
294
        case REQ_BODY_NONE:
295 12
                return (0);
296
        case REQ_BODY_WITHOUT_LEN:
297
        case REQ_BODY_WITH_LEN:
298 108
                break;
299
        default:
300 0
                WRONG("Wrong req_body_status in VRB_Cache()");
301
        }
302
303 108
        if (req->htc->content_length > maxsize) {
304 12
                req->req_body_status = REQ_BODY_FAIL;
305 12
                (void)VFP_Error(req->vfc, "Request body too big to cache");
306 12
                return (-1);
307
        }
308
309 96
        return (vrb_pull(req, maxsize, NULL, NULL));
310
}