Exemplo n.º 1
0
static enum fetch_step
vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
{

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

	AZ(vbf_beresp2obj(bo));

	if (ObjHasAttr(bo->wrk, bo->stale_oc, OA_ESIDATA))
		AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc,
		    OA_ESIDATA));

	AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc, OA_FLAGS));
	AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc, OA_GZIPBITS));

	if (bo->do_stream) {
		ObjSetState(wrk, bo->fetch_objcore, BOS_PREP_STREAM);
		HSH_Unbusy(wrk, bo->fetch_objcore);
		ObjSetState(wrk, bo->fetch_objcore, BOS_STREAM);
	}

	if (ObjIterate(wrk, bo->stale_oc, bo, vbf_objiterator, 0))
		(void)VFP_Error(bo->vfc, "Template object failed");

	if (bo->stale_oc->flags & OC_F_FAILED)
		(void)VFP_Error(bo->vfc, "Template object failed");
	if (bo->vfc->failed) {
		VDI_Finish(bo->wrk, bo);
		wrk->stats->fetch_failed++;
		return (F_STP_FAIL);
	}
	return (F_STP_FETCHEND);
}
Exemplo n.º 2
0
static enum fetch_step
vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
{

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

	AZ(vbf_beresp2obj(bo));

	if (ObjHasAttr(bo->wrk, bo->stale_oc, OA_ESIDATA))
		AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc,
		    OA_ESIDATA));

	AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc, OA_FLAGS));
	AZ(ObjCopyAttr(bo->wrk, bo->fetch_objcore, bo->stale_oc, OA_GZIPBITS));

	if (bo->do_stream) {
		ObjSetState(wrk, bo->fetch_objcore, BOS_PREP_STREAM);
		HSH_Unbusy(wrk, bo->fetch_objcore);
		ObjSetState(wrk, bo->fetch_objcore, BOS_STREAM);
	}

	if (ObjIterate(wrk, bo->stale_oc, bo, vbf_objiterator, 0))
		(void)VFP_Error(bo->vfc, "Template object failed");

	if (bo->stale_oc->flags & OC_F_FAILED)
		(void)VFP_Error(bo->vfc, "Template object failed");
	if (bo->vfc->failed) {
		VDI_Finish(bo->wrk, bo);
		return (F_STP_FAIL);
	}

	AZ(ObjSetU64(wrk, bo->fetch_objcore, OA_LEN,
	    bo->fetch_objcore->boc->len_so_far));

	if (!bo->do_stream)
		HSH_Unbusy(wrk, bo->fetch_objcore);

	HSH_Kill(bo->stale_oc);

	/* Recycle the backend connection before setting BOS_FINISHED to
	   give predictable backend reuse behavior for varnishtest */
	VDI_Finish(bo->wrk, bo);

	ObjSetState(wrk, bo->fetch_objcore, BOS_FINISHED);
	VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk));
	return (F_STP_DONE);
}
Exemplo n.º 3
0
static enum req_fsm_nxt
cnt_transmit(struct worker *wrk, struct req *req)
{
	struct boc *boc;
	const char *r;
	uint16_t status;
	int sendbody;
	intmax_t clval;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->transport, TRANSPORT_MAGIC);

	/* Grab a ref to the bo if there is one */
	boc = HSH_RefBoc(req->objcore);

	clval = http_GetContentLength(req->resp);
	if (boc != NULL)
		req->resp_len = clval;
	else
		req->resp_len = ObjGetLen(req->wrk, req->objcore);

	req->res_mode = 0;

	/* RFC 7230, 3.3.3 */
	status = http_GetStatus(req->resp);
	if (!strcmp(req->http0->hd[HTTP_HDR_METHOD].b, "HEAD")) {
		if (req->objcore->flags & OC_F_PASS)
			sendbody = -1;
		else
			sendbody = 0;
	} else if (status < 200 || status == 204 || status == 304) {
		req->resp_len = -1;
		sendbody = 0;
	} else
		sendbody = 1;

	if (sendbody >= 0) {
		if (!req->disable_esi && req->resp_len != 0 &&
		    ObjHasAttr(wrk, req->objcore, OA_ESIDATA))
			VDP_push(req, VDP_ESI, NULL, 0, "ESI");

		if (cache_param->http_gzip_support &&
		    ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) &&
		    !RFC2616_Req_Gzip(req->http))
			VDP_push(req, VDP_gunzip, NULL, 1, "GUZ");

		if (cache_param->http_range_support &&
		    http_IsStatus(req->resp, 200)) {
			http_SetHeader(req->resp, "Accept-Ranges: bytes");
			if (sendbody && http_GetHdr(req->http, H_Range, &r))
				VRG_dorange(req, r);
		}
	}

	if (sendbody < 0) {
		/* Don't touch pass+HEAD C-L */
		sendbody = 0;
	} else if (clval >= 0 && clval == req->resp_len) {
		/* Reuse C-L header */
	} else {
		http_Unset(req->resp, H_Content_Length);
		if (req->resp_len >= 0 && sendbody)
			http_PrintfHeader(req->resp,
			    "Content-Length: %jd", req->resp_len);
	}

	req->transport->deliver(req, boc, sendbody);

	VSLb_ts_req(req, "Resp", W_TIM_real(wrk));

	if (req->objcore->flags & (OC_F_PRIVATE | OC_F_PASS)) {
		if (boc != NULL) {
			HSH_Abandon(req->objcore);
			ObjWaitState(req->objcore, BOS_FINISHED);
		}
		ObjSlim(wrk, req->objcore);
	}

	if (boc != NULL)
		HSH_DerefBoc(wrk, req->objcore);

	(void)HSH_DerefObjCore(wrk, &req->objcore);
	http_Teardown(req->resp);

	return (REQ_FSM_DONE);
}