static unsigned http1_WrTxt(const struct worker *wrk, const txt *hh, const char *suf) { unsigned u; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); AN(wrk); AN(hh); AN(hh->b); AN(hh->e); u = V1L_Write(wrk, hh->b, hh->e - hh->b); if (suf != NULL) u += V1L_Write(wrk, suf, -1); return (u); }
vbf_iter_req_body(void *priv, unsigned flush, const void *ptr, ssize_t l) { struct busyobj *bo; CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); if (l > 0) { (void)V1L_Write(bo->wrk, ptr, l); if (flush && V1L_Flush(bo->wrk)) return (-1); } return (0); }
vbf_iter_req_body(void *priv, int flush, const void *ptr, ssize_t l) { struct busyobj *bo; CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); if (l > 0) { bo->acct.bereq_bodybytes += V1L_Write(bo->wrk, ptr, l); if (flush && V1L_Flush(bo->wrk)) return (-1); } return (0); }
vbf_iter_req_body(struct req *req, void *priv, void *ptr, size_t l) { struct busyobj *bo; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CAST_OBJ_NOTNULL(bo, priv, BUSYOBJ_MAGIC); if (l > 0) { bo->acct.bereq_bodybytes += V1L_Write(bo->wrk, ptr, l); if (V1L_Flush(bo->wrk)) return (-1); } return (0); }
void V1L_EndChunk(const struct worker *wrk) { struct v1l *v1l; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); v1l = wrk->v1l; CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); assert(v1l->ciov < v1l->siov); (void)V1L_Flush(wrk); v1l->ciov = v1l->siov; v1l->niov = 0; v1l->cliov = 0; (void)V1L_Write(wrk, "0\r\n\r\n", -1); }
unsigned HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf) { unsigned u, l; assert(hf == HTTP1_Req || hf == HTTP1_Resp); AN(hp->hd[hf[0]].b); AN(hp->hd[hf[1]].b); AN(hp->hd[hf[2]].b); l = http1_WrTxt(w, &hp->hd[hf[0]], " "); l += http1_WrTxt(w, &hp->hd[hf[1]], " "); l += http1_WrTxt(w, &hp->hd[hf[2]], "\r\n"); for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) l += http1_WrTxt(w, &hp->hd[u], "\r\n"); l += V1L_Write(w, "\r\n", -1); return (l); }
v1d_bytes(struct req *req, enum vdp_action act, void **priv, const void *ptr, ssize_t len) { ssize_t wl = 0; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); (void)priv; if (act == VDP_INIT || act == VDP_FINI) return (0); AZ(req->vdp_nxt); /* always at the bottom of the pile */ if (len > 0) wl = V1L_Write(req->wrk, ptr, len); req->acct.resp_bodybytes += len; if (act > VDP_NULL && V1L_Flush(req->wrk)) return (-1); if (len != wl) return (-1); return (0); }
void V1P_Process(struct req *req, struct busyobj *bo, int fd) { struct worker *wrk; struct pollfd fds[2]; int i; struct acct_pipe acct_pipe; CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC); wrk = req->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); assert(fd > 0); req->res_mode = RES_PIPE; memset(&acct_pipe, 0, sizeof acct_pipe); acct_pipe.req = req->acct.req_hdrbytes; req->acct.req_hdrbytes = 0; CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc->vbc, VBC_MAGIC); bo->wrk = req->wrk; bo->director_state = DIR_S_BODY; (void)VTCP_blocking(fd); V1L_Reserve(wrk, wrk->aws, &fd, bo->vsl, req->t_req); acct_pipe.bereq += HTTP1_Write(wrk, bo->bereq, HTTP1_Req); if (req->htc->pipeline_b != NULL) acct_pipe.in += V1L_Write(wrk, req->htc->pipeline_b, req->htc->pipeline_e - req->htc->pipeline_b); i = V1L_FlushRelease(wrk); VSLb_ts_req(req, "Pipe", W_TIM_real(wrk)); if (i == 0) { if (bo->htc->vbc->state == VBC_STATE_STOLEN) VBT_Wait(req->wrk, bo->htc->vbc); memset(fds, 0, sizeof fds); fds[0].fd = fd; fds[0].events = POLLIN | POLLERR; fds[1].fd = req->sp->fd; fds[1].events = POLLIN | POLLERR; while (fds[0].fd > -1 || fds[1].fd > -1) { fds[0].revents = 0; fds[1].revents = 0; i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3)); if (i < 1) break; if (fds[0].revents && rdf(fd, req->sp->fd, &acct_pipe.out)) { if (fds[1].fd == -1) break; (void)shutdown(fd, SHUT_RD); (void)shutdown(req->sp->fd, SHUT_WR); fds[0].events = 0; fds[0].fd = -1; } if (fds[1].revents && rdf(req->sp->fd, fd, &acct_pipe.in)) { if (fds[0].fd == -1) break; (void)shutdown(req->sp->fd, SHUT_RD); (void)shutdown(fd, SHUT_WR); fds[1].events = 0; fds[1].fd = -1; } } } VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk)); pipecharge(req, &acct_pipe, bo->htc->vbc->backend->vsc); SES_Close(req->sp, SC_TX_PIPE); bo->doclose = SC_TX_PIPE; }