~ubuntu-branches/ubuntu/trusty/varnish/trusty-proposed

« back to all changes in this revision

Viewing changes to bin/varnishd/cache_fetch.c

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen, Stig Sandbeck Mathisen, Tollef Fog Heen
  • Date: 2013-05-05 15:53:14 UTC
  • mfrom: (0.1.16)
  • Revision ID: package-import@ubuntu.com-20130505155314-i99wuol99cfwzrtv
Tags: 3.0.3-1
[ Stig Sandbeck Mathisen ]
* New upstream release

[ Tollef Fog Heen ]
* Make varnishlog's and varnishncsa's init script exit with the exit
  status of status_of_proc to make them useful.  Fixes upstream trac
  #1226.

[ Stig Sandbeck Mathisen ]
* Do not rewrite /etc/default/varnish on upgrade.
  Thanks to Andreas Beckmann <anbe@debian.org> (Closes: 698577)
* Undo mangling of /etc/default/varnish that happened during lenny->squeeze
  upgrade.
  Thanks to Andreas Beckmann <anbe@debian.org> (Closes: 698577)

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
static unsigned fetchfrag;
44
44
 
45
45
/*--------------------------------------------------------------------
 
46
 * We want to issue the first error we encounter on fetching and
 
47
 * supress the rest.  This function does that.
 
48
 *
 
49
 * Other code is allowed to look at w->fetch_failed to bail out
 
50
 *
 
51
 * For convenience, always return -1
 
52
 */
 
53
 
 
54
int
 
55
FetchError2(const struct sess *sp, const char *error, const char *more)
 
56
{
 
57
        struct worker *w;
 
58
 
 
59
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
60
        CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
 
61
        w = sp->wrk;
 
62
 
 
63
        if (!w->fetch_failed) {
 
64
                if (more == NULL)
 
65
                        WSP(sp, SLT_FetchError, "%s", error);
 
66
                else
 
67
                        WSP(sp, SLT_FetchError, "%s: %s", error, more);
 
68
        }
 
69
        w->fetch_failed = 1;
 
70
        return (-1);
 
71
}
 
72
 
 
73
int
 
74
FetchError(const struct sess *sp, const char *error)
 
75
{
 
76
        return(FetchError2(sp, error, NULL));
 
77
}
 
78
 
 
79
/*--------------------------------------------------------------------
 
80
 * VFP method functions
 
81
 */
 
82
 
 
83
static int
 
84
VFP_Begin(struct sess *sp, size_t estimate)
 
85
{
 
86
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
87
        AN(sp->wrk->vfp);
 
88
 
 
89
        sp->wrk->vfp->begin(sp, estimate);
 
90
        if (sp->wrk->fetch_failed)
 
91
                return (-1);
 
92
        return (0);
 
93
}
 
94
 
 
95
static int
 
96
VFP_Bytes(struct sess *sp, struct http_conn *htc, ssize_t sz)
 
97
{
 
98
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
99
        AN(sp->wrk->vfp);
 
100
        CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
 
101
        AZ(sp->wrk->fetch_failed);
 
102
 
 
103
        return (sp->wrk->vfp->bytes(sp, htc, sz));
 
104
}
 
105
 
 
106
static int
 
107
VFP_End(struct sess *sp)
 
108
{
 
109
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
110
        AN(sp->wrk->vfp);
 
111
 
 
112
        return (sp->wrk->vfp->end(sp));
 
113
}
 
114
 
 
115
 
 
116
/*--------------------------------------------------------------------
46
117
 * VFP_NOP
47
118
 *
48
119
 * This fetch-processor does nothing but store the object.
61
132
vfp_nop_begin(struct sess *sp, size_t estimate)
62
133
{
63
134
 
64
 
        if (fetchfrag > 0) {
65
 
                estimate = fetchfrag;
66
 
                WSL(sp->wrk, SLT_Debug, sp->fd,
67
 
                    "Fetch %d byte segments:", fetchfrag);
68
 
        }
69
135
        if (estimate > 0)
70
136
                (void)FetchStorage(sp, estimate);
71
137
}
75
141
 *
76
142
 * Process (up to) 'bytes' from the socket.
77
143
 *
78
 
 * Return -1 on error
 
144
 * Return -1 on error, issue FetchError()
 
145
 *      will not be called again, once error happens.
79
146
 * Return 0 on EOF on socket even if bytes not reached.
80
147
 * Return 1 when 'bytes' have been processed.
81
148
 */
