static int cnt_deliver(struct sess *sp) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); sp->t_resp = TIM_real(); if (sp->obj->objhead != NULL) { if ((sp->t_resp - sp->obj->last_lru) > params->lru_timeout && EXP_Touch(sp->obj)) sp->obj->last_lru = sp->t_resp; /* XXX: locking ? */ sp->obj->last_use = sp->t_resp; /* XXX: locking ? */ } sp->wrk->resp = &sp->wrk->http[2]; http_Setup(sp->wrk->resp, sp->wrk->ws); RES_BuildHttp(sp); VCL_deliver_method(sp); switch (sp->handling) { case VCL_RET_DELIVER: break; case VCL_RET_RESTART: INCOMPL(); break; default: WRONG("Illegal action in vcl_deliver{}"); } sp->director = NULL; sp->restarts = 0; RES_WriteObj(sp); AZ(sp->wrk->wfd); HSH_Deref(sp->wrk, &sp->obj); sp->wrk->resp = NULL; sp->step = STP_DONE; return (0); }
static int cnt_prepresp(struct worker *wrk, struct req *req) { struct busyobj *bo; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); bo = req->busyobj; CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); req->res_mode = 0; if (bo == NULL) { 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 { req->res_mode |= RES_LEN; } } else { AZ(bo->do_esi); } 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 */ 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; } } req->t_resp = W_TIM_real(wrk); if (req->obj->objcore->objhead != NULL) { if ((req->t_resp - req->obj->last_lru) > cache_param->lru_timeout && EXP_Touch(req->obj->objcore)) req->obj->last_lru = req->t_resp; if (!cache_param->obj_readonly) req->obj->last_use = req->t_resp; /* XXX: locking ? */ } HTTP_Setup(req->resp, req->ws, req->vsl, HTTP_Resp); RES_BuildHttp(req); VCL_deliver_method(req); switch (req->handling) { case VCL_RET_DELIVER: break; case VCL_RET_RESTART: if (req->restarts >= cache_param->max_restarts) break; if (bo != NULL) { AN(bo->do_stream); (void)HSH_Deref(&wrk->stats, NULL, &req->obj); VBO_DerefBusyObj(wrk, &req->busyobj); } else { (void)HSH_Deref(&wrk->stats, NULL, &req->obj); } AZ(req->obj); http_Teardown(req->resp); req->req_step = R_STP_RESTART; return (0); default: WRONG("Illegal action in vcl_deliver{}"); } req->req_step = R_STP_DELIVER; return (0); }
static int cnt_prepresp(struct sess *sp) { struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk = sp->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(wrk->obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); if (wrk->busyobj != NULL) { CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); AN(wrk->busyobj->do_stream); AssertObjCorePassOrBusy(wrk->obj->objcore); } wrk->res_mode = 0; if (wrk->busyobj == NULL) wrk->res_mode |= RES_LEN; if (wrk->busyobj != NULL && (wrk->busyobj->h_content_length != NULL || !wrk->busyobj->do_stream) && !wrk->busyobj->do_gzip && !wrk->busyobj->do_gunzip) wrk->res_mode |= RES_LEN; if (!sp->disable_esi && wrk->obj->esidata != NULL) { /* In ESI mode, we don't know the aggregate length */ wrk->res_mode &= ~RES_LEN; wrk->res_mode |= RES_ESI; } if (sp->esi_level > 0) { wrk->res_mode &= ~RES_LEN; wrk->res_mode |= RES_ESI_CHILD; } if (cache_param->http_gzip_support && wrk->obj->gziped && !RFC2616_Req_Gzip(sp)) { /* * We don't know what it uncompresses to * XXX: we could cache that */ wrk->res_mode &= ~RES_LEN; wrk->res_mode |= RES_GUNZIP; } if (!(wrk->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) { if (wrk->obj->len == 0 && (wrk->busyobj == NULL || !wrk->busyobj->do_stream)) /* * If the object is empty, neither ESI nor GUNZIP * can make it any different size */ wrk->res_mode |= RES_LEN; else if (!sp->wantbody) { /* Nothing */ } else if (sp->http->protover >= 11) { wrk->res_mode |= RES_CHUNKED; } else { wrk->res_mode |= RES_EOF; sp->doclose = "EOF mode"; } } sp->t_resp = W_TIM_real(wrk); if (wrk->obj->objcore != NULL) { if ((sp->t_resp - wrk->obj->last_lru) > cache_param->lru_timeout && EXP_Touch(wrk->obj->objcore)) wrk->obj->last_lru = sp->t_resp; wrk->obj->last_use = sp->t_resp; /* XXX: locking ? */ } http_Setup(wrk->resp, wrk->ws); RES_BuildHttp(sp); VCL_deliver_method(sp); switch (sp->handling) { case VCL_RET_DELIVER: break; case VCL_RET_RESTART: if (sp->restarts >= cache_param->max_restarts) break; if (wrk->busyobj != NULL) { AN(wrk->busyobj->do_stream); VDI_CloseFd(wrk, &wrk->busyobj->vbc); HSH_Drop(wrk); VBO_DerefBusyObj(wrk, &wrk->busyobj); } else { (void)HSH_Deref(wrk, NULL, &wrk->obj); } AZ(wrk->obj); sp->restarts++; sp->director = NULL; http_Setup(wrk->resp, NULL); sp->step = STP_RECV; return (0); default: WRONG("Illegal action in vcl_deliver{}"); } if (wrk->busyobj != NULL && wrk->busyobj->do_stream) { AssertObjCorePassOrBusy(wrk->obj->objcore); sp->step = STP_STREAMBODY; } else { sp->step = STP_DELIVER; } return (0); }