Example #1
0
uint16_t
http_DissectResponse(struct worker *w, const struct http_conn *htc,
    struct http *hp)
{
	int j;
	uint16_t retval = 0;
	char *p;


	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	hp->logtag = HTTP_Rx;

	if (http_splitline(w, htc->fd, hp, htc,
	    HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_RESPONSE))
		retval = 503;

	if (retval == 0 && memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7))
		retval = 503;

	if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3)
		retval = 503;

	if (retval == 0) {
		hp->status = 0;
		p = hp->hd[HTTP_HDR_STATUS].b;
		for (j = 100; j != 0; j /= 10) {
			if (!vct_isdigit(*p)) {
				retval = 503;
				break;
			}
			hp->status += (uint16_t)(j * (*p - '0'));
			p++;
		}
		if (*p != '\0')
			retval = 503;
	}

	if (retval != 0) {
		WSLR(w, SLT_HttpGarbage, htc->fd, htc->rxbuf);
		assert(retval >= 100 && retval <= 999);
		hp->status = retval;
	} else {
		http_ProtoVer(hp);
	}

	if (hp->hd[HTTP_HDR_RESPONSE].b == NULL ||
	    !Tlen(hp->hd[HTTP_HDR_RESPONSE])) {
		/* Backend didn't send a response string, use the standard */
		hp->hd[HTTP_HDR_RESPONSE].b =
		    TRUST_ME(http_StatusMessage(hp->status));
		hp->hd[HTTP_HDR_RESPONSE].e =
		    strchr(hp->hd[HTTP_HDR_RESPONSE].b, '\0');
	}
	return (retval);
}
static int
cnt_error(struct sess *sp)
{
    struct worker *w;
    struct http *h;
    char date[40];

    CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);

    w = sp->wrk;
    if (sp->obj == NULL) {
        HSH_Prealloc(sp);
        sp->obj = HSH_NewObject(sp, 1);
        sp->obj->xid = sp->xid;
        sp->obj->entered = sp->t_req;
    } else {
        /* XXX: Null the headers ? */
    }
    CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
    h = sp->obj->http;

    http_PutProtocol(w, sp->fd, h, "HTTP/1.1");
    http_PutStatus(w, sp->fd, h, sp->err_code);
    TIM_format(TIM_real(), date);
    http_PrintfHeader(w, sp->fd, h, "Date: %s", date);
    http_PrintfHeader(w, sp->fd, h, "Server: Varnish");
    http_PrintfHeader(w, sp->fd, h, "Retry-After: %d", params->err_ttl);

    if (sp->err_reason != NULL)
        http_PutResponse(w, sp->fd, h, sp->err_reason);
    else
        http_PutResponse(w, sp->fd, h,
                         http_StatusMessage(sp->err_code));
    VCL_error_method(sp);

    if (sp->handling == VCL_RET_RESTART) {
        HSH_Drop(sp);
        sp->director = NULL;
        sp->restarts++;
        sp->step = STP_RECV;
        return (0);
    }

    /* We always close when we take this path */
    sp->doclose = "error";
    sp->wantbody = 1;

    assert(sp->handling == VCL_RET_DELIVER);
    sp->err_code = 0;
    sp->err_reason = NULL;
    sp->wrk->bereq = NULL;
    sp->step = STP_DELIVER;
    return (0);
}
Example #3
0
void
VRT_error(struct sess *sp, unsigned code, const char *reason)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	WSL(sp->wrk, SLT_Debug, 0, "VCL_error(%u, %s)", code, reason ?
	    reason : "(null)");
	if (code < 100 || code > 999)
		code = 503;
	sp->err_code = (uint16_t)code;
	sp->err_reason = reason ? reason : http_StatusMessage(sp->err_code);
}
Example #4
0
void
VRT_error(const struct vrt_ctx *ctx, unsigned code, const char *reason)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
	VSLb(ctx->vsl, SLT_Debug, "VCL_error(%u, %s)", code,
	    reason ?  reason : "(null)");
	if (code < 100 || code > 999)
		code = 503;
	ctx->req->err_code = (uint16_t)code;
	ctx->req->err_reason =
	    reason ? reason : http_StatusMessage(ctx->req->err_code);
}
uint16_t
HTTP1_DissectResponse(struct http *hp, const struct http_conn *htc)
{
	uint16_t retval = 0;
	char *p;


	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);

	if (htc_splitline(hp, htc, 0))
		retval = 503;

	if (retval == 0 && memcmp(hp->hd[HTTP_HDR_PROTO].b, "HTTP/1.", 7))
		retval = 503;

	if (retval == 0 && Tlen(hp->hd[HTTP_HDR_STATUS]) != 3)
		retval = 503;

	if (retval == 0) {
		p = hp->hd[HTTP_HDR_STATUS].b;

		if (p[0] >= '1' && p[0] <= '9' &&
		    p[1] >= '0' && p[1] <= '9' &&
		    p[2] >= '0' && p[2] <= '9')
			hp->status =
			    100 * (p[0] - '0') + 10 * (p[1] - '0') + p[2] - '0';
		else
			retval = 503;
	}

	if (retval != 0) {
		VSLbt(hp->vsl, SLT_HttpGarbage, htc->rxbuf);
		assert(retval >= 100 && retval <= 999);
		hp->status = retval;
	} else
		htc_proto_ver(hp);

	if (hp->hd[HTTP_HDR_RESPONSE].b == NULL ||
	    !Tlen(hp->hd[HTTP_HDR_RESPONSE])) {
		/* Backend didn't send a response string, use the standard */
		hp->hd[HTTP_HDR_RESPONSE].b =
		    TRUST_ME(http_StatusMessage(hp->status));
		hp->hd[HTTP_HDR_RESPONSE].e =
		    strchr(hp->hd[HTTP_HDR_RESPONSE].b, '\0');
	}
	return (retval);
}
Example #6
0
static int
cnt_error(struct worker *wrk, struct req *req)
{
	struct http *h;
	struct busyobj *bo;
	char date[40];

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	AZ(req->objcore);
	AZ(req->obj);
	AZ(req->busyobj);

	bo = VBO_GetBusyObj(wrk, req);
	req->busyobj = bo;
	AZ(bo->stats);
	bo->stats = &wrk->stats;
	req->objcore = HSH_NewObjCore(wrk);
	req->obj = STV_NewObject(bo, &req->objcore,
	    TRANSIENT_STORAGE, cache_param->http_resp_size,
	    (uint16_t)cache_param->http_max_hdr);
	bo->stats = NULL;
	if (req->obj == NULL) {
		req->doclose = SC_OVERLOAD;
		req->director = NULL;
		http_Teardown(bo->beresp);
		http_Teardown(bo->bereq);
		return(1);
	}
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	req->obj->vxid = bo->vsl->wid;
	req->obj->exp.entered = req->t_req;

	h = req->obj->http;

	if (req->err_code < 100 || req->err_code > 999)
		req->err_code = 501;

	http_PutProtocol(h, "HTTP/1.1");
	http_PutStatus(h, req->err_code);
	VTIM_format(W_TIM_real(wrk), date);
	http_PrintfHeader(h, "Date: %s", date);
	http_SetHeader(h, "Server: Varnish");

	if (req->err_reason != NULL)
		http_PutResponse(h, req->err_reason);
	else
		http_PutResponse(h, http_StatusMessage(req->err_code));
	VCL_error_method(req);

	if (req->handling == VCL_RET_RESTART &&
	    req->restarts <  cache_param->max_restarts) {
		HSH_Drop(wrk, &req->obj);
		VBO_DerefBusyObj(wrk, &req->busyobj);
		req->req_step = R_STP_RESTART;
		return (0);
	} else if (req->handling == VCL_RET_RESTART)
		req->handling = VCL_RET_DELIVER;


	/* We always close when we take this path */
	req->doclose = SC_TX_ERROR;
	req->wantbody = 1;

	assert(req->handling == VCL_RET_DELIVER);
	req->err_code = 0;
	req->err_reason = NULL;
	http_Teardown(bo->bereq);
	VBO_DerefBusyObj(wrk, &req->busyobj);
	req->req_step = R_STP_PREPRESP;
	return (0);
}
Example #7
0
static enum req_fsm_nxt
cnt_error(struct worker *wrk, struct req *req)
{
	struct http *h;
	struct busyobj *bo;
	char date[40];

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	AZ(req->objcore);
	AZ(req->obj);

	req->acct_req.error++;
	bo = VBO_GetBusyObj(wrk, req);
	AZ(bo->stats);
	bo->stats = &wrk->stats;
	bo->fetch_objcore = HSH_Private(wrk);
	bo->fetch_obj = STV_NewObject(bo,
	    TRANSIENT_STORAGE, cache_param->http_resp_size,
	    (uint16_t)cache_param->http_max_hdr);
	req->obj = bo->fetch_obj;
	bo->stats = NULL;
	if (req->obj == NULL) {
		req->doclose = SC_OVERLOAD;
		req->director = NULL;
		AZ(HSH_DerefObjCore(&wrk->stats, &bo->fetch_objcore));
		bo->fetch_objcore = NULL;
		http_Teardown(bo->beresp);
		http_Teardown(bo->bereq);
		VBO_DerefBusyObj(wrk, &bo);
		return (REQ_FSM_DONE);
	}
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	AZ(req->objcore);
	req->obj->vxid = bo->vsl->wid;
	req->obj->exp.entered = req->t_req;

	h = req->obj->http;

	if (req->err_code < 100 || req->err_code > 999)
		req->err_code = 501;

	http_PutProtocol(h, "HTTP/1.1");
	http_PutStatus(h, req->err_code);
	VTIM_format(W_TIM_real(wrk), date);
	http_PrintfHeader(h, "Date: %s", date);
	http_SetHeader(h, "Server: Varnish");

	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	HSH_Ref(req->obj->objcore);

	if (req->err_reason != NULL)
		http_PutResponse(h, req->err_reason);
	else
		http_PutResponse(h, http_StatusMessage(req->err_code));
	VCL_error_method(req->vcl, wrk, req, NULL, req->http->ws);

	/* Stop the insanity before it turns "Hotel California" on us */
	if (req->restarts >= cache_param->max_restarts)
		wrk->handling = VCL_RET_DELIVER;

	if (wrk->handling == VCL_RET_RESTART) {
		VBO_DerefBusyObj(wrk, &bo);
		HSH_Drop(wrk, &req->obj);
		req->req_step = R_STP_RESTART;
		return (REQ_FSM_MORE);
	}
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);

	/* We always close when we take this path */
	req->doclose = SC_TX_ERROR;
	req->wantbody = 1;

	assert(wrk->handling == VCL_RET_DELIVER);
	req->err_code = 0;
	req->err_reason = NULL;
	http_Teardown(bo->bereq);
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	VBO_DerefBusyObj(wrk, &bo);
	req->req_step = R_STP_DELIVER;
	CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
	return (REQ_FSM_MORE);
}
Example #8
0
static int
cnt_error(struct sess *sp)
{
    struct http *h;
    char date[40];
    struct worker *wrk;

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

    if (wrk->obj == NULL) {
        HSH_Prealloc(sp);
        AZ(wrk->busyobj);
        wrk->busyobj = VBO_GetBusyObj(wrk);
        wrk->obj = STV_NewObject(wrk, NULL, cache_param->http_resp_size,
                                 (uint16_t)cache_param->http_max_hdr);
        if (wrk->obj == NULL)
            wrk->obj = STV_NewObject(wrk, TRANSIENT_STORAGE,
                                     cache_param->http_resp_size,
                                     (uint16_t)cache_param->http_max_hdr);
        if (wrk->obj == NULL) {
            sp->doclose = "Out of objects";
            sp->director = NULL;
            http_Setup(wrk->busyobj->beresp, NULL);
            http_Setup(wrk->busyobj->bereq, NULL);
            sp->step = STP_DONE;
            return(0);
        }
        AN(wrk->obj);
        wrk->obj->xid = sp->xid;
        wrk->obj->exp.entered = sp->t_req;
    } else {
        CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC);
        /* XXX: Null the headers ? */
    }
    CHECK_OBJ_NOTNULL(wrk->obj, OBJECT_MAGIC);
    h = wrk->obj->http;

    if (sp->err_code < 100 || sp->err_code > 999)
        sp->err_code = 501;

    http_PutProtocol(wrk, sp->vsl_id, h, "HTTP/1.1");
    http_PutStatus(h, sp->err_code);
    VTIM_format(W_TIM_real(wrk), date);
    http_PrintfHeader(wrk, sp->vsl_id, h, "Date: %s", date);
    http_SetHeader(wrk, sp->vsl_id, h, "Server: Varnish");

    if (sp->err_reason != NULL)
        http_PutResponse(wrk, sp->vsl_id, h, sp->err_reason);
    else
        http_PutResponse(wrk, sp->vsl_id, h,
                         http_StatusMessage(sp->err_code));
    VCL_error_method(sp);

    if (sp->handling == VCL_RET_RESTART &&
            sp->restarts <  cache_param->max_restarts) {
        HSH_Drop(wrk);
        VBO_DerefBusyObj(wrk, &wrk->busyobj);
        sp->director = NULL;
        sp->restarts++;
        sp->step = STP_RECV;
        return (0);
    } else if (sp->handling == VCL_RET_RESTART)
        sp->handling = VCL_RET_DELIVER;


    /* We always close when we take this path */
    sp->doclose = "error";
    sp->wantbody = 1;

    assert(sp->handling == VCL_RET_DELIVER);
    sp->err_code = 0;
    sp->err_reason = NULL;
    http_Setup(wrk->busyobj->bereq, NULL);
    VBO_DerefBusyObj(wrk, &wrk->busyobj);
    sp->step = STP_PREPRESP;
    return (0);
}
Example #9
0
static enum req_fsm_nxt
cnt_synth(struct worker *wrk, struct req *req)
{
	char date[40];
	struct http *h;
	double now;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);

	wrk->stats.s_synth++;

	HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
	h = req->resp;

	now = W_TIM_real(wrk);
	VSLb_ts_req(req, "Process", now);

	if (req->err_code < 100 || req->err_code > 999)
		req->err_code = 501;

	http_ClrHeader(h);
	http_PutProtocol(h, "HTTP/1.1");
	http_PutStatus(h, req->err_code);
	VTIM_format(now, date);
	http_PrintfHeader(h, "Date: %s", date);
	http_SetHeader(h, "Server: Varnish");
	http_PrintfHeader(req->resp,
	    "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK);
	if (req->err_reason != NULL)
		http_PutResponse(h, req->err_reason);
	else
		http_PutResponse(h, http_StatusMessage(req->err_code));

	AZ(req->synth_body);
	req->synth_body = VSB_new_auto();
	AN(req->synth_body);

	VCL_synth_method(req->vcl, wrk, req, NULL, req->http->ws);

	http_Unset(h, H_Content_Length);

	AZ(VSB_finish(req->synth_body));

	if (wrk->handling == VCL_RET_RESTART) {
		http_ClrHeader(h);
		VSB_delete(req->synth_body);
		req->synth_body = NULL;
		req->req_step = R_STP_RESTART;
		return (REQ_FSM_MORE);
	}
	assert(wrk->handling == VCL_RET_DELIVER);

	if (http_HdrIs(req->resp, H_Connection, "close"))
		req->doclose = SC_RESP_CLOSE;

	V1D_Deliver_Synth(req);

	VSLb_ts_req(req, "Resp", W_TIM_real(wrk));

	VSB_delete(req->synth_body);
	req->synth_body = NULL;

	req->err_code = 0;
	req->err_reason = NULL;
	return (REQ_FSM_DONE);
}