void http_SetHeader(struct http *to, const char *hdr) { CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); if (to->nhd >= to->shd) { VSC_C_main->losthdr++; VSLb(to->vsl, SLT_LostHeader, "%s", hdr); return; } http_SetH(to, to->nhd++, hdr); }
void http_SetHeader(struct worker *w, unsigned vsl_id, struct http *to, const char *hdr) { CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); if (to->nhd >= to->shd) { VSC_C_main->losthdr++; WSL(w, SLT_LostHeader, vsl_id, "%s", hdr); return; } http_SetH(to, to->nhd++, hdr); }
void http_FilterReq(struct http *to, const struct http *fm, unsigned how) { CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC); http_linkh(to, fm, HTTP_HDR_METHOD); http_linkh(to, fm, HTTP_HDR_URL); if (how == HTTPH_R_FETCH) http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1"); else http_linkh(to, fm, HTTP_HDR_PROTO); http_filterfields(to, fm, how); }
static void vrt_do_string(const struct http *hp, int fld, const char *err, const char *p, va_list ap) { const char *b; AN(hp); b = VRT_String(hp->ws, NULL, p, ap); if (b == NULL || *b == '\0') { VSLb(hp->vsl, SLT_LostHeader, "%s", err); } else { http_SetH(hp, fld, b); } va_end(ap); }
static void vrt_do_string(const struct http *hp, int fld, const char *err, const char *p, va_list ap) { const char *b; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); b = VRT_String(hp->ws, NULL, p, ap); if (b == NULL || *b == '\0') { VSLb(hp->vsl, SLT_LostHeader, "%s", err); WS_MarkOverflow(hp->ws); return; } http_SetH(hp, fld, b); }
void http_FilterReq(const struct req *req, unsigned how) { struct http *hp; hp = req->busyobj->bereq; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); http_linkh(hp, req->http, HTTP_HDR_METHOD); http_linkh(hp, req->http, HTTP_HDR_URL); if (how == HTTPH_R_FETCH) http_SetH(hp, HTTP_HDR_PROTO, "HTTP/1.1"); else http_linkh(hp, req->http, HTTP_HDR_PROTO); http_filterfields(hp, req->http, how); http_PrintfHeader(hp, "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK); }
void http_SetStatus(struct http *to, uint16_t status) { char buf[4]; CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); /* * We allow people to use top digits for internal VCL * signalling, but strip them from the ASCII version. */ to->status = status; status %= 1000; assert(status >= 100); bprintf(buf, "%03d", status); http_PutField(to, HTTP_HDR_STATUS, buf); http_SetH(to, HTTP_HDR_REASON, http_Status2Reason(status)); }
void http_FilterHeader(const struct sess *sp, unsigned how) { struct http *hp; hp = sp->wrk->bereq; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); hp->logtag = HTTP_Tx; http_copyh(hp, sp->http, HTTP_HDR_REQ); http_copyh(hp, sp->http, HTTP_HDR_URL); if (how == HTTPH_R_FETCH) http_SetH(hp, HTTP_HDR_PROTO, "HTTP/1.1"); else http_copyh(hp, sp->http, HTTP_HDR_PROTO); http_FilterFields(sp->wrk, sp->fd, hp, sp->http, how); http_PrintfHeader(sp->wrk, sp->fd, hp, "X-Varnish: %u", sp->xid); }
void http_FilterReq(const struct sess *sp, unsigned how) { struct http *hp; hp = sp->req->busyobj->bereq; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); hp->logtag = HTTP_Tx; http_linkh(hp, sp->req->http, HTTP_HDR_REQ); http_linkh(hp, sp->req->http, HTTP_HDR_URL); if (how == HTTPH_R_FETCH) http_SetH(hp, HTTP_HDR_PROTO, "HTTP/1.1"); else http_linkh(hp, sp->req->http, HTTP_HDR_PROTO); http_filterfields(hp, sp->req->http, how); http_PrintfHeader(hp, "X-Varnish: %u", sp->req->xid); }
static void vrt_do_string(VRT_CTX, struct http *hp, int fld, const char *err, const char *p, va_list ap) { const char *b; CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC); b = VRT_String(hp->ws, NULL, p, ap); if (b == NULL) { VRT_fail(ctx, "Workspace overflow (%s)", err); WS_MarkOverflow(hp->ws); return; } if (*b == '\0') { VRT_fail(ctx, "Setting %s to empty string", err); return; } http_SetH(hp, fld, b); }
static void ved_include(struct req *preq, const char *src, const char *host, struct ecx *ecx) { struct worker *wrk; struct req *req; enum req_fsm_nxt s; struct transport xp; CHECK_OBJ_NOTNULL(preq, REQ_MAGIC); CHECK_OBJ_NOTNULL(ecx, ECX_MAGIC); wrk = preq->wrk; if (preq->esi_level >= cache_param->max_esi_depth) return; req = Req_New(wrk, preq->sp); req->req_body_status = REQ_BODY_NONE; AZ(req->vsl->wid); req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER); VSLb(req->vsl, SLT_Begin, "req %u esi", VXID(preq->vsl->wid)); VSLb(preq->vsl, SLT_Link, "req %u esi", VXID(req->vsl->wid)); req->esi_level = preq->esi_level + 1; if (preq->esi_level == 0) assert(preq->top == preq); else CHECK_OBJ_NOTNULL(preq->top, REQ_MAGIC); req->top = preq->top; HTTP_Copy(req->http0, preq->http0); req->http0->ws = req->ws; req->http0->vsl = req->vsl; req->http0->logtag = SLT_ReqMethod; req->http0->conds = 0; http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { http_Unset(req->http0, H_Host); http_SetHeader(req->http0, host); } http_ForceField(req->http0, HTTP_HDR_METHOD, "GET"); http_ForceField(req->http0, HTTP_HDR_PROTO, "HTTP/1.1"); /* Don't allow conditionalss, we can't use a 304 */ http_Unset(req->http0, H_If_Modified_Since); http_Unset(req->http0, H_If_None_Match); /* Don't allow Range */ http_Unset(req->http0, H_Range); /* Set Accept-Encoding according to what we want */ http_Unset(req->http0, H_Accept_Encoding); if (ecx->isgzip) http_ForceHeader(req->http0, H_Accept_Encoding, "gzip"); /* Client content already taken care of */ http_Unset(req->http0, H_Content_Length); /* Reset request to status before we started messing with it */ HTTP_Copy(req->http, req->http0); req->vcl = preq->vcl; preq->vcl = NULL; req->wrk = preq->wrk; /* * XXX: We should decide if we should cache the director * XXX: or not (for session/backend coupling). Until then * XXX: make sure we don't trip up the check in vcl_recv. */ req->req_step = R_STP_RECV; req->t_req = preq->t_req; assert(isnan(req->t_first)); assert(isnan(req->t_prev)); INIT_OBJ(&xp, TRANSPORT_MAGIC); xp.deliver = VED_Deliver; req->transport = &xp; req->transport_priv = ecx; THR_SetRequest(req); VSLb_ts_req(req, "Start", W_TIM_real(wrk)); req->ws_req = WS_Snapshot(req->ws); while (1) { req->wrk = wrk; s = CNT_Request(wrk, req); if (s == REQ_FSM_DONE) break; DSL(DBG_WAITINGLIST, req->vsl->wid, "loop waiting for ESI (%d)", (int)s); assert(s == REQ_FSM_DISEMBARK); AZ(req->wrk); (void)usleep(10000); } VRTPRIV_dynamic_kill(req->sp->privs, (uintptr_t)req); CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); preq->vcl = req->vcl; req->vcl = NULL; req->wrk = NULL; THR_SetRequest(preq); Req_Release(req); }
static enum fetch_step vbf_stp_fetchhdr(struct worker *wrk, struct busyobj *bo) { int i; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); xxxassert (wrk->handling == VCL_RET_FETCH); HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp); if (!bo->do_pass) vbf_release_req(bo); /* XXX: retry ?? */ assert(bo->state == BOS_INVALID); i = V1F_fetch_hdr(wrk, bo, bo->req); /* * If we recycle a backend connection, there is a finite chance * that the backend closed it before we get a request to it. * Do a single retry in that case. */ if (i == 1) { VSC_C_main->backend_retry++; i = V1F_fetch_hdr(wrk, bo, bo->req); } if (bo->do_pass) vbf_release_req(bo); /* XXX : retry ?? */ AZ(bo->req); if (i) { AZ(bo->vbc); bo->err_code = 503; http_SetH(bo->beresp, HTTP_HDR_PROTO, "HTTP/1.1"); http_SetResp(bo->beresp, "HTTP/1.1", 503, "Backend fetch failed"); http_SetHeader(bo->beresp, "Content-Length: 0"); http_SetHeader(bo->beresp, "Connection: close"); } else { AN(bo->vbc); } /* * These two headers can be spread over multiple actual headers * and we rely on their content outside of VCL, so collect them * into one line here. */ http_CollectHdr(bo->beresp, H_Cache_Control); http_CollectHdr(bo->beresp, H_Vary); /* * Figure out how the fetch is supposed to happen, before the * headers are adultered by VCL * NB: Also sets other wrk variables */ bo->htc.body_status = RFC2616_Body(bo, &wrk->stats); bo->err_code = http_GetStatus(bo->beresp); /* * What does RFC2616 think about TTL ? */ EXP_Clr(&bo->exp); bo->exp.entered = W_TIM_real(wrk); RFC2616_Ttl(bo); /* pass from vclrecv{} has negative TTL */ if (bo->fetch_objcore->objhead == NULL) bo->exp.ttl = -1.; AZ(bo->do_esi); VCL_backend_response_method(bo->vcl, wrk, NULL, bo, bo->beresp->ws); if (bo->do_esi) bo->do_stream = 0; if (wrk->handling == VCL_RET_DELIVER) return (F_STP_FETCH); if (wrk->handling == VCL_RET_RETRY) { assert(bo->state == BOS_INVALID); bo->retries++; if (bo->retries <= cache_param->max_retries) { VDI_CloseFd(&bo->vbc); return (F_STP_STARTFETCH); } // XXX: wrk->handling = VCL_RET_SYNTH; } return (F_STP_NOTYET); }
void http_ForceGet(const struct http *to) { if (strcmp(http_GetReq(to), "GET")) http_SetH(to, HTTP_HDR_METHOD, "GET"); }