uint16_t
HTTP1_DissectResponse(struct http_conn *htc, struct http *hp,
    const struct http *req)
{
	uint16_t retval = 0;
	const char *p;
	int8_t rv;


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

	if (http1_splitline(hp, htc,
	    HTTP1_Resp, cache_param->http_resp_hdr_len))
		retval = 503;

	if (retval == 0) {
		hp->protover = http1_proto_ver(hp);
		if (hp->protover == 0)
			retval = 503;
		rv = http1_proto_ver(req);
		if (hp->protover > rv)
			hp->protover = rv;
	}

	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) {
		VSLb(hp->vsl, SLT_HttpGarbage, "%.*s",
		    (int)(htc->rxbuf_e - htc->rxbuf_b), htc->rxbuf_b);
		assert(retval >= 100 && retval <= 999);
		assert(retval == 503);
		hp->status = retval;
		http_SetH(hp, HTTP_HDR_STATUS, "503");
		http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(retval));
	}

	if (hp->hd[HTTP_HDR_REASON].b == NULL ||
	    !Tlen(hp->hd[HTTP_HDR_REASON]))
		http_SetH(hp, HTTP_HDR_REASON, http_Status2Reason(hp->status));

	htc->body_status = http1_body_status(hp, htc, 0);

	return (retval);
}
h2_minimal_response(struct req *req, uint16_t status)
{
	struct h2_req *r2;
	size_t l;
	uint8_t buf[6];

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);

	assert(status >= 100);
	assert(status < 1000);

	l = h2_status(buf, status);
	assert(l < sizeof(buf));

	VSLb(req->vsl, SLT_RespProtocol, "HTTP/2.0");
	VSLb(req->vsl, SLT_RespStatus, "%03d", status);
	VSLb(req->vsl, SLT_RespReason, "%s", http_Status2Reason(status, NULL));

	if (status >= 400)
		req->err_code = status;

	/* XXX return code checking once H2_Send returns anything but 0 */
	H2_Send_Get(req->wrk, r2->h2sess, r2);
	H2_Send(req->wrk, r2,
	    H2_F_HEADERS,
	    H2FF_HEADERS_END_HEADERS |
		(status < 200 ? 0 : H2FF_HEADERS_END_STREAM),
	    l, buf);
	H2_Send_Rel(r2->h2sess, r2);
	return (0);
}
Example #3
0
http1_minimal_response(struct req *req, uint16_t status)
{
	ssize_t wl, l;
	char buf[80];
	const char *reason;

	assert(status >= 100);
	assert(status < 1000);

	reason = http_Status2Reason(status, NULL);

	l = snprintf(buf, sizeof(buf),
	    "HTTP/1.1 %03d %s\r\n\r\n", status, reason);
	assert (l < sizeof(buf));

	VSLb(req->vsl, SLT_RespProtocol, "HTTP/1.1");
	VSLb(req->vsl, SLT_RespStatus, "%03d", status);
	VSLb(req->vsl, SLT_RespReason, "%s", reason);

	if (status >= 400)
		req->err_code = status;
	wl = write(req->sp->fd, buf, l);

	if (wl > 0)
		req->acct.resp_hdrbytes += wl;
	if (wl != l) {
		if (wl < 0)
			VTCP_Assert(1);
		if (!req->doclose)
			req->doclose = SC_REM_CLOSE;
		return (-1);
	}
	return (0);
}
Example #4
0
void
VRT_synth(VRT_CTX, unsigned code, const char *reason)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
	if (code < 100)
		code = 503;
	ctx->req->err_code = (uint16_t)code;
	ctx->req->err_reason = reason ? reason
	    : http_Status2Reason(ctx->req->err_code % 1000, NULL);
}
Example #5
0
void
http_PutResponse(struct http *to, const char *proto, uint16_t status,
    const char *reason)
{

	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
	if (proto != NULL)
		http_SetH(to, HTTP_HDR_PROTO, proto);
	http_SetStatus(to, status);
	if (reason == NULL)
		reason = http_Status2Reason(status);
	http_SetH(to, HTTP_HDR_REASON, reason);
}
Example #6
0
void
VRT_error(VRT_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_Status2Reason(ctx->req->err_code);
}
Example #7
0
void
http_SetStatus(struct http *to, uint16_t status)
{
	char buf[4];

	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
	/*
	 * We allow people to use top digits for internal VCL
	 * signalling, but strip them from the ASCII version.
	 */
	to->status = status;
	status %= 1000;
	assert(status >= 100);
	bprintf(buf, "%03d", status);
	http_PutField(to, HTTP_HDR_STATUS, buf);
	http_SetH(to, HTTP_HDR_REASON, http_Status2Reason(status));
}