static int cnt_error(struct sess *sp) { struct worker *w; struct http *h; char date[40]; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); w = sp->wrk; if (sp->obj == NULL) { HSH_Prealloc(sp); sp->obj = HSH_NewObject(sp, 1); sp->obj->xid = sp->xid; sp->obj->entered = sp->t_req; } else { /* XXX: Null the headers ? */ } CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); h = sp->obj->http; http_PutProtocol(w, sp->fd, h, "HTTP/1.1"); http_PutStatus(w, sp->fd, h, sp->err_code); TIM_format(TIM_real(), date); http_PrintfHeader(w, sp->fd, h, "Date: %s", date); http_PrintfHeader(w, sp->fd, h, "Server: Varnish"); http_PrintfHeader(w, sp->fd, h, "Retry-After: %d", params->err_ttl); if (sp->err_reason != NULL) http_PutResponse(w, sp->fd, h, sp->err_reason); else http_PutResponse(w, sp->fd, h, http_StatusMessage(sp->err_code)); VCL_error_method(sp); if (sp->handling == VCL_RET_RESTART) { HSH_Drop(sp); sp->director = NULL; sp->restarts++; sp->step = STP_RECV; return (0); } /* We always close when we take this path */ sp->doclose = "error"; sp->wantbody = 1; assert(sp->handling == VCL_RET_DELIVER); sp->err_code = 0; sp->err_reason = NULL; sp->wrk->bereq = NULL; sp->step = STP_DELIVER; return (0); }
static int cnt_error(struct worker *wrk, struct req *req) { struct http *h; struct busyobj *bo; char date[40]; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); AZ(req->obj); AZ(req->busyobj); bo = VBO_GetBusyObj(wrk, req); req->busyobj = bo; AZ(bo->stats); bo->stats = &wrk->stats; req->objcore = HSH_NewObjCore(wrk); req->obj = STV_NewObject(bo, &req->objcore, TRANSIENT_STORAGE, cache_param->http_resp_size, (uint16_t)cache_param->http_max_hdr); bo->stats = NULL; if (req->obj == NULL) { req->doclose = SC_OVERLOAD; req->director = NULL; http_Teardown(bo->beresp); http_Teardown(bo->bereq); return(1); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); req->obj->vxid = bo->vsl->wid; req->obj->exp.entered = req->t_req; h = req->obj->http; if (req->err_code < 100 || req->err_code > 999) req->err_code = 501; http_PutProtocol(h, "HTTP/1.1"); http_PutStatus(h, req->err_code); VTIM_format(W_TIM_real(wrk), date); http_PrintfHeader(h, "Date: %s", date); http_SetHeader(h, "Server: Varnish"); if (req->err_reason != NULL) http_PutResponse(h, req->err_reason); else http_PutResponse(h, http_StatusMessage(req->err_code)); VCL_error_method(req); if (req->handling == VCL_RET_RESTART && req->restarts < cache_param->max_restarts) { HSH_Drop(wrk, &req->obj); VBO_DerefBusyObj(wrk, &req->busyobj); req->req_step = R_STP_RESTART; return (0); } else if (req->handling == VCL_RET_RESTART) req->handling = VCL_RET_DELIVER; /* We always close when we take this path */ req->doclose = SC_TX_ERROR; req->wantbody = 1; assert(req->handling == VCL_RET_DELIVER); req->err_code = 0; req->err_reason = NULL; http_Teardown(bo->bereq); VBO_DerefBusyObj(wrk, &req->busyobj); req->req_step = R_STP_PREPRESP; return (0); }
static int cnt_error(struct sess *sp) { struct http *h; char date[40]; struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk = sp->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); if (wrk->obj == NULL) { HSH_Prealloc(sp); AZ(wrk->busyobj); wrk->busyobj = VBO_GetBusyObj(wrk); wrk->obj = STV_NewObject(wrk, NULL, cache_param->http_resp_size, (uint16_t)cache_param->http_max_hdr); if (wrk->obj == NULL) wrk->obj = STV_NewObject(wrk, TRANSIENT_STORAGE, cache_param->http_resp_size, (uint16_t)cache_param->http_max_hdr); if (wrk->obj == NULL) { sp->doclose = "Out of objects"; sp->director = NULL; http_Setup(wrk->busyobj->beresp, NULL); http_Setup(wrk->busyobj->bereq, NULL); sp->step = STP_DONE; return(0); } AN(wrk->obj); wrk->obj->xid = sp->xid; wrk->obj->exp.entered = sp->t_req; } else { CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); /* XXX: Null the headers ? */ } CHECK_OBJ_NOTNULL(wrk->obj, OBJECT_MAGIC); h = wrk->obj->http; if (sp->err_code < 100 || sp->err_code > 999) sp->err_code = 501; http_PutProtocol(wrk, sp->vsl_id, h, "HTTP/1.1"); http_PutStatus(h, sp->err_code); VTIM_format(W_TIM_real(wrk), date); http_PrintfHeader(wrk, sp->vsl_id, h, "Date: %s", date); http_SetHeader(wrk, sp->vsl_id, h, "Server: Varnish"); if (sp->err_reason != NULL) http_PutResponse(wrk, sp->vsl_id, h, sp->err_reason); else http_PutResponse(wrk, sp->vsl_id, h, http_StatusMessage(sp->err_code)); VCL_error_method(sp); if (sp->handling == VCL_RET_RESTART && sp->restarts < cache_param->max_restarts) { HSH_Drop(wrk); VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->director = NULL; sp->restarts++; sp->step = STP_RECV; return (0); } else if (sp->handling == VCL_RET_RESTART) sp->handling = VCL_RET_DELIVER; /* We always close when we take this path */ sp->doclose = "error"; sp->wantbody = 1; assert(sp->handling == VCL_RET_DELIVER); sp->err_code = 0; sp->err_reason = NULL; http_Setup(wrk->busyobj->bereq, NULL); VBO_DerefBusyObj(wrk, &wrk->busyobj); sp->step = STP_PREPRESP; return (0); }
static enum req_fsm_nxt cnt_error(struct worker *wrk, struct req *req) { struct http *h; struct busyobj *bo; char date[40]; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); AZ(req->obj); req->acct_req.error++; bo = VBO_GetBusyObj(wrk, req); AZ(bo->stats); bo->stats = &wrk->stats; bo->fetch_objcore = HSH_Private(wrk); bo->fetch_obj = STV_NewObject(bo, TRANSIENT_STORAGE, cache_param->http_resp_size, (uint16_t)cache_param->http_max_hdr); req->obj = bo->fetch_obj; bo->stats = NULL; if (req->obj == NULL) { req->doclose = SC_OVERLOAD; req->director = NULL; AZ(HSH_DerefObjCore(&wrk->stats, &bo->fetch_objcore)); bo->fetch_objcore = NULL; http_Teardown(bo->beresp); http_Teardown(bo->bereq); VBO_DerefBusyObj(wrk, &bo); return (REQ_FSM_DONE); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); AZ(req->objcore); req->obj->vxid = bo->vsl->wid; req->obj->exp.entered = req->t_req; h = req->obj->http; if (req->err_code < 100 || req->err_code > 999) req->err_code = 501; http_PutProtocol(h, "HTTP/1.1"); http_PutStatus(h, req->err_code); VTIM_format(W_TIM_real(wrk), date); http_PrintfHeader(h, "Date: %s", date); http_SetHeader(h, "Server: Varnish"); CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); HSH_Ref(req->obj->objcore); if (req->err_reason != NULL) http_PutResponse(h, req->err_reason); else http_PutResponse(h, http_StatusMessage(req->err_code)); VCL_error_method(req->vcl, wrk, req, NULL, req->http->ws); /* Stop the insanity before it turns "Hotel California" on us */ if (req->restarts >= cache_param->max_restarts) wrk->handling = VCL_RET_DELIVER; if (wrk->handling == VCL_RET_RESTART) { VBO_DerefBusyObj(wrk, &bo); HSH_Drop(wrk, &req->obj); req->req_step = R_STP_RESTART; return (REQ_FSM_MORE); } CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); /* We always close when we take this path */ req->doclose = SC_TX_ERROR; req->wantbody = 1; assert(wrk->handling == VCL_RET_DELIVER); req->err_code = 0; req->err_reason = NULL; http_Teardown(bo->bereq); CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); VBO_DerefBusyObj(wrk, &bo); req->req_step = R_STP_DELIVER; CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC); return (REQ_FSM_MORE); }
static enum req_fsm_nxt cnt_synth(struct worker *wrk, struct req *req) { char date[40]; struct http *h; double now; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); wrk->stats.s_synth++; HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod); h = req->resp; now = W_TIM_real(wrk); VSLb_ts_req(req, "Process", now); if (req->err_code < 100 || req->err_code > 999) req->err_code = 501; http_ClrHeader(h); http_PutProtocol(h, "HTTP/1.1"); http_PutStatus(h, req->err_code); VTIM_format(now, date); http_PrintfHeader(h, "Date: %s", date); http_SetHeader(h, "Server: Varnish"); http_PrintfHeader(req->resp, "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK); if (req->err_reason != NULL) http_PutResponse(h, req->err_reason); else http_PutResponse(h, http_StatusMessage(req->err_code)); AZ(req->synth_body); req->synth_body = VSB_new_auto(); AN(req->synth_body); VCL_synth_method(req->vcl, wrk, req, NULL, req->http->ws); http_Unset(h, H_Content_Length); AZ(VSB_finish(req->synth_body)); if (wrk->handling == VCL_RET_RESTART) { http_ClrHeader(h); VSB_delete(req->synth_body); req->synth_body = NULL; req->req_step = R_STP_RESTART; return (REQ_FSM_MORE); } assert(wrk->handling == VCL_RET_DELIVER); if (http_HdrIs(req->resp, H_Connection, "close")) req->doclose = SC_RESP_CLOSE; V1D_Deliver_Synth(req); VSLb_ts_req(req, "Resp", W_TIM_real(wrk)); VSB_delete(req->synth_body); req->synth_body = NULL; req->err_code = 0; req->err_reason = NULL; return (REQ_FSM_DONE); }