43
43
static unsigned fetchfrag;
45
45
/*--------------------------------------------------------------------
46
* We want to issue the first error we encounter on fetching and
47
* supress the rest. This function does that.
49
* Other code is allowed to look at w->fetch_failed to bail out
51
* For convenience, always return -1
55
FetchError2(const struct sess *sp, const char *error, const char *more)
59
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
60
CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
63
if (!w->fetch_failed) {
65
WSP(sp, SLT_FetchError, "%s", error);
67
WSP(sp, SLT_FetchError, "%s: %s", error, more);
74
FetchError(const struct sess *sp, const char *error)
76
return(FetchError2(sp, error, NULL));
79
/*--------------------------------------------------------------------
80
* VFP method functions
84
VFP_Begin(struct sess *sp, size_t estimate)
86
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
89
sp->wrk->vfp->begin(sp, estimate);
90
if (sp->wrk->fetch_failed)
96
VFP_Bytes(struct sess *sp, struct http_conn *htc, ssize_t sz)
98
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
100
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
101
AZ(sp->wrk->fetch_failed);
103
return (sp->wrk->vfp->bytes(sp, htc, sz));
107
VFP_End(struct sess *sp)
109
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
112
return (sp->wrk->vfp->end(sp));
116
/*--------------------------------------------------------------------
48
119
* This fetch-processor does nothing but store the object.
196
262
/*--------------------------------------------------------------------*/
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)
204
269
assert(sp->wrk->body_status == BS_LENGTH);
206
cl = fetch_number(b, 10);
207
sp->wrk->vfp->begin(sp, cl > 0 ? cl : 0);
209
WSP(sp, SLT_FetchError, "straight length field bogus");
272
return (FetchError(sp, "straight length field bogus"));
211
273
} else if (cl == 0)
214
i = sp->wrk->vfp->bytes(sp, htc, cl);
276
i = VFP_Bytes(sp, htc, cl);
216
WSP(sp, SLT_FetchError, "straight read_error: %d %d (%s)",
217
i, errno, htc->error);
278
return (FetchError(sp, "straight insufficient bytes"));
223
/*--------------------------------------------------------------------*/
224
/* XXX: Cleanup. It must be possible somehow :-( */
226
#define CERR() do { \
228
WSP(sp, SLT_FetchError, \
229
"chunked read_error: %d (%s)", \
230
errno, htc->error); \
283
/*--------------------------------------------------------------------
284
* Read a chunked HTTP object.
286
* XXX: Reading one byte at a time is pretty pessimal.
236
290
fetch_chunked(struct sess *sp, struct http_conn *htc)
243
sp->wrk->vfp->begin(sp, 0);
244
297
assert(sp->wrk->body_status == BS_CHUNKED);
246
299
/* Skip leading whitespace */
248
i = HTC_Read(htc, buf, 1);
301
if (HTC_Read(sp->wrk, htc, buf, 1) <= 0)
250
303
} while (vct_islws(buf[0]));
305
if (!vct_ishex(buf[0]))
306
return (FetchError(sp,"chunked header non-hex"));
252
308
/* Collect hex digits, skipping leading zeros */
253
309
for (u = 1; u < sizeof buf; u++) {
255
i = HTC_Read(htc, buf + u, 1);
311
if (HTC_Read(sp->wrk, htc, buf + u, 1) <= 0)
257
313
} while (u == 1 && buf[0] == '0' && buf[u] == '0');
258
314
if (!vct_ishex(buf[u]))
262
318
if (u >= sizeof buf) {
263
WSP(sp, SLT_FetchError, "chunked header too long");
319
return (FetchError(sp,"chunked header too long"));
267
322
/* Skip trailing white space */
268
while(vct_islws(buf[u]) && buf[u] != '\n') {
269
i = HTC_Read(htc, buf + u, 1);
273
if (buf[u] != '\n') {
274
WSP(sp, SLT_FetchError, "chunked header char syntax");
323
while(vct_islws(buf[u]) && buf[u] != '\n')
324
if (HTC_Read(sp->wrk, htc, buf + u, 1) <= 0)
328
return (FetchError(sp,"chunked header no NL"));
279
331
cl = fetch_number(buf, 16);
281
WSP(sp, SLT_FetchError, "chunked header nbr syntax");
284
i = sp->wrk->vfp->bytes(sp, htc, cl);
287
i = HTC_Read(htc, buf, 1);
289
if (buf[0] == '\r') {
290
i = HTC_Read(htc, buf, 1);
293
if (buf[0] != '\n') {
294
WSP(sp, SLT_FetchError, "chunked tail syntax");
333
return (FetchError(sp,"chunked header number syntax"));
335
if (cl > 0 && VFP_Bytes(sp, htc, cl) <= 0)
338
i = HTC_Read(sp->wrk, htc, buf, 1);
341
if (buf[0] == '\r' && HTC_Read(sp->wrk, htc, buf, 1) <= 0)
344
return (FetchError(sp,"chunked tail no NL"));
297
345
} while (cl > 0);
303
349
/*--------------------------------------------------------------------*/
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);
314
WSP(sp, SLT_FetchError, "eof read_error: %d (%s)",
357
i = VFP_Bytes(sp, htc, SSIZE_MAX);
445
487
WSP(sp, SLT_FetchError, "http first read error: %d %d (%s)",
446
i, errno, w->htc->error);
488
i, errno, strerror(errno));
448
490
/* XXX: other cleanup ? */
449
491
/* Retryable if we never received anything */
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);
562
cls = fetch_straight(sp, w->htc, cl);
515
XXXAZ(w->vfp->end(sp));
518
cls = fetch_chunked(sp, w->htc);
568
cls = VFP_Begin(sp, cl);
570
cls = fetch_chunked(sp, w->htc);
520
XXXAZ(w->vfp->end(sp));
523
cls = fetch_eof(sp, w->htc);
576
cls = VFP_Begin(sp, cl);
578
cls = fetch_eof(sp, w->htc);
525
XXXAZ(w->vfp->end(sp));