88
155
 
89
156
        while (bytes > 0) {
90
157
                st = FetchStorage(sp, 0);
91
 
                if (st == NULL) {
92
 
                        htc->error = "Could not get storage";
93
 
                        return (-1);
94
 
                }
 
158
                if (st == NULL)
 
159
                        return(-1);
95
160
                l = st->space - st->len;
96
161
                if (l > bytes)
97
162
                        l = bytes;
98
 
                w = HTC_Read(htc, st->ptr + st->len, l);
 
163
                w = HTC_Read(sp->wrk, htc, st->ptr + st->len, l);
99
164
                if (w <= 0)
100
 
                        return (w);
 
165
                        return(w);
101
166
                st->len += w;
102
167
                sp->obj->len += w;
103
168
                bytes -= w;
142
207
};
143
208
 
144
209
/*--------------------------------------------------------------------
145
 
 * Fetch Storage
 
210
 * Fetch Storage to put object into.
 
211
 *
146
212
 */
147
213
 
148
214
struct storage *
162
228
                l = params->fetch_chunksize * 1024LL;
163
229
        st = STV_alloc(sp, l);
164
230
        if (st == NULL) {
165
 
                errno = ENOMEM;
 
231
                (void)FetchError(sp, "Could not get storage");
166
232
                return (NULL);
167
233
        }
168
234
        AZ(st->len);
196
262
/*--------------------------------------------------------------------*/
197
263
 
198
264
static int
199
 
fetch_straight(struct sess *sp, struct http_conn *htc, const char *b)
 
265
fetch_straight(struct sess *sp, struct http_conn *htc, ssize_t cl)
200
266
{
201
267
        int i;
202
 
        ssize_t cl;
203
268
 
204
269
        assert(sp->wrk->body_status == BS_LENGTH);
205
270
 
206
 
        cl = fetch_number(b, 10);
207
 
        sp->wrk->vfp->begin(sp, cl > 0 ? cl : 0);
208
271
        if (cl < 0) {
209
 
                WSP(sp, SLT_FetchError, "straight length field bogus");
210
 
                return (-1);
 
272
                return (FetchError(sp, "straight length field bogus"));
211
273
        } else if (cl == 0)
212
274
                return (0);
213
275
 
214
 
        i = sp->wrk->vfp->bytes(sp, htc, cl);
 
276
        i = VFP_Bytes(sp, htc, cl);
215
277
        if (i <= 0) {
216
 
                WSP(sp, SLT_FetchError, "straight read_error: %d %d (%s)",
217
 
                    i, errno, htc->error);
218
 
                return (-1);
 
278
                return (FetchError(sp, "straight insufficient bytes"));
219
279
        }
220
280
        return (0);
221
281
}
222
282
 
223
 
/*--------------------------------------------------------------------*/
224
 
/* XXX: Cleanup.  It must be possible somehow :-( */
225
 
 
226
 
#define CERR() do {                                             \
227
 
                if (i != 1) {                                   \
228
 
                        WSP(sp, SLT_FetchError,                 \
229
 
                            "chunked read_error: %d (%s)",      \
230
 
                            errno, htc->error);                 \
231
 
                        return (-1);                            \
232
 
                }                                               \
233
 
        } while (0)
 
283
/*--------------------------------------------------------------------
 
284
 * Read a chunked HTTP object.
 
285
 *
 
286
 * XXX: Reading one byte at a time is pretty pessimal.
 
287
 */
234
288
 
235
289
static int
236
290
fetch_chunked(struct sess *sp, struct http_conn *htc)
240
294
        unsigned u;
241
295
        ssize_t cl;
242
296
 
243
 
        sp->wrk->vfp->begin(sp, 0);
