static int vfp_esi_bytes_gg(const struct busyobj *bo, struct vef_priv *vef, struct http_conn *htc, size_t bytes) { ssize_t wl; size_t dl; const void *dp; enum vgzret_e vr; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); while (bytes > 0) { wl = vef_read(htc, vef->ibuf2, vef->ibuf2_sz, bytes); if (wl <= 0) return (wl); bytes -= wl; VGZ_Ibuf(bo->vgz_rx, vef->ibuf2, wl); do { wl = vef->ibuf_sz - (vef->ibuf_i - vef->ibuf); VGZ_Obuf(bo->vgz_rx, vef->ibuf_i, wl); vr = VGZ_Gunzip(bo->vgz_rx, &dp, &dl); if (vr < VGZ_OK) return (-1); if (dl > 0 && vfp_vep_inject(bo, vef, dl)) return (-1); } while (!VGZ_IbufEmpty(bo->vgz_rx)); } return (1); }
int VGZ_WrwInit(struct vgz *vg) { CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); if (vgz_getmbuf(vg)) return (-1); VGZ_Obuf(vg, vg->m_buf, vg->m_sz); return (0); }
int VGZ_ObufStorage(struct busyobj *bo, struct vgz *vg) { struct storage *st; st = VFP_GetStorage(bo, 0); if (st == NULL) return (-1); VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len); return (0); }
int VGZ_ObufStorage(struct busyobj *bo, struct vgz *vg) { struct storage *st; st = FetchStorage(bo, 0); if (st == NULL) return (-1); vg->st_obuf = st; VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len); return (0); }
static int vfp_esi_bytes_gg(struct worker *wrk, struct http_conn *htc, size_t bytes) { ssize_t wl; char ibuf[cache_param->gzip_stack_buffer]; char ibuf2[cache_param->gzip_stack_buffer]; struct vef_priv *vef; size_t dl; const void *dp; int i; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); vef = wrk->busyobj->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); assert(sizeof ibuf >= 1024); ibuf2[0] = 0; /* For Flexelint */ while (bytes > 0) { wl = vef_read(wrk, htc, ibuf, sizeof ibuf, bytes); if (wl <= 0) return (wl); bytes -= wl; vef->bufp = ibuf; VGZ_Ibuf(wrk->busyobj->vgz_rx, ibuf, wl); do { VGZ_Obuf(wrk->busyobj->vgz_rx, ibuf2, sizeof ibuf2); i = VGZ_Gunzip(wrk->busyobj->vgz_rx, &dp, &dl); /* XXX: check i */ assert(i >= VGZ_OK); vef->bufp = ibuf2; if (dl > 0) VEP_Parse(wrk, ibuf2, dl); if (vef->error) { errno = vef->error; return (-1); } if (vef->bufp < ibuf2 + dl) { dl = (ibuf2 + dl) - vef->bufp; assert(dl + vef->npend < sizeof vef->pending); memmove(vef->pending + vef->npend, vef->bufp, dl); vef->npend += dl; } } while (!VGZ_IbufEmpty(wrk->busyobj->vgz_rx)); } return (1); }
static ssize_t vfp_vep_callback(struct vfp_ctx *vc, void *priv, ssize_t l, enum vgz_flag flg) { struct vef_priv *vef; ssize_t dl; const void *dp; uint8_t *ptr; int i; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CAST_OBJ_NOTNULL(vef, priv, VEF_MAGIC); assert(l >= 0); if (vef->error) { vef->tot += l; return (vef->tot); } /* * l == 0 is valid when 'flg' calls for action, but in the * normal case we can just ignore a l==0 request. * (It would cause Z_BUF_ERROR anyway) */ if (l == 0 && flg == VGZ_NORMAL) return (vef->tot); CHECK_OBJ_NOTNULL(vc->bo, BUSYOBJ_MAGIC); VGZ_Ibuf(vef->vgz, vef->ibuf_o, l); do { dl = 0; if (VFP_GetStorage(vc, &dl, &ptr) != VFP_OK) { vef->error = ENOMEM; vef->tot += l; return (vef->tot); } VGZ_Obuf(vef->vgz, ptr, dl); i = VGZ_Gzip(vef->vgz, &dp, &dl, flg); VGZ_UpdateObj(vc, vef->vgz, VUA_UPDATE); if (dl > 0) { vef->tot += dl; VFP_Extend(vc, dl); } } while (i != VGZ_ERROR && (!VGZ_IbufEmpty(vef->vgz) || VGZ_ObufFull(vef->vgz))); assert(i == VGZ_ERROR || VGZ_IbufEmpty(vef->vgz)); vef->ibuf_o += l; return (vef->tot); }
vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes) { ssize_t w; char ibuf[params->gzip_stack_buffer]; char ibuf2[params->gzip_stack_buffer]; struct vef_priv *vef; size_t dl; const void *dp; int i; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); vef = sp->wrk->vef_priv; CHECK_OBJ_NOTNULL(vef, VEF_MAGIC); assert(sizeof ibuf >= 1024); ibuf2[0] = 0; /* For Flexelint */ while (bytes > 0) { w = vef_read(htc, ibuf, sizeof ibuf, bytes); if (w <= 0) return (w); bytes -= w; vef->bufp = ibuf; VGZ_Ibuf(sp->wrk->vgz_rx, ibuf, w); do { VGZ_Obuf(sp->wrk->vgz_rx, ibuf2, sizeof ibuf2); i = VGZ_Gunzip(sp->wrk->vgz_rx, &dp, &dl); /* XXX: check i */ assert(i >= VGZ_OK); vef->bufp = ibuf2; if (dl > 0) VEP_parse(sp, ibuf2, dl); if (vef->error) { errno = vef->error; return (-1); } if (vef->bufp < ibuf2 + dl) { dl = (ibuf2 + dl) - vef->bufp; assert(dl + vef->npend < sizeof vef->pending); memmove(vef->pending + vef->npend, vef->bufp, dl); vef->npend += dl; } } while (!VGZ_IbufEmpty(sp->wrk->vgz_rx)); } return (1); }
vfp_gzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { ssize_t l; struct vgz *vg; enum vgzret_e vr = VGZ_ERROR; const void *dp; ssize_t dl; enum vfp_status vp = VFP_ERROR; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); AN(p); AN(lp); l = *lp; *lp = 0; VGZ_Obuf(vg, p, l); do { if (VGZ_IbufEmpty(vg)) { l = vg->m_sz; vp = VFP_Suck(vc, vg->m_buf, &l); if (vp == VFP_ERROR) break; if (vp == VFP_END) vg->flag = VGZ_FINISH; VGZ_Ibuf(vg, vg->m_buf, l); } if (!VGZ_IbufEmpty(vg) || vg->flag == VGZ_FINISH) { vr = VGZ_Gzip(vg, &dp, &dl, vg->flag); if (vr < VGZ_OK) return (VFP_Error(vc, "Gzip failed")); if (dl > 0) { VGZ_UpdateObj(vc, vg, VUA_UPDATE); *lp = dl; assert(dp == p); return (VFP_OK); } } AN(VGZ_IbufEmpty(vg)); } while (vg->flag != VGZ_FINISH); if (vr != VGZ_END) return (VFP_Error(vc, "Gzip failed")); VGZ_UpdateObj(vc, vg, VUA_END_GZIP); return (VFP_END); }
void VGZ_WrwFlush(struct req *req, struct vgz *vg) { struct worker *wrk; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); if (vg->m_len == 0) return; (void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); }
vfp_gunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { ssize_t l; struct vgz *vg; enum vgzret_e vr = VGZ_ERROR; const void *dp; ssize_t dl; enum vfp_status vp = VFP_OK; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); AN(p); AN(lp); l = *lp; *lp = 0; VGZ_Obuf(vg, p, l); do { if (VGZ_IbufEmpty(vg)) { l = vg->m_sz; vp = VFP_Suck(vc, vg->m_buf, &l); if (vp == VFP_ERROR) return (vp); VGZ_Ibuf(vg, vg->m_buf, l); } if (!VGZ_IbufEmpty(vg) || vp == VFP_END) { vr = VGZ_Gunzip(vg, &dp, &dl); if (vr == VGZ_END && !VGZ_IbufEmpty(vg)) return(VFP_Error(vc, "Junk after gzip data")); if (vr < VGZ_OK) return (VFP_Error(vc, "Invalid Gzip data: %s", vgz_msg(vg))); if (dl > 0) { *lp = dl; assert(dp == p); return (VFP_OK); } } AN(VGZ_IbufEmpty(vg)); } while (vp == VFP_OK); if (vr != VGZ_END) return(VFP_Error(vc, "Gunzip error at the very end")); return (vp); }
static ssize_t vfp_vep_callback(struct busyobj *bo, void *priv, ssize_t l, enum vgz_flag flg) { struct vef_priv *vef; size_t dl; const void *dp; struct storage *st; int i; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CAST_OBJ_NOTNULL(vef, priv, VEF_MAGIC); assert(l >= 0); if (vef->error) { vef->tot += l; return (vef->tot); } /* * l == 0 is valid when 'flg' calls for action, but in the * normal case we can just ignore a l==0 request. * (It would cause Z_BUF_ERROR anyway) */ if (l == 0 && flg == VGZ_NORMAL) return (vef->tot); VGZ_Ibuf(vef->vgz, vef->ibuf_o, l); do { st = VFP_GetStorage(bo, 0); if (st == NULL) { vef->error = ENOMEM; vef->tot += l; return (vef->tot); } VGZ_Obuf(vef->vgz, st->ptr + st->len, st->space - st->len); i = VGZ_Gzip(vef->vgz, &dp, &dl, flg); vef->tot += dl; VBO_extend(bo, dl); } while (i != VGZ_ERROR && (!VGZ_IbufEmpty(vef->vgz) || VGZ_ObufFull(vef->vgz))); assert(i == VGZ_ERROR || VGZ_IbufEmpty(vef->vgz)); vef->ibuf_o += l; return (vef->tot); }
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); }
VDP_gunzip(struct req *req, enum vdp_action act, const void *ptr, ssize_t len) { enum vgzret_e vr; size_t dl; const void *dp; struct worker *wrk; struct vgz *vg; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); vg = req->vgz; CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AN(vg->m_buf); if (len == 0) { AN(act > VDP_NULL); return (VDP_bytes(req, act, vg->m_buf, vg->m_len)); } VGZ_Ibuf(vg, ptr, len); do { if (vg->m_len == vg->m_sz) vr = VGZ_STUCK; else { vr = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; } if (vr < VGZ_OK) return (-1); if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) { if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len)) return (-1); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END); return (0); }
vfp_testgunzip_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *p, ssize_t *lp) { struct vgz *vg; enum vgzret_e vr = VGZ_ERROR; const void *dp; ssize_t dl; enum vfp_status vp; CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); AN(p); AN(lp); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); vp = VFP_Suck(vc, p, lp); if (vp == VFP_ERROR) return (vp); if (*lp > 0 || vp == VFP_END) { VGZ_Ibuf(vg, p, *lp); do { VGZ_Obuf(vg, vg->m_buf, vg->m_sz); vr = VGZ_Gunzip(vg, &dp, &dl); if (vr == VGZ_END && !VGZ_IbufEmpty(vg)) return(VFP_Error(vc, "Junk after gzip data")); if (vr < VGZ_OK) return (VFP_Error(vc, "Invalid Gzip data: %s", vgz_msg(vg))); } while (!VGZ_IbufEmpty(vg)); } VGZ_UpdateObj(vc, vg, VUA_UPDATE); if (vp == VFP_END) { if (vr != VGZ_END) return (VFP_Error(vc, "tGunzip failed")); VGZ_UpdateObj(vc, vg, VUA_END_GUNZIP); } return (vp); }
vfp_testgunzip_pull(struct busyobj *bo, struct vfp_entry *vfe, void *p, ssize_t *lp) { struct vgz *vg; enum vgzret_e vr = VGZ_ERROR; const void *dp; size_t dl; enum vfp_status vp; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); AN(p); AN(lp); CAST_OBJ_NOTNULL(vg, vfe->priv1, VGZ_MAGIC); vp = VFP_Suck(bo, p, lp); if (vp == VFP_ERROR) return (vp); if (*lp > 0 || vp == VFP_END) { VGZ_Ibuf(vg, p, *lp); do { VGZ_Obuf(vg, vg->m_buf, vg->m_sz); vr = VGZ_Gunzip(vg, &dp, &dl); if (vr == VGZ_END && !VGZ_IbufEmpty(vg)) return(VFP_Error(bo, "Junk after gzip data")); if (vr < VGZ_OK) return (VFP_Error(bo, "Invalid Gzip data: %s", vg->vz.msg)); } while (!VGZ_IbufEmpty(vg)); } if (vp == VFP_END) { if (vr != VGZ_END) return (VFP_Error(bo, "tGunzip failed")); VGZ_UpdateObj(vg, bo->fetch_obj); } return (vp); }
int VGZ_WrwGunzip(struct worker *wrk, struct vgz *vg, const void *ibuf, ssize_t ibufl) { int i; size_t dl; const void *dp; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AN(vg->m_buf); VGZ_Ibuf(vg, ibuf, ibufl); if (ibufl == 0) return (VGZ_OK); do { if (vg->m_len == vg->m_sz) i = VGZ_STUCK; else { i = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; } if (i < VGZ_OK) { /* XXX: VSL ? */ return (-1); } if (vg->m_len == vg->m_sz || i == VGZ_STUCK) { wrk->acct_tmp.bodybytes += vg->m_len; (void)WRW_Write(wrk, vg->m_buf, vg->m_len); (void)WRW_Flush(wrk); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); if (i == VGZ_STUCK) i = VGZ_OK; return (i); }
enum vgzret_e VGZ_WrwGunzip(struct req *req, struct vgz *vg, const void *ibuf, ssize_t ibufl) { enum vgzret_e vr; size_t dl; const void *dp; struct worker *wrk; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC); AN(vg->m_buf); VGZ_Ibuf(vg, ibuf, ibufl); if (ibufl == 0) return (VGZ_OK); do { if (vg->m_len == vg->m_sz) vr = VGZ_STUCK; else { vr = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; } if (vr < VGZ_OK) return (vr); if (vg->m_len == vg->m_sz || vr == VGZ_STUCK) { (void)VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); if (vr == VGZ_STUCK) vr = VGZ_OK; return (vr); }
VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { enum vgzret_e vr; ssize_t dl; const void *dp; struct worker *wrk; struct vgz *vg; const char *p; uint64_t u; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); if (act == VDP_INIT) { vg = VGZ_NewUngzip(req->vsl, "U D -"); AN(vg); if (vgz_getmbuf(vg)) { (void)VGZ_Destroy(&vg); return (-1); } req->res_mode |= RES_GUNZIP; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); *priv = vg; http_Unset(req->resp, H_Content_Encoding); req->resp_len = -1; if (req->objcore->boc != NULL) return (0); /* No idea about length (yet) */ p = ObjGetAttr(req->wrk, req->objcore, OA_GZIPBITS, &dl); if (p == NULL || dl != 32) return (0); /* No OA_GZIPBITS yet */ u = vbe64dec(p + 24); /* * If the size is non-zero AND we are the top * VDP (ie: no ESI), we know what size the output will be. */ if (u != 0 && VTAILQ_FIRST(&req->vdp)->func == VDP_gunzip) req->resp_len = u; return (0); } CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC); AN(vg->m_buf); if (act == VDP_FINI) { /* NB: Gunzip'ing may or may not have completed successfully. */ AZ(len); (void)VGZ_Destroy(&vg); *priv = NULL; return (0); } if (len == 0) return (0); VGZ_Ibuf(vg, ptr, len); do { vr = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; if (vr < VGZ_OK) return (-1); if (vg->m_len == vg->m_sz || vr != VGZ_OK) { if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len)) return (req->vdp_retval); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END); return (0); }
VDP_gunzip(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { enum vgzret_e vr; ssize_t dl; const void *dp; struct worker *wrk; struct vgz *vg; char *p; uint64_t u; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); if (act == VDP_INIT) { vg = VGZ_NewUngzip(req->vsl, "U D -"); AN(vg); if (vgz_getmbuf(vg)) { (void)VGZ_Destroy(&vg); return (-1); } VGZ_Obuf(vg, vg->m_buf, vg->m_sz); *priv = vg; http_Unset(req->resp, H_Content_Length); p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &dl); if (p != NULL && dl == 32) { u = vbe64dec(p + 24); /* XXX: Zero is suspect: OA_GZIPBITS wasn't set */ if (u != 0) http_PrintfHeader(req->resp, "Content-Length: %ju", (uintmax_t)u); } http_Unset(req->resp, H_Content_Encoding); return (0); } CAST_OBJ_NOTNULL(vg, *priv, VGZ_MAGIC); AN(vg->m_buf); if (act == VDP_FINI) { /* NB: Gunzip'ing may or may not have completed successfully. */ AZ(len); (void)VGZ_Destroy(&vg); *priv = NULL; return (0); } if (len == 0) return (0); VGZ_Ibuf(vg, ptr, len); do { vr = VGZ_Gunzip(vg, &dp, &dl); vg->m_len += dl; if (vr < VGZ_OK) return (-1); if (vg->m_len == vg->m_sz || vr != VGZ_OK) { if (VDP_bytes(req, VDP_FLUSH, vg->m_buf, vg->m_len)) return (-1); vg->m_len = 0; VGZ_Obuf(vg, vg->m_buf, vg->m_sz); } } while (!VGZ_IbufEmpty(vg)); assert(vr == VGZ_STUCK || vr == VGZ_OK || vr == VGZ_END); return (0); }