示例#1
0
vfp_testgzip_begin(struct busyobj *bo, size_t estimate)
{
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	(void)estimate;
	bo->vgz_rx = VGZ_NewUngzip(bo->vsl, "u F -");
	CHECK_OBJ_NOTNULL(bo->vgz_rx, VGZ_MAGIC);
	XXXAZ(vgz_getmbuf(bo->vgz_rx));
}
示例#2
0
vfp_esi_begin(struct busyobj *bo, size_t estimate)
{
	struct vef_priv *vef;

	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	(void)estimate;

	ALLOC_OBJ(vef, VEF_MAGIC);
	XXXAN(vef);
	AZ(bo->vef_priv);
	bo->vef_priv = vef;

	AZ(bo->vgz_rx);
	if (bo->is_gzip && bo->do_gunzip) {
		bo->vgz_rx = VGZ_NewUngzip(bo->vsl, "U F E");
		VEP_Init(bo, NULL);
		vef->ibuf_sz = cache_param->gzip_buffer;
	} else if (bo->is_gunzip && bo->do_gzip) {
		vef->vgz = VGZ_NewGzip(bo->vsl, "G F E");
		VEP_Init(bo, vfp_vep_callback);
		vef->ibuf_sz = cache_param->gzip_buffer;
	} else if (bo->is_gzip) {
		bo->vgz_rx = VGZ_NewUngzip(bo->vsl, "U F E");
		vef->vgz = VGZ_NewGzip(bo->vsl, "G F E");
		VEP_Init(bo, vfp_vep_callback);
		vef->ibuf_sz = cache_param->gzip_buffer;
		vef->ibuf2_sz = cache_param->gzip_buffer;
	} else {
		VEP_Init(bo, NULL);
	}
	if (vef->ibuf_sz > 0) {
		vef->ibuf = calloc(1L, vef->ibuf_sz);
		XXXAN(vef->ibuf);
		vef->ibuf_i = vef->ibuf;
		vef->ibuf_o = vef->ibuf;
	}
	if (vef->ibuf2_sz > 0) {
		vef->ibuf2 = calloc(1L, vef->ibuf2_sz);
		XXXAN(vef->ibuf2);
	}
	AN(bo->vep);
}
vfp_esi_begin(struct sess *sp, size_t estimate)
{
	struct vef_priv *vef;

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	/* XXX: snapshot WS's ? We'll need the space */

	AZ(sp->wrk->vgz_rx);
	if (sp->wrk->is_gzip && sp->wrk->do_gunzip) {
		sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "U F E");
		VEP_Init(sp, NULL);
	} else if (sp->wrk->is_gunzip && sp->wrk->do_gzip) {
		ALLOC_OBJ(vef, VEF_MAGIC);
		AN(vef);
		//vef = (void*)WS_Alloc(sp->ws, sizeof *vef);
		//memset(vef, 0, sizeof *vef);
		//vef->magic = VEF_MAGIC;
		vef->vgz = VGZ_NewGzip(sp, "G F E");
		AZ(sp->wrk->vef_priv);
		sp->wrk->vef_priv = vef;
		VEP_Init(sp, vfp_vep_callback);
	} else if (sp->wrk->is_gzip) {
		sp->wrk->vgz_rx = VGZ_NewUngzip(sp, "U F E");
		ALLOC_OBJ(vef, VEF_MAGIC);
		AN(vef);
		//vef = (void*)WS_Alloc(sp->ws, sizeof *vef);
		//memset(vef, 0, sizeof *vef);
		//vef->magic = VEF_MAGIC;
		vef->vgz = VGZ_NewGzip(sp, "G F E");
		AZ(sp->wrk->vef_priv);
		sp->wrk->vef_priv = vef;
		VEP_Init(sp, vfp_vep_callback);
	} else {
		AZ(sp->wrk->vef_priv);
		VEP_Init(sp, NULL);
	}

	(void)estimate;
	AN(sp->wrk->vep);
}
示例#4
0
vfp_esi_begin(struct worker *wrk, size_t estimate)
{
	struct busyobj *bo;
	struct vef_priv *vef;

	(void)estimate;
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	bo = wrk->busyobj;
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

	AZ(bo->vgz_rx);
	if (bo->is_gzip && bo->do_gunzip) {
		bo->vgz_rx = VGZ_NewUngzip(wrk, "U F E");
		VEP_Init(wrk, NULL);
	} else if (bo->is_gunzip && bo->do_gzip) {
		ALLOC_OBJ(vef, VEF_MAGIC);
		AN(vef);
		vef->vgz = VGZ_NewGzip(wrk, "G F E");
		AZ(bo->vef_priv);
		bo->vef_priv = vef;
		VEP_Init(wrk, vfp_vep_callback);
	} else if (bo->is_gzip) {
		bo->vgz_rx = VGZ_NewUngzip(wrk, "U F E");
		ALLOC_OBJ(vef, VEF_MAGIC);
		AN(vef);
		vef->vgz = VGZ_NewGzip(wrk, "G F E");
		AZ(bo->vef_priv);
		bo->vef_priv = vef;
		VEP_Init(wrk, vfp_vep_callback);
	} else {
		AZ(bo->vef_priv);
		VEP_Init(wrk, NULL);
	}

	AN(bo->vep);
}
示例#5
0
vfp_gzip_init(struct vfp_ctx *vc, struct vfp_entry *vfe)
{
	struct vgz *vg;

	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);

	if (http_HdrIs(vc->http, H_Content_Length, "0")) {
		http_Unset(vc->http, H_Content_Encoding);
		return (VFP_NULL);
	}

	if (vfe->vfp->priv2 == VFP_GZIP) {
		if (http_GetHdr(vc->http, H_Content_Encoding, NULL))
			return (VFP_NULL);
		vg = VGZ_NewGzip(vc->wrk->vsl, vfe->vfp->priv1);
	} else {
		if (!http_HdrIs(vc->http, H_Content_Encoding, "gzip"))
			return (VFP_NULL);
		vg = VGZ_NewUngzip(vc->wrk->vsl, vfe->vfp->priv1);
	}
	if (vg == NULL)
		return (VFP_ERROR);
	vfe->priv1 = vg;
	if (vgz_getmbuf(vg))
		return (VFP_ERROR);
	VGZ_Ibuf(vg, vg->m_buf, 0);
	AZ(vg->m_len);

	if (vfe->vfp->priv2 == VFP_GUNZIP || vfe->vfp->priv2 == VFP_GZIP) {
		http_Unset(vc->http, H_Content_Encoding);
		http_Unset(vc->http, H_Content_Length);
		RFC2616_Weaken_Etag(vc->http);
	}

	if (vfe->vfp->priv2 == VFP_GZIP)
		http_SetHeader(vc->http, "Content-Encoding: gzip");

	if (vfe->vfp->priv2 == VFP_GZIP || vfe->vfp->priv2 == VFP_TESTGUNZIP)
		RFC2616_Vary_AE(vc->http);

	return (VFP_OK);
}
示例#6
0
vfp_gzip_init(struct busyobj *bo, struct vfp_entry *vfe)
{
	struct vgz *vg;

        CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);

	if (vfe->vfp->priv2)
		vg = VGZ_NewGzip(bo->vsl, vfe->vfp->priv1);
	else
		vg = VGZ_NewUngzip(bo->vsl, vfe->vfp->priv1);
	if (vg == NULL)
		return (VFP_ERROR);
	if (vgz_getmbuf(vg))
		return (VFP_ERROR);
	vfe->priv1 = vg;
	VGZ_Ibuf(vg, vg->m_buf, 0);
	AZ(vg->m_len);
	return (VFP_OK);
}
示例#7
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;
	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);
}
示例#8
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);
}
void
V1D_Deliver(struct req *req)
{
	char *r;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	CHECK_OBJ_NOTNULL(req->obj->objcore, OBJCORE_MAGIC);

	req->res_mode = 0;

	if (!req->disable_esi && req->obj->esidata != NULL) {
		/* In ESI mode, we can't know the aggregate length */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_ESI;
	} else if (req->resp->status == 304) {
		req->res_mode &= ~RES_LEN;
		http_Unset(req->resp, H_Content_Length);
		req->wantbody = 0;
	} else if (req->obj->objcore->busyobj == NULL) {
		/* XXX: Not happy with this convoluted test */
		req->res_mode |= RES_LEN;
		if (!(req->obj->objcore->flags & OC_F_PASS) ||
		    req->obj->len != 0) {
			http_Unset(req->resp, H_Content_Length);
			http_PrintfHeader(req->resp,
			    "Content-Length: %zd", req->obj->len);
		}
	}

	if (req->esi_level > 0) {
		/* Included ESI object, always CHUNKED or EOF */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_ESI_CHILD;
	}

	if (cache_param->http_gzip_support && req->obj->gziped &&
	    !RFC2616_Req_Gzip(req->http)) {
		/*
		 * We don't know what it uncompresses to
		 * XXX: we could cache that, but would still deliver
		 * XXX: with multiple writes because of the gunzip buffer
		 */
		req->res_mode &= ~RES_LEN;
		req->res_mode |= RES_GUNZIP;
	}

	if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) {
		/* We havn't chosen yet, do so */
		if (!req->wantbody) {
			/* Nothing */
		} else if (req->http->protover >= 11) {
			req->res_mode |= RES_CHUNKED;
		} else {
			req->res_mode |= RES_EOF;
			req->doclose = SC_TX_EOF;
		}
	}
	VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);

	if (!(req->res_mode & RES_LEN))
		http_Unset(req->resp, H_Content_Length);

	if (req->res_mode & RES_GUNZIP)
		http_Unset(req->resp, H_Content_Encoding);

	if (req->res_mode & RES_CHUNKED)
		http_SetHeader(req->resp, "Transfer-Encoding: chunked");

	http_SetHeader(req->resp,
	    req->doclose ? "Connection: close" : "Connection: keep-alive");

	req->vdps[0] = v1d_bytes;
	req->vdp_nxt = 0;

	if (
	    req->wantbody &&
	    !(req->res_mode & (RES_ESI|RES_ESI_CHILD)) &&
	    cache_param->http_range_support &&
	    req->obj->response == 200) {
		http_SetHeader(req->resp, "Accept-Ranges: bytes");
		if (http_GetHdr(req->http, H_Range, &r))
			v1d_dorange(req, r);
	}

	if (req->res_mode & RES_ESI)
		RFC2616_Weaken_Etag(req->resp);

	WRW_Reserve(req->wrk, &req->sp->fd, req->vsl, req->t_resp);

	/*
	 * Send HTTP protocol header, unless interior ESI object
	 */
	if (!(req->res_mode & RES_ESI_CHILD))
		req->acct_req.hdrbytes += HTTP1_Write(req->wrk, req->resp, 1);

	if (req->res_mode & RES_CHUNKED)
		WRW_Chunked(req->wrk);

	if (!req->wantbody) {
		/* This was a HEAD or conditional request */
	} else if (req->res_mode & RES_ESI) {
		AZ(req->obj->objcore->busyobj);
		ESI_Deliver(req);
	} else if (req->res_mode & RES_ESI_CHILD && req->gzip_resp) {
		while (req->obj->objcore->busyobj)
			(void)usleep(10000);
		ESI_DeliverChild(req);
	} else if (req->res_mode & RES_GUNZIP ||
	    (req->res_mode & RES_ESI_CHILD &&
	    !req->gzip_resp && req->obj->gziped)) {
		VDP_push(req, VDP_gunzip);
		req->vgz = VGZ_NewUngzip(req->vsl, "U D -");
		AZ(VGZ_WrwInit(req->vgz));
		v1d_WriteDirObj(req);
		(void)VGZ_Destroy(&req->vgz);
		VDP_pop(req, VDP_gunzip);
	} else {
		v1d_WriteDirObj(req);
	}

	if (req->res_mode & RES_CHUNKED && !(req->res_mode & RES_ESI_CHILD))
		WRW_EndChunk(req->wrk);

	if (WRW_FlushRelease(req->wrk) && req->sp->fd >= 0)
		SES_Close(req->sp, SC_REM_CLOSE);
}
示例#10
0
static int
cnt_streambody(struct sess *sp)
{
    int i;
    struct stream_ctx sctx;
    uint8_t obuf[sp->wrk->res_mode & RES_GUNZIP ?
                 cache_param->gzip_stack_buffer : 1];
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

    CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
    memset(&sctx, 0, sizeof sctx);
    sctx.magic = STREAM_CTX_MAGIC;
    AZ(wrk->sctx);
    wrk->sctx = &sctx;

    if (wrk->res_mode & RES_GUNZIP) {
        sctx.vgz = VGZ_NewUngzip(wrk, "U S -");
        sctx.obuf = obuf;
        sctx.obuf_len = sizeof (obuf);
    }

    RES_StreamStart(sp);

    AssertObjCorePassOrBusy(wrk->obj->objcore);

    i = FetchBody(wrk, wrk->obj);

    http_Setup(wrk->busyobj->bereq, NULL);
    http_Setup(wrk->busyobj->beresp, NULL);
    wrk->busyobj->vfp = NULL;
    AZ(wrk->busyobj->vbc);
    AN(sp->director);

    if (!i && wrk->obj->objcore != NULL) {
        EXP_Insert(wrk->obj);
        AN(wrk->obj->objcore);
        AN(wrk->obj->objcore->ban);
        HSH_Unbusy(wrk);
    } else {
        sp->doclose = "Stream error";
    }
    wrk->acct_tmp.fetch++;
    sp->director = NULL;
    sp->restarts = 0;

    RES_StreamEnd(sp);
    if (wrk->res_mode & RES_GUNZIP)
        (void)VGZ_Destroy(&sctx.vgz, sp->vsl_id);

    wrk->sctx = NULL;
    assert(WRW_IsReleased(wrk));
    assert(wrk->wrw.ciov == wrk->wrw.siov);
    (void)HSH_Deref(wrk, NULL, &wrk->obj);
    VBO_DerefBusyObj(wrk, &wrk->busyobj);
    http_Setup(wrk->resp, NULL);
    sp->step = STP_DONE;
    return (0);
}