static struct vsb * sock_id(const char *pfx, int fd) { struct vsb *vsb; char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; vsb = VSB_new_auto(); AN(vsb); VTCP_myname(fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); VTCP_hisname(fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); VSB_printf(vsb, "%s %s %s %s %s", pfx, abuf2, pbuf2, abuf1, pbuf1); AZ(VSB_finish(vsb)); return (vsb); }
int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd) { struct http *hp; int retval; (void)sfd; ALLOC_OBJ(hp, HTTP_MAGIC); AN(hp); hp->fd = sock; hp->timeout = vtc_maxdur * 1000 / 2; hp->nrxbuf = 2048*1024; hp->rxbuf = malloc(hp->nrxbuf); /* XXX */ AN(hp->rxbuf); hp->vsb = VSB_new_auto(); AN(hp->vsb); hp->sfd = sfd; hp->rem_ip = malloc(VTCP_ADDRBUFSIZE); AN(hp->rem_ip); hp->rem_port = malloc(VTCP_PORTBUFSIZE); AN(hp->rem_port); hp->vl = vl; hp->gziplevel = 0; hp->gzipresidual = -1; VTCP_hisname(sock, hp->rem_ip, VTCP_ADDRBUFSIZE, hp->rem_port, VTCP_PORTBUFSIZE); parse_string(spec, http_cmds, hp, vl); retval = hp->fd; VSB_destroy(&hp->vsb); free(hp->rxbuf); free(hp->rem_ip); free(hp->rem_port); free(hp); return (retval); }
static struct vbc * vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo) { struct vbc *vc; double tmod; char abuf1[VTCP_ADDRBUFSIZE], abuf2[VTCP_ADDRBUFSIZE]; char pbuf1[VTCP_PORTBUFSIZE], pbuf2[VTCP_PORTBUFSIZE]; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); AN(bp->vsc); if (!VBE_Healthy(bp, NULL)) { // XXX: per backend stats ? VSC_C_main->backend_unhealthy++; return (NULL); } if (bp->max_connections > 0 && bp->n_conn >= bp->max_connections) { // XXX: per backend stats ? VSC_C_main->backend_busy++; return (NULL); } AZ(bo->htc); bo->htc = WS_Alloc(bo->ws, sizeof *bo->htc); if (bo->htc == NULL) /* XXX: counter ? */ return (NULL); bo->htc->doclose = SC_NULL; FIND_TMO(connect_timeout, tmod, bo, bp); vc = VBT_Get(bp->tcp_pool, tmod, bp, wrk); if (vc == NULL) { // XXX: Per backend stats ? VSC_C_main->backend_fail++; bo->htc = NULL; return (NULL); } assert(vc->fd >= 0); AN(vc->addr); Lck_Lock(&bp->mtx); bp->n_conn++; bp->vsc->conn++; bp->vsc->req++; Lck_Unlock(&bp->mtx); if (bp->proxy_header != 0) VPX_Send_Proxy(vc->fd, bp->proxy_header, bo->sp); VTCP_myname(vc->fd, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1); VTCP_hisname(vc->fd, abuf2, sizeof abuf2, pbuf2, sizeof pbuf2); VSLb(bo->vsl, SLT_BackendOpen, "%d %s %s %s %s %s", vc->fd, bp->display_name, abuf2, pbuf2, abuf1, pbuf1); INIT_OBJ(bo->htc, HTTP_CONN_MAGIC); bo->htc->priv = vc; bo->htc->fd = vc->fd; FIND_TMO(first_byte_timeout, bo->htc->first_byte_timeout, bo, bp); FIND_TMO(between_bytes_timeout, bo->htc->between_bytes_timeout, bo, bp); return (vc); }
int V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr, int onlycached) { struct http *hp; int j; ssize_t i; struct http_conn *htc; int do_chunked = 0; char abuf[VTCP_ADDRBUFSIZE]; char pbuf[VTCP_PORTBUFSIZE]; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); CHECK_OBJ_ORNULL(bo->req, REQ_MAGIC); htc = bo->htc; assert(*htc->rfd > 0); hp = bo->bereq; if (bo->req != NULL && bo->req->req_body_status == REQ_BODY_WITHOUT_LEN) { http_PrintfHeader(hp, "Transfer-Encoding: chunked"); do_chunked = 1; } VTCP_hisname(*htc->rfd, abuf, sizeof abuf, pbuf, sizeof pbuf); VSLb(bo->vsl, SLT_BackendStart, "%s %s", abuf, pbuf); (void)VTCP_blocking(*htc->rfd); /* XXX: we should timeout instead */ V1L_Reserve(wrk, wrk->aws, htc->rfd, bo->vsl, bo->t_prev); *ctr += HTTP1_Write(wrk, hp, HTTP1_Req); /* Deal with any message-body the request might (still) have */ i = 0; if (bo->req != NULL && (bo->req->req_body_status == REQ_BODY_CACHED || !onlycached)) { if (do_chunked) V1L_Chunked(wrk); i = VRB_Iterate(bo->req, vbf_iter_req_body, bo); if (bo->req->req_body_status == REQ_BODY_FAIL) { assert(i < 0); VSLb(bo->vsl, SLT_FetchError, "req.body read error: %d (%s)", errno, strerror(errno)); bo->req->doclose = SC_RX_BODY; } if (do_chunked) V1L_EndChunk(wrk); } j = V1L_FlushRelease(wrk); if (j != 0 || i < 0) { VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", errno, strerror(errno)); VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); htc->doclose = SC_TX_ERROR; return (-1); } VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); return (0); }