Exemplo n.º 1
0
VCL_VOID
VRT_l_beresp_storage_hint(VRT_CTX, const char *str, ...)
{
	const char *p;
	va_list ap;
	uintptr_t sn;
	VCL_STEVEDORE stv;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);

	sn = WS_Snapshot(ctx->ws);
	va_start(ap, str);
	p = VRT_String(ctx->ws, NULL, str, ap);
	va_end(ap);

	if (p == NULL) {
		VSLb(ctx->vsl, SLT_LostHeader, "storage_hint");
		WS_Reset(ctx->ws, sn);
		WS_MarkOverflow(ctx->ws);
		return;
	}

	stv = VRT_stevedore(p);
	if (stv != NULL)
		ctx->bo->storage = stv;

	WS_Reset(ctx->ws, sn);
}
Exemplo n.º 2
0
vmod_log(VRT_CTX, const char *fmt, ...)
{
	const char *p;
	va_list ap;
	uintptr_t sn;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	sn = WS_Snapshot(ctx->ws);
	va_start(ap, fmt);
	p = VRT_String(ctx->ws, NULL, fmt, ap);
	va_end(ap);

	if (p == NULL) {
		WS_MarkOverflow(ctx->ws);
		WS_Reset(ctx->ws, sn);
		return;
	}

	AN(p);
	if (ctx->vsl != NULL)
		VSLb(ctx->vsl, SLT_VCL_Log, "%s", p);
	else
		VSL(SLT_VCL_Log, 0, "%s", p);
	WS_Reset(ctx->ws, sn);
}
static int
cnt_pipe(struct sess *sp)
{

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);

    sp->acct_req.pipe++;
    WS_Reset(sp->wrk->ws, NULL);
    sp->wrk->bereq = &sp->wrk->http[0];
    http_Setup(sp->wrk->bereq, sp->wrk->ws);
    http_FilterHeader(sp, HTTPH_R_PIPE);

    VCL_pipe_method(sp);

    if (sp->handling == VCL_RET_ERROR)
        INCOMPL();
    assert(sp->handling == VCL_RET_PIPE);

    PipeSession(sp);
    AZ(sp->wrk->wfd);
    sp->wrk->bereq = NULL;
    sp->step = STP_DONE;
    return (0);
}
static int
cnt_miss(struct sess *sp)
{

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);

    AZ(sp->obj);
    AN(sp->objcore);
    AN(sp->objhead);
    WS_Reset(sp->wrk->ws, NULL);
    sp->wrk->bereq = &sp->wrk->http[0];
    http_Setup(sp->wrk->bereq, sp->wrk->ws);
    http_FilterHeader(sp, HTTPH_R_FETCH);
    VCL_miss_method(sp);
    switch(sp->handling) {
    case VCL_RET_ERROR:
        HSH_DerefObjCore(sp);
        sp->step = STP_ERROR;
        return (0);
    case VCL_RET_PASS:
        HSH_DerefObjCore(sp);
        sp->step = STP_PASS;
        return (0);
    case VCL_RET_FETCH:
        sp->step = STP_FETCH;
        return (0);
    case VCL_RET_RESTART:
        HSH_DerefObjCore(sp);
        INCOMPL();
    default:
        WRONG("Illegal action in vcl_miss{}");
    }
}
Exemplo n.º 5
0
static int
cnt_pipe(struct sess *sp)
{
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
    AZ(wrk->busyobj);

    wrk->acct_tmp.pipe++;
    wrk->busyobj = VBO_GetBusyObj(wrk);
    WS_Reset(wrk->ws, NULL);
    wrk->busyobj = VBO_GetBusyObj(wrk);
    http_Setup(wrk->busyobj->bereq, wrk->ws);
    http_FilterHeader(sp, HTTPH_R_PIPE);

    VCL_pipe_method(sp);

    if (sp->handling == VCL_RET_ERROR)
        INCOMPL();
    assert(sp->handling == VCL_RET_PIPE);

    PipeSession(sp);
    assert(WRW_IsReleased(wrk));
    http_Setup(wrk->busyobj->bereq, NULL);
    VBO_DerefBusyObj(wrk, &wrk->busyobj);
    sp->step = STP_DONE;
    return (0);
}
Exemplo n.º 6
0
static int
cnt_pass(struct sess *sp)
{
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
    AZ(wrk->obj);
    AZ(wrk->busyobj);

    wrk->busyobj = VBO_GetBusyObj(wrk);
    WS_Reset(wrk->ws, NULL);
    wrk->busyobj = VBO_GetBusyObj(wrk);
    http_Setup(wrk->busyobj->bereq, wrk->ws);
    http_FilterHeader(sp, HTTPH_R_PASS);

    wrk->connect_timeout = 0;
    wrk->first_byte_timeout = 0;
    wrk->between_bytes_timeout = 0;
    VCL_pass_method(sp);
    if (sp->handling == VCL_RET_ERROR) {
        http_Setup(wrk->busyobj->bereq, NULL);
        VBO_DerefBusyObj(wrk, &wrk->busyobj);
        sp->step = STP_ERROR;
        return (0);
    }
    assert(sp->handling == VCL_RET_PASS);
    wrk->acct_tmp.pass++;
    sp->sendbody = 1;
    sp->step = STP_FETCH;
    return (0);
}
Exemplo n.º 7
0
void
VRT_Rollback(struct sess *sp)
{

	HTTP_Copy(sp->http, sp->http0);
	WS_Reset(sp->ws, sp->ws_req);
}
Exemplo n.º 8
0
void
VRT_Rollback(const struct vrt_ctx *ctx)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
	HTTP_Copy(ctx->req->http, ctx->req->http0);
	WS_Reset(ctx->req->ws, ctx->req->ws_req);
}
Exemplo n.º 9
0
void
VRT_Rollback(VRT_CTX, const struct http *hp)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	if (hp == ctx->http_req) {
		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
		HTTP_Copy(ctx->req->http, ctx->req->http0);
		WS_Reset(ctx->req->ws, ctx->req->ws_req);
	} else if (hp == ctx->http_bereq) {
		CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
		HTTP_Copy(ctx->bo->bereq, ctx->bo->bereq0);
		WS_Reset(ctx->bo->bereq->ws, ctx->bo->ws_bo);
		WS_Reset(ctx->bo->ws, ctx->bo->ws_bo);
	} else
		WRONG("VRT_Rollback 'hp' invalid");
}
Exemplo n.º 10
0
void
Req_Rollback(struct req *req)
{
	VCL_TaskLeave(req->vcl, req->privs);
	VCL_TaskEnter(req->vcl, req->privs);
	HTTP_Clone(req->http, req->http0);
	if (WS_Overflowed(req->ws))
		req->wrk->stats->ws_client_overflow++;
	WS_Reset(req->ws, req->ws_req);
}
Exemplo n.º 11
0
void
vmod_workspace_reset(VRT_CTX, VCL_ENUM which)
{
	struct ws *ws;
	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);

	ws = wsfind(ctx, which);
	WS_Assert(ws);

	WS_Reset(ws, debug_ws_snap);
}
Exemplo n.º 12
0
static void
WRW_Release(struct worker *wrk)
{
	struct wrw *wrw;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	wrw = wrk->wrw;
	wrk->wrw = NULL;
	CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC);
	WS_Release(wrk->aws, 0);
	WS_Reset(wrk->aws, NULL);
}
Exemplo n.º 13
0
static void *
server_bgthread(struct worker *wrk, void *priv)
{
	struct vmod_fsdirector_file_system *fs;
	struct sockaddr_storage addr_s;
	socklen_t len;
	struct http_conn *htc;
	int fd;
	enum htc_status_e htc_status;

	CAST_OBJ_NOTNULL(fs, priv, VMOD_FSDIRECTOR_MAGIC);
	assert(fs->sock >= 0);

	htc = &fs->htc;
	fs->wrk = wrk;
	WS_Init(wrk->aws, fs->ws_name, malloc(WS_LEN), WS_LEN);

	while (1) {
		do {
			fd = accept(fs->sock, (void*)&addr_s, &len);
		} while (fd < 0 && errno == EAGAIN);

		if (fd < 0) {
			continue;
		}

		HTTP1_Init(htc, wrk->aws, fd, NULL, HTTP1_BUF, HTTP1_MAX_HDR);

		htc_status = HTTP1_Rx(htc);
		switch (htc_status) {
			case HTTP1_OVERFLOW:
			case HTTP1_ERROR_EOF:
			case HTTP1_ALL_WHITESPACE:
			case HTTP1_NEED_MORE:
				prepare_answer(htc, 400);
				prepare_body(htc);
				break;
			case HTTP1_COMPLETE:
				answer_appropriate(fs);
				break;
		}

		WS_Reset(wrk->aws, NULL);
		close(fd);
	}

	pthread_exit(0);

	NEEDLESS_RETURN(NULL);
}
Exemplo n.º 14
0
static void
wrw_release(struct worker *wrk, uint64_t *pacc)
{
	struct wrw *wrw;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	wrw = wrk->wrw;
	wrk->wrw = NULL;
	CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC);
	if (pacc != NULL)
		*pacc += wrw->cnt;
	WS_Release(wrk->aws, 0);
	WS_Reset(wrk->aws, NULL);
}
Exemplo n.º 15
0
vmod_syslog(VRT_CTX, VCL_INT fac, const char *fmt, ...)
{
	const char *p;
	va_list ap;
	uintptr_t sn;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	sn = WS_Snapshot(ctx->ws);
	va_start(ap, fmt);
	p = VRT_String(ctx->ws, NULL, fmt, ap);
	va_end(ap);
	if (p != NULL)
		syslog((int)fac, "%s", p);
	WS_Reset(ctx->ws, sn);
}
Exemplo n.º 16
0
unsigned
V1L_FlushRelease(struct worker *wrk)
{
	struct v1l *v1l;
	unsigned u;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	u = V1L_Flush(wrk);
	v1l = wrk->v1l;
	wrk->v1l = NULL;
	CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC);
	WS_Release(v1l->ws, 0);
	WS_Reset(v1l->ws, v1l->res);
	return (u);
}
Exemplo n.º 17
0
void
Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->topreq, REQ_MAGIC);
	assert(sp == req->sp);
	AZ(req->vcl0);

	req->director_hint = NULL;
	req->restarts = 0;

	AZ(req->privs->magic);

	if (req->vcl != NULL)
		VCL_Recache(wrk, &req->vcl);

	/* Charge and log byte counters */
	req_AcctLogCharge(wrk->stats, req);
	if (req->vsl->wid)
		VSL_End(req->vsl);

	if (!isnan(req->t_prev) && req->t_prev > 0. && req->t_prev > sp->t_idle)
		sp->t_idle = req->t_prev;
	else
		sp->t_idle = W_TIM_real(wrk);

	req->t_first = NAN;
	req->t_prev = NAN;
	req->t_req = NAN;
	req->req_body_status = REQ_BODY_INIT;

	req->hash_always_miss = 0;
	req->hash_ignore_busy = 0;
	req->esi_level = 0;
	req->is_hit = 0;

	if (WS_Overflowed(req->ws))
		wrk->stats->ws_client_overflow++;

	WS_Reset(req->ws, 0);
}
Exemplo n.º 18
0
enum vgzret_e
VGZ_Destroy(struct vgz **vgp)
{
	struct vgz *vg;
	enum vgzret_e vr;
	int i;

	vg = *vgp;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	*vgp = NULL;

	VSLb(vg->vsl, SLT_Gzip, "%s %jd %jd %jd %jd %jd",
	    vg->id,
	    (intmax_t)vg->vz.total_in,
	    (intmax_t)vg->vz.total_out,
	    (intmax_t)vg->vz.start_bit,
	    (intmax_t)vg->vz.last_bit,
	    (intmax_t)vg->vz.stop_bit);
	if (vg->tmp != NULL)
		WS_Reset(vg->tmp, vg->tmp_snapshot);
	if (vg->dir == VGZ_GZ)
		i = deflateEnd(&vg->vz);
	else
		i = inflateEnd(&vg->vz);
	if (vg->last_i == Z_STREAM_END && i == Z_OK)
		i = Z_STREAM_END;
	if (vg->m_buf)
		free(vg->m_buf);
	if (i == Z_OK)
		vr = VGZ_OK;
	else if (i == Z_STREAM_END)
		vr = VGZ_END;
	else if (i == Z_BUF_ERROR)
		vr = VGZ_STUCK;
	else {
		VSLb(vg->vsl, SLT_Gzip, "G(un)zip error: %d (%s)", i, vg->vz.msg);
		vr = VGZ_ERROR;
	}
	FREE_OBJ(vg);
	return (vr);
}
static int
cnt_pass(struct sess *sp)
{

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);
    AZ(sp->obj);

    WS_Reset(sp->wrk->ws, NULL);
    sp->wrk->bereq = &sp->wrk->http[0];
    http_Setup(sp->wrk->bereq, sp->wrk->ws);
    http_FilterHeader(sp, HTTPH_R_PASS);

    VCL_pass_method(sp);
    if (sp->handling == VCL_RET_ERROR) {
        sp->step = STP_ERROR;
        return (0);
    }
    assert(sp->handling == VCL_RET_PASS);
    sp->acct_req.pass++;
    sp->sendbody = 1;
    sp->step = STP_FETCH;
    return (0);
}
Exemplo n.º 20
0
int
VGZ_Destroy(struct vgz **vgp)
{
	struct vgz *vg;
	int i;

	vg = *vgp;
	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
	*vgp = NULL;

	VSLb(vg->vsl, SLT_Gzip, "%s %jd %jd %jd %jd %jd",
	    vg->id,
	    (intmax_t)vg->vz.total_in,
	    (intmax_t)vg->vz.total_out,
	    (intmax_t)vg->vz.start_bit,
	    (intmax_t)vg->vz.last_bit,
	    (intmax_t)vg->vz.stop_bit);
	if (vg->tmp != NULL)
		WS_Reset(vg->tmp, vg->tmp_snapshot);
	if (vg->dir == VGZ_GZ)
		i = deflateEnd(&vg->vz);
	else
		i = inflateEnd(&vg->vz);
	if (vg->last_i == Z_STREAM_END && i == Z_OK)
		i = Z_STREAM_END;
	if (vg->m_buf)
		free(vg->m_buf);
	FREE_OBJ(vg);
	if (i == Z_OK)
		return (VGZ_OK);
	if (i == Z_STREAM_END)
		return (VGZ_END);
	if (i == Z_BUF_ERROR)
		return (VGZ_STUCK);
	return (VGZ_ERROR);
}
Exemplo n.º 21
0
static const char *
sort_querystring(struct ws *ws, const char *uri)
{
	if (uri == NULL) {
		return NULL;
	}

	char *query_string = strchr(uri, '?');
	if (query_string == NULL) {
		return uri;
	}

	if (query_string[1] == '\0') {
		return truncate_querystring(ws, uri, query_string);
	}

	/* reserve some memory */
	char *snapshot = WS_Snapshot(ws);
	char *sorted_uri = WS_Alloc(ws, strlen(uri) + 1);

	WS_Assert(ws);

	if (sorted_uri == NULL) {
		WS_Reset(ws, snapshot);
		return uri;
	}

	unsigned available = WS_Reserve(ws, 0);
	struct query_param *params = (struct query_param*) ws->f;
	struct query_param *end = params + available;

	/* initialize the params array */
	int head = 10;

	if (&params[head + 1] > end) {
		head = 0;
	}

	if (&params[head + 1] > end) {
		WS_Release(ws, 0);
		WS_Reset(ws, snapshot);
		return uri;
	}

	int tail = head;
	int last_param = head;

	/* search and sort params */
	bool sorted = true;
	char *c = query_string + 1;
	params[head].value = c;

	for (; *c != '\0' && &params[tail+1] < end; c++) {
		if (*c != '&') {
			continue;
		}

		const char *current_param = c+1;
		params[last_param].length = c - params[last_param].value;

		if (head > 0 && compare_params(params[head].value, current_param) > -1) {
			sorted = false;
			params[--head].value = current_param;
			last_param = head;
			continue;
		}

		if (compare_params(params[tail].value, current_param) < 1) {
			params[++tail].value = current_param;
			last_param = tail;
			continue;
		}

		sorted = false;

		int i = tail++;
		params[tail] = params[i];

		int previous = i-1;
		while (i > head && compare_params(params[previous].value, current_param) > -1) {
			params[i--] = params[previous--];
		}

		params[i].value = current_param;
		last_param = i;
	}

	if (sorted == true || &params[tail+1] >= end || tail - head < 1) {
		WS_Release(ws, 0);
		WS_Reset(ws, snapshot);
		return uri;
	}

	params[last_param].length = c - params[last_param].value;

	/* copy the url parts */
	char *position = mempcpy(sorted_uri, uri, query_string - uri + 1);
	int count = tail-head;

	for (;count > 0; count--, ++head) {
		if (params[head].length > 0) {
			position = mempcpy(position, params[head].value, params[head].length);
			*position++ = '&';
		}
	}

	if (params[head].length > 0) {
		position = mempcpy(position, params[head].value, params[head].length);
	}
	else {
		position--;
	}

	*position = '\0';

	WS_Release(ws, 0);
	return sorted_uri;
}
Exemplo n.º 22
0
void
Pool_Work_Thread(struct pool *pp, struct worker *wrk)
{
	struct pool_task *tp;
	struct pool_task tpx, tps;
	int i;

	CHECK_OBJ_NOTNULL(pp, POOL_MAGIC);
	wrk->pool = pp;
	while (1) {
		Lck_Lock(&pp->mtx);

		CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);

		WS_Reset(wrk->aws, NULL);
		AZ(wrk->vsl);

		tp = VTAILQ_FIRST(&pp->front_queue);
		if (tp != NULL) {
			pp->lqueue--;
			VTAILQ_REMOVE(&pp->front_queue, tp, list);
		} else {
			tp = VTAILQ_FIRST(&pp->back_queue);
			if (tp != NULL)
				VTAILQ_REMOVE(&pp->back_queue, tp, list);
		}

		if ((tp == NULL && wrk->stats->summs > 0) ||
		    (wrk->stats->summs >= cache_param->wthread_stats_rate))
			pool_addstat(pp->a_stat, wrk->stats);

		if (tp != NULL) {
			wrk->stats->summs++;
		} else if (pp->b_stat != NULL && pp->a_stat->summs) {
			/* Nothing to do, push pool stats into global pool */
			tps.func = pool_stat_summ;
			tps.priv = pp->a_stat;
			pp->a_stat = pp->b_stat;
			pp->b_stat = NULL;
			tp = &tps;
		} else {
			/* Nothing to do: To sleep, perchance to dream ... */
			if (isnan(wrk->lastused))
				wrk->lastused = VTIM_real();
			wrk->task.func = NULL;
			wrk->task.priv = wrk;
			VTAILQ_INSERT_HEAD(&pp->idle_queue, &wrk->task, list);
			do {
				i = Lck_CondWait(&wrk->cond, &pp->mtx,
				    wrk->vcl == NULL ?  0 : wrk->lastused+60.);
				if (i == ETIMEDOUT)
					VCL_Rel(&wrk->vcl);
			} while (wrk->task.func == NULL);
			tpx = wrk->task;
			tp = &tpx;
			wrk->stats->summs++;
		}
		Lck_Unlock(&pp->mtx);

		if (tp->func == pool_kiss_of_death)
			break;

		do {
			memset(&wrk->task, 0, sizeof wrk->task);
			assert(wrk->pool == pp);
			tp->func(wrk, tp->priv);
			tpx = wrk->task;
			tp = &tpx;
		} while (tp->func != NULL);

		/* cleanup for next task */
		wrk->seen_methods = 0;
	}
	wrk->pool = NULL;
}
Exemplo n.º 23
0
static int
cnt_miss(struct sess *sp)
{
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
    CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC);

    AZ(wrk->obj);
    AN(wrk->objcore);
    CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
    WS_Reset(wrk->ws, NULL);
    wrk->busyobj = VBO_GetBusyObj(wrk);
    http_Setup(wrk->busyobj->bereq, wrk->ws);
    http_FilterHeader(sp, HTTPH_R_FETCH);
    http_ForceGet(wrk->busyobj->bereq);
    if (cache_param->http_gzip_support) {
        /*
         * We always ask the backend for gzip, even if the
         * client doesn't grok it.  We will uncompress for
         * the minority of clients which don't.
         */
        http_Unset(wrk->busyobj->bereq, H_Accept_Encoding);
        http_SetHeader(wrk, sp->vsl_id, wrk->busyobj->bereq,
                       "Accept-Encoding: gzip");
    }
    wrk->connect_timeout = 0;
    wrk->first_byte_timeout = 0;
    wrk->between_bytes_timeout = 0;

    VCL_miss_method(sp);

    switch(sp->handling) {
    case VCL_RET_ERROR:
        AZ(HSH_Deref(wrk, wrk->objcore, NULL));
        wrk->objcore = NULL;
        http_Setup(wrk->busyobj->bereq, NULL);
        VBO_DerefBusyObj(wrk, &wrk->busyobj);
        sp->step = STP_ERROR;
        return (0);
    case VCL_RET_PASS:
        AZ(HSH_Deref(wrk, wrk->objcore, NULL));
        wrk->objcore = NULL;
        VBO_DerefBusyObj(wrk, &wrk->busyobj);
        sp->step = STP_PASS;
        return (0);
    case VCL_RET_FETCH:
        CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
        sp->step = STP_FETCH;
        return (0);
    case VCL_RET_RESTART:
        AZ(HSH_Deref(wrk, wrk->objcore, NULL));
        wrk->objcore = NULL;
        VBO_DerefBusyObj(wrk, &wrk->busyobj);
        INCOMPL();
    default:
        WRONG("Illegal action in vcl_miss{}");
    }
}
Exemplo n.º 24
0
static int
cnt_done(struct sess *sp)
{
    double dh, dp, da;
    int i;
    struct worker *wrk;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    wrk = sp->wrk;
    CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
    CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC);

    AZ(wrk->obj);
    AZ(wrk->busyobj);
    sp->director = NULL;
    sp->restarts = 0;

    wrk->busyobj = NULL;

    SES_Charge(sp);

    /* If we did an ESI include, don't mess up our state */
    if (sp->esi_level > 0)
        return (1);

    if (sp->vcl != NULL) {
        if (wrk->vcl != NULL)
            VCL_Rel(&wrk->vcl);
        wrk->vcl = sp->vcl;
        sp->vcl = NULL;
    }


    sp->t_end = W_TIM_real(wrk);
    WSP(sp, SLT_Debug, "PHK req %.9f resp %.9f end %.9f open %.9f",
        sp->t_req, sp->t_resp, sp->t_end,  sp->t_open);
    if (sp->xid == 0) {
        // sp->t_req = sp->t_end;
        sp->t_resp = sp->t_end;
    } else {
        dp = sp->t_resp - sp->t_req;
        da = sp->t_end - sp->t_resp;
        dh = sp->t_req - sp->t_open;
        /* XXX: Add StatReq == StatSess */
        /* XXX: Workaround for pipe */
        if (sp->fd >= 0) {
            WSP(sp, SLT_Length, "%ju",
                (uintmax_t)sp->req_bodybytes);
        }
        WSP(sp, SLT_ReqEnd, "%u %.9f %.9f %.9f %.9f %.9f",
            sp->xid, sp->t_req, sp->t_end, dh, dp, da);
    }
    sp->xid = 0;
    WSL_Flush(wrk, 0);

    sp->t_open = sp->t_end;
    sp->t_resp = NAN;

    sp->req_bodybytes = 0;

    sp->t_req = NAN;
    sp->hash_always_miss = 0;
    sp->hash_ignore_busy = 0;

    if (sp->fd >= 0 && sp->doclose != NULL) {
        /*
         * This is an orderly close of the connection; ditch nolinger
         * before we close, to get queued data transmitted.
         */
        // XXX: not yet (void)VTCP_linger(sp->fd, 0);
        SES_Close(sp, sp->doclose);
    }

    if (sp->fd < 0) {
        wrk->stats.sess_closed++;
        SES_Delete(sp, NULL);
        return (1);
    }

    if (wrk->stats.client_req >= cache_param->wthread_stats_rate)
        WRK_SumStat(wrk);
    /* Reset the workspace to the session-watermark */
    WS_Reset(sp->ws, sp->ws_ses);
    WS_Reset(wrk->ws, NULL);

    i = HTC_Reinit(sp->htc);
    if (i == 1) {
        wrk->stats.sess_pipeline++;
        sp->step = STP_START;
        return (0);
    }
    if (Tlen(sp->htc->rxbuf)) {
        wrk->stats.sess_readahead++;
        sp->step = STP_WAIT;
        return (0);
    }
    if (cache_param->session_linger > 0) {
        wrk->stats.sess_linger++;
        sp->step = STP_WAIT;
        return (0);
    }
    wrk->stats.sess_herd++;
    Pool_Wait(sp);
    return (1);
}
static int
cnt_done(struct sess *sp)
{
    double dh, dp, da;
    int i;

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
    CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC);

    AZ(sp->obj);
    AZ(sp->vbe);
    sp->director = NULL;
    sp->restarts = 0;

    if (sp->vcl != NULL && sp->esis == 0) {
        if (sp->wrk->vcl != NULL)
            VCL_Rel(&sp->wrk->vcl);
        sp->wrk->vcl = sp->vcl;
        sp->vcl = NULL;
    }

    sp->t_end = TIM_real();
    sp->wrk->lastused = sp->t_end;
    if (sp->xid == 0) {
        sp->t_req = sp->t_end;
        sp->t_resp = sp->t_end;
    }
    dp = sp->t_resp - sp->t_req;
    da = sp->t_end - sp->t_resp;
    dh = sp->t_req - sp->t_open;
    WSL(sp->wrk, SLT_ReqEnd, sp->id, "%u %.9f %.9f %.9f %.9f %.9f",
        sp->xid, sp->t_req, sp->t_end, dh, dp, da);

    sp->xid = 0;
    sp->t_open = sp->t_end;
    sp->t_resp = NAN;
    WSL_Flush(sp->wrk, 0);

    /* If we did an ESI include, don't mess up our state */
    if (sp->esis > 0)
        return (1);

    sp->t_req = NAN;

    if (sp->fd >= 0 && sp->doclose != NULL) {
        /*
         * This is an orderly close of the connection; ditch nolinger
         * before we close, to get queued data transmitted.
         */
        TCP_linger(sp->fd, 0);
        vca_close_session(sp, sp->doclose);
    }
    if (sp->fd < 0) {
        SES_Charge(sp);
        VSL_stats->sess_closed++;
        sp->wrk = NULL;
        SES_Delete(sp);
        return (1);
    }

    /* Reset the workspace to the session-watermark */
    WS_Reset(sp->ws, sp->ws_ses);

    i = HTC_Reinit(sp->htc);
    if (i == 1) {
        VSL_stats->sess_pipeline++;
        sp->step = STP_START;
        return (0);
    }
    if (Tlen(sp->htc->rxbuf)) {
        VSL_stats->sess_readahead++;
        sp->step = STP_WAIT;
        return (0);
    }
    if (params->session_linger > 0) {
        VSL_stats->sess_linger++;
        sp->step = STP_WAIT;
        return (0);
    }
    VSL_stats->sess_herd++;
    SES_Charge(sp);
    sp->wrk = NULL;
    vca_return_session(sp);
    return (1);
}
Exemplo n.º 26
0
static enum http1_cleanup_ret
http1_cleanup(struct sess *sp, struct worker *wrk, struct req *req)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_ORNULL(req->vcl, VCL_CONF_MAGIC);

	req->director_hint = NULL;
	req->restarts = 0;

	AZ(req->esi_level);

	if (req->vcl != NULL) {
		if (wrk->vcl != NULL)
			VCL_Rel(&wrk->vcl);
		wrk->vcl = req->vcl;
		req->vcl = NULL;
	}

	/* Charge and log byte counters */
	AN(req->vsl->wid);
	CNT_AcctLogCharge(wrk->stats, req);
	req->req_bodybytes = 0;
	req->resp_hdrbytes = 0;
	req->resp_bodybytes = 0;

	VSL_End(req->vsl);

	if (!isnan(req->t_prev) && req->t_prev > 0.)
		sp->t_idle = req->t_prev;
	else
		sp->t_idle = W_TIM_real(wrk);

	req->t_first = NAN;
	req->t_prev = NAN;
	req->t_req = NAN;
	req->req_body_status = REQ_BODY_INIT;

	req->hash_always_miss = 0;
	req->hash_ignore_busy = 0;

	if (sp->fd >= 0 && req->doclose != SC_NULL)
		SES_Close(sp, req->doclose);

	if (sp->fd < 0) {
		wrk->stats->sess_closed++;
		AZ(req->vcl);
		SES_ReleaseReq(req);
		SES_Delete(sp, SC_NULL, NAN);
		return (SESS_DONE_RET_GONE);
	}

	WS_Reset(req->ws, NULL);
	WS_Reset(wrk->aws, NULL);

	if (HTTP1_Reinit(req->htc) == HTTP1_COMPLETE) {
		AZ(req->vsl->wid);
		req->t_first = req->t_req = sp->t_idle;
		wrk->stats->sess_pipeline++;
		req->acct.req_hdrbytes += Tlen(req->htc->rxbuf);
		return (SESS_DONE_RET_START);
	} else {
		if (Tlen(req->htc->rxbuf))
			wrk->stats->sess_readahead++;
		return (SESS_DONE_RET_WAIT);
	}
}