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; 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; 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; } (void)VTCP_blocking(htc->fd); /* XXX: we should timeout instead */ V1L_Reserve(wrk, wrk->aws, &htc->fd, 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); }
int VRB_Ignore(struct req *req) { CHECK_OBJ_NOTNULL(req, REQ_MAGIC); if (req->req_body_status == REQ_BODY_WITH_LEN || req->req_body_status == REQ_BODY_WITHOUT_LEN) (void)VRB_Iterate(req, httpq_req_body_discard, NULL); return(0); }
VCL_VOID vmod_req(VRT_CTX, VCL_STRING val) { //thread check if(ctx->req == NULL || ctx->req->magic != REQ_MAGIC){ VSLb(ctx->vsl, SLT_Error,"vmod-dump: dump.req work only at client-thread."); return; } //remote client local server //VRT_r_remote_ip //VRT_r_client_ip //VRT_r_local_ip //VRT_r_server_ip //VRT_IP_string(IP) ip->str //VSA_Port(IP) ip->port VSLb(ctx->vsl, SLT_Debug,"%s-I: %s %d %s %d", VMOD_DUMP_PRE, VRT_IP_string(ctx, VRT_r_client_ip(ctx)), VSA_Port(VRT_r_client_ip(ctx)), VRT_IP_string(ctx, VRT_r_server_ip(ctx)), VSA_Port(VRT_r_server_ip(ctx)) ); VSLb(ctx->vsl, SLT_Debug,"%s-S: REQ", VMOD_DUMP_PRE); VSLb(ctx->vsl, SLT_Debug,"%s-V: %s", VMOD_DUMP_PRE, val); unsigned u; //reserve work-space u = WS_Reserve(ctx->req->ws, 0); if(u <= VMOD_DUMP_KEY_LEN) { //no space. WS_Release(ctx->req->ws, 0); return; } work_head(ctx->req,ctx->req->ws->f, u, ctx->req->http0,HTTP1_Req); //free work-space WS_Release(ctx->req->ws, 0); VRB_Iterate(ctx->req, vbf_printRequestBody, NULL); VSLb(ctx->vsl, SLT_Debug,"%s-S: END", VMOD_DUMP_PRE); }
vmod_body(VRT_CTX, struct vmod_priv *priv, VCL_BYTES maxsize) { struct vsb *vsb; const char *p; ssize_t size; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); if (priv->priv) return (VSB_data(priv->priv)); if (!http_GetHdr(ctx->req->http, H_Content_Type, &p)) return (NULL); if (strncasecmp(p, FORM_URLENCODED, sizeof(FORM_URLENCODED) - 1)) { VSLb(ctx->vsl, SLT_Error, "vsf.body: Unsupported form encoding (%s)", p); return (NULL); } size = VRT_CacheReqBody(ctx, maxsize); if (size <= 0) return (NULL); vsb = VSB_new(NULL, NULL, size + 1, 0); if (!vsb) { VSLb(ctx->vsl, SLT_Error, "vsf.body: Out of memory"); return (NULL); } if (VRB_Iterate(ctx->req, vsf_iter_req_body, vsb) == -1) { VSLb(ctx->vsl, SLT_Error, "vsf.body: Problem fetching the body"); VSB_delete(vsb); return (NULL); } AZ(VSB_finish(vsb)); priv->free = (vmod_priv_free_f *)VSB_delete; priv->priv = vsb; return (VSB_data(vsb)); }
int V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, uint64_t *ctr_bodybytes, int onlycached, char *abuf, char *pbuf) { struct http *hp; int j; ssize_t i; uint64_t bytes, hdrbytes; struct http_conn *htc; int do_chunked = 0; 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); AN(ctr_hdrbytes); AN(ctr_bodybytes); 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; } VSLb(bo->vsl, SLT_BackendStart, "%s %s", abuf, pbuf); (void)VTCP_blocking(*htc->rfd); /* XXX: we should timeout instead */ V1L_Open(wrk, wrk->aws, htc->rfd, bo->vsl, bo->t_prev, 0); hdrbytes = 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, vstrerror(errno)); bo->req->doclose = SC_RX_BODY; } if (do_chunked) V1L_EndChunk(wrk); } j = V1L_Close(wrk, &bytes); /* Bytes accounting */ if (bytes < hdrbytes) *ctr_hdrbytes += bytes; else { *ctr_hdrbytes += hdrbytes; *ctr_bodybytes += bytes - hdrbytes; } if (j != 0 || i < 0) { VSLb(bo->vsl, SLT_FetchError, "backend write error: %d (%s)", errno, vstrerror(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); }
int V1F_fetch_hdr(struct worker *wrk, struct busyobj *bo, const char *def_host) { struct http *hp; enum http1_status_e hs; int retry = 1; int j, first; ssize_t i; struct http_conn *htc; int do_chunked = 0; 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; hp = bo->bereq; /* * Now that we know our backend, we can set a default Host: * header if one is necessary. This cannot be done in the VCL * because the backend may be chosen by a director. */ if (!http_GetHdr(bo->bereq, H_Host, NULL) && def_host != NULL) http_PrintfHeader(hp, "Host: %s", def_host); if (bo->req != NULL && bo->req->req_body_status == REQ_BODY_WITHOUT_LEN) { http_PrintfHeader(hp, "Transfer-Encoding: chunked"); do_chunked = 1; } (void)VTCP_blocking(htc->fd); /* XXX: we should timeout instead */ V1L_Reserve(wrk, wrk->aws, &htc->fd, bo->vsl, bo->t_prev); bo->acct.bereq_hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); /* Deal with any message-body the request might (still) have */ i = 0; if (bo->req != NULL) { if (do_chunked) V1L_Chunked(wrk); i = VRB_Iterate(bo->req, vbf_iter_req_body, bo); if (bo->req->req_body_status == REQ_BODY_TAKEN) { retry = -1; } else if (bo->req->req_body_status == REQ_BODY_FAIL) { VSLb(bo->vsl, SLT_FetchError, "req.body read error: %d (%s)", errno, strerror(errno)); bo->req->doclose = SC_RX_BODY; retry = -1; } 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)); bo->doclose = SC_TX_ERROR; return (retry); } VSLb_ts_busyobj(bo, "Bereq", W_TIM_real(wrk)); VSC_C_main->backend_req++; /* Receive response */ HTTP1_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 = HTTP1_Rx(htc); if (hs == HTTP1_OVERFLOW) { bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; VSLb(bo->vsl, SLT_FetchError, "http %sread error: overflow", first ? "first " : ""); bo->doclose = SC_RX_OVERFLOW; return (-1); } if (hs == HTTP1_ERROR_EOF) { bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; VSLb(bo->vsl, SLT_FetchError, "http %sread error: EOF", first ? "first " : ""); bo->doclose = SC_RX_TIMEOUT; return (retry); } if (first) { retry = -1; first = 0; VTCP_set_read_timeout(htc->fd, htc->between_bytes_timeout); } } while (hs != HTTP1_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"); bo->doclose = SC_RX_JUNK; return (-1); } bo->doclose = http_DoConnection(hp); return (0); }