enum htc_status_e SES_RxReq(const struct worker *wrk, struct req *req, htc_complete_f *func) { double tmo; double now, when; struct sess *sp; enum htc_status_e hs; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); sp = req->sp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); AZ(isnan(sp->t_idle)); assert(isnan(req->t_first)); when = sp->t_idle + cache_param->timeout_idle; tmo = cache_param->timeout_linger; while (1) { hs = SES_Rx(req->htc, tmo); now = VTIM_real(); if (hs == HTC_S_EOF) { WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b); return (HTC_S_CLOSE); } if (hs == HTC_S_OVERFLOW) { WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b); return (HTC_S_OVERFLOW); } hs = func(req->htc); if (hs == HTC_S_OVERFLOW) { WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b); return (HTC_S_OVERFLOW); } if (hs == HTC_S_JUNK) { WS_ReleaseP(req->htc->ws, req->htc->rxbuf_b); return (HTC_S_JUNK); } if (hs == HTC_S_COMPLETE) { /* Got it, run with it */ if (isnan(req->t_first)) req->t_first = now; req->t_req = now; return (HTC_S_COMPLETE); } if (when < now) return (HTC_S_TIMEOUT); if (hs == HTC_S_MORE) { /* Working on it */ if (isnan(req->t_first)) req->t_first = now; tmo = when - now; continue; } assert(hs == HTC_S_EMPTY); /* Nothing but whitespace */ tmo = sp->t_idle + cache_param->timeout_linger - now; if (tmo < 0) return (HTC_S_IDLE); } }
int V1F_FetchRespHdr(struct busyobj *bo) { struct http *hp; enum htc_status_e hs; int first; struct http_conn *htc; CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); htc = bo->htc; VSC_C_main->backend_req++; /* Receive response */ SES_RxInit(htc, bo->ws, cache_param->http_resp_size, cache_param->http_resp_hdr_len); CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); VTCP_set_read_timeout(htc->fd, htc->first_byte_timeout); first = 1; do { hs = SES_Rx(htc, 0); if (hs == HTC_S_MORE) hs = HTTP1_Complete(htc); if (hs == HTC_S_OVERFLOW) { WS_ReleaseP(htc->ws, htc->rxbuf_b); bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; VSLb(bo->vsl, SLT_FetchError, "http %sread error: overflow", first ? "first " : ""); htc->doclose = SC_RX_OVERFLOW; return (-1); } if (hs == HTC_S_EOF) { WS_ReleaseP(htc->ws, htc->rxbuf_b); bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF", first ? "first " : ""); htc->doclose = SC_RX_TIMEOUT; return (first ? 1 : -1); } if (first) { first = 0; VTCP_set_read_timeout(htc->fd, htc->between_bytes_timeout); } } while (hs != HTC_S_COMPLETE); bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; hp = bo->beresp; if (HTTP1_DissectResponse(hp, htc)) { VSLb(bo->vsl, SLT_FetchError, "http format error"); htc->doclose = SC_RX_JUNK; return (-1); } htc->doclose = http_DoConnection(hp); return (0); }