static int fetch_chunked(struct worker *wrk, struct http_conn *htc) { int i; char buf[20]; /* XXX: 20 is arbitrary */ unsigned u; ssize_t cl; assert(wrk->busyobj->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ do { if (HTC_Read(wrk, htc, buf, 1) <= 0) return (-1); } while (vct_islws(buf[0])); if (!vct_ishex(buf[0])) return (FetchError(wrk,"chunked header non-hex")); /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { if (HTC_Read(wrk, htc, buf + u, 1) <= 0) return (-1); } while (u == 1 && buf[0] == '0' && buf[u] == '0'); if (!vct_ishex(buf[u])) break; } if (u >= sizeof buf) return (FetchError(wrk,"chunked header too long")); /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') if (HTC_Read(wrk, htc, buf + u, 1) <= 0) return (-1); if (buf[u] != '\n') return (FetchError(wrk,"chunked header no NL")); buf[u] = '\0'; cl = fetch_number(buf, 16); if (cl < 0) return (FetchError(wrk,"chunked header number syntax")); if (cl > 0 && wrk->busyobj->vfp->bytes(wrk, htc, cl) <= 0) return (-1); i = HTC_Read(wrk, htc, buf, 1); if (i <= 0) return (-1); if (buf[0] == '\r' && HTC_Read(wrk, htc, buf, 1) <= 0) return (-1); if (buf[0] != '\n') return (FetchError(wrk,"chunked tail no NL")); } while (cl > 0); return (0); }
vfp_gzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; ssize_t l, wl; int i = -100; size_t dl; const void *dp; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0 || !VGZ_IbufEmpty(vg)) { if (VGZ_IbufEmpty(vg) && bytes > 0) { l = vg->m_sz; if (l > bytes) l = bytes; wl = HTC_Read(htc, vg->m_buf, l); if (wl <= 0) return (wl); VGZ_Ibuf(vg, vg->m_buf, wl); bytes -= wl; } if (VGZ_ObufStorage(bo, vg)) return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL); assert(i == Z_OK); bo->fetch_obj->len += dl; } return (1); }
vfp_gunzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; ssize_t l, wl; int i = -100; size_t dl; const void *dp; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0 || vg->vz.avail_in > 0) { if (vg->vz.avail_in == 0 && bytes > 0) { l = vg->m_sz; if (l > bytes) l = bytes; wl = HTC_Read(htc, vg->m_buf, l); if (wl <= 0) return (wl); VGZ_Ibuf(vg, vg->m_buf, wl); bytes -= wl; } if (VGZ_ObufStorage(bo, vg)) return(-1); i = VGZ_Gunzip(vg, &dp, &dl); if (i != VGZ_OK && i != VGZ_END) return(FetchError(bo, "Gunzip data error")); bo->fetch_obj->len += dl; } assert(i == Z_OK || i == Z_STREAM_END); return (1); }
int FetchReqBody(const struct sess *sp) { unsigned long content_length; char buf[8192]; char *ptr, *endp; int rdcnt; if (http_GetHdr(sp->req->http, H_Content_Length, &ptr)) { content_length = strtoul(ptr, &endp, 10); /* XXX should check result of conversion */ while (content_length) { if (content_length > sizeof buf) rdcnt = sizeof buf; else rdcnt = content_length; rdcnt = HTC_Read(sp->wrk, sp->req->htc, buf, rdcnt); if (rdcnt <= 0) return (1); content_length -= rdcnt; if (!sp->req->sendbody) continue; (void)WRW_Write(sp->wrk, buf, rdcnt); /* XXX: stats ? */ if (WRW_Flush(sp->wrk)) return (2); } } if (http_GetHdr(sp->req->http, H_Transfer_Encoding, NULL)) { /* XXX: Handle chunked encoding. */ WSP(sp, SLT_Debug, "Transfer-Encoding in request"); return (1); } return (0); }
vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes) { ssize_t l, w; struct storage *st; while (bytes > 0) { st = FetchStorage(sp, 0); if (st == NULL) { htc->error = "Could not get storage"; return (-1); } l = st->space - st->len; if (l > bytes) l = bytes; w = HTC_Read(htc, st->ptr + st->len, l); if (w <= 0) return (w); st->len += w; sp->obj->len += w; bytes -= w; if (sp->wrk->do_stream) RES_StreamPoll(sp); } return (1); }
static ssize_t vef_read(struct http_conn *htc, void *buf, ssize_t buflen, ssize_t bytes) { ssize_t d; if (buflen < bytes) bytes = buflen; if (params->esi_syntax & 0x8) { d = (random() & 3) + 1; if (d < bytes) bytes = d; } return (HTC_Read(htc, buf, bytes)); }
vfp_testgzip_bytes(struct busyobj *bo, struct http_conn *htc, ssize_t bytes) { struct vgz *vg; ssize_t l, wl; int i = -100; size_t dl; const void *dp; struct storage *st; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AZ(vg->vz.avail_in); while (bytes > 0) { st = FetchStorage(bo, 0); if (st == NULL) return(-1); l = st->space - st->len; if (l > bytes) l = bytes; wl = HTC_Read(htc, st->ptr + st->len, l); if (wl <= 0) return (wl); bytes -= wl; VGZ_Ibuf(vg, st->ptr + st->len, wl); st->len += wl; bo->fetch_obj->len += wl; while (!VGZ_IbufEmpty(vg)) { VGZ_Obuf(vg, vg->m_buf, vg->m_sz); i = VGZ_Gunzip(vg, &dp, &dl); if (i == VGZ_END && !VGZ_IbufEmpty(vg)) return(FetchError(bo, "Junk after gzip data")); if (i != VGZ_OK && i != VGZ_END) return(FetchError2(bo, "Invalid Gzip data", vg->vz.msg)); } } assert(i == VGZ_OK || i == VGZ_END); return (1); }
vfp_nop_bytes(struct worker *wrk, struct http_conn *htc, ssize_t bytes) { ssize_t l, wl; struct storage *st; AZ(wrk->busyobj->fetch_failed); while (bytes > 0) { st = FetchStorage(wrk, 0); if (st == NULL) return(-1); l = st->space - st->len; if (l > bytes) l = bytes; wl = HTC_Read(wrk, htc, st->ptr + st->len, l); if (wl <= 0) return (wl); st->len += wl; wrk->busyobj->fetch_obj->len += wl; bytes -= wl; if (wrk->busyobj->do_stream) RES_StreamPoll(wrk); } return (1); }
static int fetch_chunked(struct sess *sp, struct http_conn *htc) { int i; char buf[20]; /* XXX: 20 is arbitrary */ unsigned u; ssize_t cl; sp->wrk->vfp->begin(sp, 0); assert(sp->wrk->body_status == BS_CHUNKED); do { /* Skip leading whitespace */ do { i = HTC_Read(htc, buf, 1); CERR(); } while (vct_islws(buf[0])); /* Collect hex digits, skipping leading zeros */ for (u = 1; u < sizeof buf; u++) { do { i = HTC_Read(htc, buf + u, 1); CERR(); } while (u == 1 && buf[0] == '0' && buf[u] == '0'); if (!vct_ishex(buf[u])) break; } if (u >= sizeof buf) { WSP(sp, SLT_FetchError, "chunked header too long"); return (-1); } /* Skip trailing white space */ while(vct_islws(buf[u]) && buf[u] != '\n') { i = HTC_Read(htc, buf + u, 1); CERR(); } if (buf[u] != '\n') { WSP(sp, SLT_FetchError, "chunked header char syntax"); return (-1); } buf[u] = '\0'; cl = fetch_number(buf, 16); if (cl < 0) { WSP(sp, SLT_FetchError, "chunked header nbr syntax"); return (-1); } else if (cl > 0) { i = sp->wrk->vfp->bytes(sp, htc, cl); CERR(); } i = HTC_Read(htc, buf, 1); CERR(); if (buf[0] == '\r') { i = HTC_Read(htc, buf, 1); CERR(); } if (buf[0] != '\n') { WSP(sp, SLT_FetchError, "chunked tail syntax"); return (-1); } } while (cl > 0); return (0); }