244
297
        assert(sp->wrk->body_status == BS_CHUNKED);
245
298
        do {
246
299
                /* Skip leading whitespace */
247
300
                do {
248
 
                        i = HTC_Read(htc, buf, 1);
249
 
                        CERR();
 
301
                        if (HTC_Read(sp->wrk, htc, buf, 1) <= 0)
 
302
                                return (-1);
250
303
                } while (vct_islws(buf[0]));
251
304
 
 
305
                if (!vct_ishex(buf[0]))
 
306
                        return (FetchError(sp,"chunked header non-hex"));
 
307
 
252
308
                /* Collect hex digits, skipping leading zeros */
253
309
                for (u = 1; u < sizeof buf; u++) {
254
310
                        do {
255
 
                                i = HTC_Read(htc, buf + u, 1);
256
 
                                CERR();
 
311
                                if (HTC_Read(sp->wrk, htc, buf + u, 1) <= 0)
 
312
                                        return (-1);
257
313
                        } while (u == 1 && buf[0] == '0' && buf[u] == '0');
258
314
                        if (!vct_ishex(buf[u]))
259
315
                                break;
260
316
                }
261
317
 
262
318
                if (u >= sizeof buf) {
263
 
                        WSP(sp, SLT_FetchError, "chunked header too long");
264
 
                        return (-1);
 
319
                        return (FetchError(sp,"chunked header too long"));
265
320
                }
266
321
 
267
322
                /* Skip trailing white space */
268
 
                while(vct_islws(buf[u]) && buf[u] != '\n') {
269
 
                        i = HTC_Read(htc, buf + u, 1);
270
 
                        CERR();
271
 
                }
272
 
 
273
 
                if (buf[u] != '\n') {
274
 
                        WSP(sp, SLT_FetchError, "chunked header char syntax");
275
 
                        return (-1);
276
 
                }
 
323
                while(vct_islws(buf[u]) && buf[u] != '\n')
 
324
                        if (HTC_Read(sp->wrk, htc, buf + u, 1) <= 0)
 
325
                                return (-1);
 
326
 
 
327
                if (buf[u] != '\n') 
 
328
                        return (FetchError(sp,"chunked header no NL"));
 
329
 
277
330
                buf[u] = '\0';
278
 
 
279
331
                cl = fetch_number(buf, 16);
280
 
                if (cl < 0) {
281
 
                        WSP(sp, SLT_FetchError, "chunked header nbr syntax");
282
 
                        return (-1);
283
 
                } else if (cl > 0) {
284
 
                        i = sp->wrk->vfp->bytes(sp, htc, cl);
285
 
                        CERR();
286
 
                }
287
 
                i = HTC_Read(htc, buf, 1);
288
 
                CERR();
289
 
                if (buf[0] == '\r') {
290
 
                        i = HTC_Read(htc, buf, 1);
291
 
                        CERR();
292
 
                }
293
 
                if (buf[0] != '\n') {
294
 
                        WSP(sp, SLT_FetchError, "chunked tail syntax");
295
 
                        return (-1);
296
 
                }
 
332
                if (cl < 0)
 
333
                        return (FetchError(sp,"chunked header number syntax"));
 
334
 
 
335
                if (cl > 0 && VFP_Bytes(sp, htc, cl) <= 0)
 
336
                        return (-1);
 
337
 
 
338
                i = HTC_Read(sp->wrk, htc, buf, 1);
 
339
                if (i <= 0)
 
340
                        return (-1);
 
341
                if (buf[0] == '\r' && HTC_Read(sp->wrk, htc, buf, 1) <= 0)
 
342
                        return (-1);
 
343
                if (buf[0] != '\n')
 
344
                        return (FetchError(sp,"chunked tail no NL"));
297
345
        } while (cl > 0);
298
346
        return (0);
299
347
}
300
348
 
301
 
#undef CERR
302
 
 
303
349
/*--------------------------------------------------------------------*/
304
350
 
305
351
static int
308
354
        int i;
309
355
 
310
356
        assert(sp->wrk->body_status == BS_EOF);
