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);
}
Esempio n. 2
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);
}
Esempio n. 3
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);
}
Esempio n. 4
0
File: vmod_vsf.c Progetto: aaam/VSF
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));
}
Esempio n. 5
0
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);
}