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_esi_end(struct worker *wrk) { struct vsb *vsb; struct vef_priv *vef; struct busyobj *bo; ssize_t l; int retval; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); bo = wrk->busyobj; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); AN(bo->vep); retval = bo->fetch_failed; if (bo->vgz_rx != NULL && VGZ_Destroy(&bo->vgz_rx, -1) != VGZ_END) retval = FetchError(wrk, "Gunzip+ESI Failed at the very end"); vsb = VEP_Finish(wrk); if (vsb != NULL) { if (!retval) { l = VSB_len(vsb); assert(l > 0); /* XXX: This is a huge waste of storage... */ bo->fetch_obj->esidata = STV_alloc(wrk, l); if (bo->fetch_obj->esidata != NULL) { memcpy(bo->fetch_obj->esidata->ptr, VSB_data(vsb), l); bo->fetch_obj->esidata->len = l; } else { retval = FetchError(wrk, "Could not allocate storage for esidata"); } } VSB_delete(vsb); } vef = bo->vef_priv; if (vef != NULL) { CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); bo->vef_priv = NULL; VGZ_UpdateObj(vef->vgz, bo->fetch_obj); if (VGZ_Destroy(&vef->vgz, -1) != VGZ_END) retval = FetchError(wrk, "ESI+Gzip Failed at the very end"); FREE_OBJ(vef); } return (retval); }
vfp_gzip_end(struct busyobj *bo) { struct vgz *vg; size_t dl; const void *dp; int i; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vg = bo->vgz_rx; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); bo->vgz_rx = NULL; if (bo->state == BOS_FAILED) { (void)VGZ_Destroy(&vg); return(0); } do { VGZ_Ibuf(vg, "", 0); if (VGZ_ObufStorage(bo, vg)) return(-1); i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH); bo->fetch_obj->len += dl; } while (i != Z_STREAM_END); VGZ_UpdateObj(vg, bo->fetch_obj); if (VGZ_Destroy(&vg) != VGZ_END) return(FetchError(bo, "Gzip error at the very end")); return (0); }
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); }
struct storage * FetchStorage(struct worker *wrk, ssize_t sz) { ssize_t l; struct storage *st; struct object *obj; obj = wrk->busyobj->fetch_obj; CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); st = VTAILQ_LAST(&obj->store, storagehead); if (st != NULL && st->len < st->space) return (st); l = fetchfrag; if (l == 0) l = sz; if (l == 0) l = cache_param->fetch_chunksize; st = STV_alloc(wrk, l); if (st == NULL) { (void)FetchError(wrk, "Could not get storage"); return (NULL); } AZ(st->len); VTAILQ_INSERT_TAIL(&obj->store, st, list); return (st); }
static int fetch_straight(struct worker *wrk, struct http_conn *htc, ssize_t cl) { int i; assert(wrk->busyobj->body_status == BS_LENGTH); if (cl < 0) { return (FetchError(wrk, "straight length field bogus")); } else if (cl == 0) return (0); i = wrk->busyobj->vfp->bytes(wrk, htc, cl); if (i <= 0) return (FetchError(wrk, "straight insufficient bytes")); return (0); }
vfp_gunzip_end(struct busyobj *bo) { struct vgz *vg; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); vg = bo->vgz_rx; bo->vgz_rx = NULL; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); if (bo->state == BOS_FAILED) { (void)VGZ_Destroy(&vg); return(0); } if (VGZ_Destroy(&vg) != VGZ_END) return(FetchError(bo, "Gunzip error at the very end")); return (0); }
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); }
const nglChar* nglKernel::OnError (uint& rError) const { return FetchError(gpKernelErrorTable, NULL, rError); }
const nglChar* nglContext::OnError (uint& rError) const { return FetchError(gpContextErrorTable, NULL, rError); }