311
 
        sp->wrk->vfp->begin(sp, 0);
312
 
        i = sp->wrk->vfp->bytes(sp, htc, SSIZE_MAX);
313
 
        if (i < 0) {
314
 
                WSP(sp, SLT_FetchError, "eof read_error: %d (%s)",
315
 
                    errno, htc->error);
 
357
        i = VFP_Bytes(sp, htc, SSIZE_MAX);
 
358
        if (i < 0) 
316
359
                return (-1);
317
 
        }
318
360
        return (0);
319
361
}
320
362
 
342
384
                                rdcnt = sizeof buf;
343
385
                        else
344
386
                                rdcnt = content_length;
345
 
                        rdcnt = HTC_Read(sp->htc, buf, rdcnt);
 
387
                        rdcnt = HTC_Read(sp->wrk, sp->htc, buf, rdcnt);
346
388
                        if (rdcnt <= 0)
347
389
                                return (1);
348
390
                        content_length -= rdcnt;
443
485
 
444
486
        if (i < 0) {
445
487
                WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)",
446
 
                    i, errno, w->htc->error);
 
488
                    i, errno, strerror(errno));
447
489
                VDI_CloseFd(sp);
448
490
                /* XXX: other cleanup ? */
449
491
                /* Retryable if we never received anything */
457
499
                if (i < 0) {
458
500
                        WSP(sp, SLT_FetchError,
459
501
                            "http first read error: %d %d (%s)",
460
 
                            i, errno, w->htc->error);
 
502
                            i, errno, strerror(errno));
461
503
                        VDI_CloseFd(sp);
462
504
                        /* XXX: other cleanup ? */
463
505
                        return (-1);
484
526
        struct storage *st;
485
527
        struct worker *w;
486
528
        int mklen;
 
529
        ssize_t cl;
487
530
 
488
531
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
489
532
        CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
499
542
 
500
543
        AZ(w->vgz_rx);
501
544
        AZ(VTAILQ_FIRST(&sp->obj->store));
 
545
 
 
546
        /* XXX: pick up estimate from objdr ? */
 
547
        cl = 0;
 
548
        w->fetch_failed = 0;
502
549
        switch (w->body_status) {
503
550
        case BS_NONE:
504
551
                cls = 0;
509
556
                mklen = 1;
510
557
                break;
511
558
        case BS_LENGTH:
512
 
                cls = fetch_straight(sp, w->htc,
513
 
                    w->h_content_length);
 
559
                cl = fetch_number(sp->wrk->h_content_length, 10);
 
560
                cls = VFP_Begin(sp, cl > 0 ? cl : 0);
 
561
                if (!cls)
 
562
                        cls = fetch_straight(sp, w->htc, cl);
514
563
                mklen = 1;
515
 
                XXXAZ(w->vfp->end(sp));
 
564
                if (VFP_End(sp))
 
565
                        cls = -1;
516
566
                break;
517
567
        case BS_CHUNKED:
518
 
                cls = fetch_chunked(sp, w->htc);
 
568
                cls = VFP_Begin(sp, cl);
 
569
                if (!cls)
 
570
                        cls = fetch_chunked(sp, w->htc);
519
571
                mklen = 1;
520
 
                XXXAZ(w->vfp->end(sp));
 
572
                if (VFP_End(sp))
 
573
                        cls = -1;
521
574
                break;
522
575
        case BS_EOF:
523
 
                cls = fetch_eof(sp, w->htc);
 
576
                cls = VFP_Begin(sp, cl);
 
577
                if (!cls)
 
578
                        cls = fetch_eof(sp, w->htc);
524
579
                mklen = 1;
525
 
                XXXAZ(w->vfp->end(sp));
 
580
                if (VFP_End(sp))
 
581
                        cls = -1;
526
582
                break;
527
583
        case BS_ERROR:
528
584
                cls = 1;
563
619
                sp->obj->len = 0;
564
620
                return (__LINE__);
565
621
        }
 
622
        AZ(w->fetch_failed);
566
623
 
567
624
        if (cls == 0 && w->do_close)
568
625
                cls = 1;