コード例 #1
0
/*
 * Return true if the hp->hd[u] header matches *hdr and the regex *re
 * matches the content.
 *
 * If re is NULL, content is not tested and as long as it's the right
 * header, a match is returned.
 */
static int
header_http_match(VRT_CTX, const struct http *hp, unsigned u, void *re,
    const char *hdr)
{
	const char *start;
	unsigned l;

	assert(hdr);
	assert(hp);

	Tcheck(hp->hd[u]);
	if (hp->hd[u].b == NULL)
		return (0);

	l = hdr[0];

	if (!header_http_IsHdr(&hp->hd[u], hdr))
		return (0);

	if (re == NULL)
		return (1);

	start = hp->hd[u].b + l;
	while (*start != '\0' && *start == ' ')
		start++;

	if (!*start)
		return (0);
	if (VRT_re_match(ctx, start, re))
		return (1);

	return (0);
}
コード例 #2
0
void
WSLR(struct worker *wrk, enum VSL_tag_e tag, int id, txt t)
{
	unsigned l, mlen;

	Tcheck(t);
	mlen = cache_param->shm_reclen;

	/* Truncate */
	l = Tlen(t);
	if (l > mlen) {
		l = mlen;
		t.e = t.b + l;
	}

	assert(wrk->wlp < wrk->wle);

	/* Wrap if necessary */
	if (VSL_END(wrk->wlp, l) >= wrk->wle)
		WSL_Flush(wrk, 1);
	assert (VSL_END(wrk->wlp, l) < wrk->wle);
	memcpy(VSL_DATA(wrk->wlp), t.b, l);
	vsl_hdr(tag, wrk->wlp, l, id);
	wrk->wlp = VSL_END(wrk->wlp, l);
	assert(wrk->wlp < wrk->wle);
	wrk->wlr++;
	if (cache_param->diag_bitmap & 0x10000)
		WSL_Flush(wrk, 0);
}
コード例 #3
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
const char *
http_GetReq(const struct http *hp)
{

	Tcheck(hp->hd[HTTP_HDR_METHOD]);
	return (hp->hd[HTTP_HDR_METHOD].b);
}
コード例 #4
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
static void
http_filterfields(struct http *to, const struct http *fm, unsigned how)
{
	unsigned u;

	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
	to->nhd = HTTP_HDR_FIRST;
	to->status = fm->status;
	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++) {
		if (fm->hd[u].b == NULL)
			continue;
		if (fm->hdf[u] & HDF_FILTER)
			continue;
#define HTTPH(a, b, c) \
		if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
			continue;
#include "tbl/http_headers.h"
#undef HTTPH
		Tcheck(fm->hd[u]);
		if (to->nhd < to->shd) {
			to->hd[to->nhd] = fm->hd[u];
			to->hdf[to->nhd] = 0;
			to->nhd++;
		} else  {
			VSC_C_main->losthdr++;
			VSLbt(to->vsl, SLT_LostHeader, fm->hd[u]);
		}
	}
}
コード例 #5
0
static int
htc_header_complete(txt *t)
{
	const char *p;

	Tcheck(*t);
	assert(*t->e == '\0');
	/* Skip any leading white space */
	for (p = t->b ; isspace(*p); p++)
		continue;
	if (*p == '\0') {
		t->e = t->b;
		*t->e = '\0';
		return (0);
	}
	while (1) {
		p = strchr(p, '\n');
		if (p == NULL)
			return (0);
		p++;
		if (*p == '\r')
			p++;
		if (*p == '\n')
			break;
	}
	p++;
	return (p - t->b);
}
コード例 #6
0
static void
wslr(struct vsl_log *vsl, enum VSL_tag_e tag, int id, txt t)
{
	unsigned l, mlen;

	Tcheck(t);
	if (id == -1)
		id = vsl->wid;
	mlen = cache_param->shm_reclen;

	/* Truncate */
	l = Tlen(t);
	if (l > mlen) {
		l = mlen;
		t.e = t.b + l;
	}

	assert(vsl->wlp < vsl->wle);

	/* Wrap if necessary */
	if (VSL_END(vsl->wlp, l) >= vsl->wle)
		VSL_Flush(vsl, 1);
	assert(VSL_END(vsl->wlp, l) < vsl->wle);
	memcpy(VSL_DATA(vsl->wlp), t.b, l);
	vsl_hdr(tag, vsl->wlp, l, id);
	vsl->wlp = VSL_END(vsl->wlp, l);
	assert(vsl->wlp < vsl->wle);
	vsl->wlr++;
	if (cache_param->diag_bitmap & 0x10000)
		VSL_Flush(vsl, 0);
}
コード例 #7
0
static void
http_filterfields(struct http *to, const struct http *fm, unsigned how)
{
	unsigned u;

	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
	to->nhd = HTTP_HDR_FIRST;
	to->status = fm->status;
	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++) {
		if (fm->hd[u].b == NULL)
			continue;
		if (fm->hdf[u] & HDF_FILTER)
			continue;
		Tcheck(fm->hd[u]);
#define HTTPH(a, b, c) \
		if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
			continue;
#include "tbl/http_headers.h"
#undef HTTPH
		assert (to->nhd < to->shd);
		to->hd[to->nhd] = fm->hd[u];
		to->hdf[to->nhd] = 0;
		http_VSLH(to, to->nhd);
		to->nhd++;
	}
}
コード例 #8
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
void
http_CollectHdr(struct http *hp, const char *hdr)
{
	unsigned u, v, ml, f = 0, x;
	char *b = NULL, *e = NULL;

	for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
		while (u < hp->nhd && http_IsHdr(&hp->hd[u], hdr)) {
			Tcheck(hp->hd[u]);
			if (f == 0) {
				/* Found first header, just record the fact */
				f = u;
				break;
			}
			if (b == NULL) {
				/* Found second header, start our collection */
				ml = WS_Reserve(hp->ws, 0);
				b = hp->ws->f;
				e = b + ml;
				x = Tlen(hp->hd[f]);
				if (b + x < e) {
					memcpy(b, hp->hd[f].b, x);
					b += x;
				} else
					b = e;
			}

			AN(b);
			AN(e);

			/* Append the Nth header we found */
			if (b < e)
				*b++ = ',';
			x = Tlen(hp->hd[u]) - *hdr;
			if (b + x < e) {
				memcpy(b, hp->hd[u].b + *hdr, x);
				b += x;
			} else
				b = e;

			/* Shift remaining headers up one slot */
			for (v = u; v < hp->nhd - 1; v++)
				hp->hd[v] = hp->hd[v + 1];
			hp->nhd--;
		}

	}
	if (b == NULL)
		return;
	AN(e);
	if (b >= e) {
		WS_Release(hp->ws, 0);
		return;
	}
	*b = '\0';
	hp->hd[f].b = hp->ws->f;
	hp->hd[f].e = b;
	WS_ReleaseP(hp->ws, b + 1);
}
コード例 #9
0
const char *
http_GetReq(const struct http *hp)
{

	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	Tcheck(hp->hd[HTTP_HDR_METHOD]);
	return (hp->hd[HTTP_HDR_METHOD].b);
}
コード例 #10
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
void
http_PutProtocol(const struct http *to, const char *protocol)
{

	http_PutField(to, HTTP_HDR_PROTO, protocol);
	if (to->hd[HTTP_HDR_PROTO].b == NULL)
		http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1");
	Tcheck(to->hd[HTTP_HDR_PROTO]);
}
コード例 #11
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
void
http_PutResponse(const struct http *to, const char *response)
{

	http_PutField(to, HTTP_HDR_RESPONSE, response);
	if (to->hd[HTTP_HDR_RESPONSE].b == NULL)
		http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response");
	Tcheck(to->hd[HTTP_HDR_RESPONSE]);
}
コード例 #12
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
static void
http_linkh(const struct http *to, const struct http *fm, unsigned n)
{

	assert(n < HTTP_HDR_FIRST);
	Tcheck(fm->hd[n]);
	to->hd[n] = fm->hd[n];
	to->hdf[n] = fm->hdf[n];
}
コード例 #13
0
ファイル: cache_http.c プロジェクト: tzuryby/Varnish-Cache
void
http_PutProtocol(struct worker *w, unsigned vsl_id, const struct http *to,
    const char *protocol)
{

	http_PutField(w, vsl_id, to, HTTP_HDR_PROTO, protocol);
	if (to->hd[HTTP_HDR_PROTO].b == NULL)
		http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1");
	Tcheck(to->hd[HTTP_HDR_PROTO]);
}
コード例 #14
0
ファイル: cache_http.c プロジェクト: tzuryby/Varnish-Cache
void
http_PutResponse(struct worker *w, unsigned vsl_id, const struct http *to,
    const char *response)
{

	http_PutField(w, vsl_id, to, HTTP_HDR_RESPONSE, response);
	if (to->hd[HTTP_HDR_RESPONSE].b == NULL)
		http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response");
	Tcheck(to->hd[HTTP_HDR_RESPONSE]);
}
コード例 #15
0
/*
 * Returns true if the *hdr header is the one pointed to by *hh.
 *
 * FIXME: duplication from varnishd.
 */
static int
header_http_IsHdr(const txt *hh, const char *hdr)
{
	unsigned l;

	Tcheck(*hh);
	AN(hdr);
	l = hdr[0];
	assert(l == strlen(hdr + 1));
	assert(hdr[l] == ':');
	hdr++;
	return (!strncasecmp(hdr, hh->b, l));
}
コード例 #16
0
ファイル: cache_http.c プロジェクト: Matt8109/Varnish-Cache
static unsigned
http_findhdr(const struct http *hp, unsigned l, const char *hdr)
{
	unsigned u;

	for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) {
		Tcheck(hp->hd[u]);
		if (hp->hd[u].e < hp->hd[u].b + l + 1)
			continue;
		if (hp->hd[u].b[l] != ':')
			continue;
		if (strncasecmp(hdr, hp->hd[u].b, l))
			continue;
		return (u);
	}
	return (0);
}
コード例 #17
0
ファイル: cache_http.c プロジェクト: BabyOnlineSG/pkg-varnish
static void
http_copyheader(struct worker *w, int fd, struct http *to,
    const struct http *fm, unsigned n)
{

	CHECK_OBJ_NOTNULL(fm, HTTP_MAGIC);
	CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
	assert(n < fm->shd);
	Tcheck(fm->hd[n]);
	if (to->nhd < to->shd) {
		to->hd[to->nhd] = fm->hd[n];
		to->hdf[to->nhd] = 0;
		to->nhd++;
	} else  {
		VSC_C_main->losthdr++;
		WSLR(w, SLT_LostHeader, fd, fm->hd[n]);
	}
}
コード例 #18
0
enum htc_status_e
HTTP1_Complete(struct http_conn *htc)
{
	char *p;
	txt *t;

	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
	AZ(htc->pipeline.b);
	AZ(htc->pipeline.e);

	t = &htc->rxbuf;
	Tcheck(*t);
	assert(*t->e == '\0');

	/* Skip any leading white space */
	for (p = t->b ; vct_islws(*p); p++)
		continue;
	if (p == t->e) {
		/* All white space */
		t->e = t->b;
		*t->e = '\0';
		return (HTTP1_ALL_WHITESPACE);
	}
	while (1) {
		p = strchr(p, '\n');
		if (p == NULL)
			return (HTTP1_NEED_MORE);
		p++;
		if (*p == '\r')
			p++;
		if (*p == '\n')
			break;
	}
	p++;
	WS_ReleaseP(htc->ws, t->e);
	if (p < t->e) {
		htc->pipeline.b = p;
		htc->pipeline.e = t->e;
		t->e = p;
	}
	return (HTTP1_COMPLETE);
}
コード例 #19
0
const char *
VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
    const char *sub)
{
	int ovector[30];
	vre_t *t;
	int i, l;
	txt res;
	char *b0;
	const char *s;
	unsigned u, x;

	AN(re);
	if (str == NULL)
		str = "";
	t = re;
	memset(ovector, 0, sizeof(ovector));
	i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
	    &params->vre_limits);

	/* If it didn't match, we can return the original string */
	if (i == VRE_ERROR_NOMATCH)
		return(str);
	if (i < VRE_ERROR_NOMATCH ) {
		WSP(sp, SLT_VCL_Error, "Regexp matching returned %d", i);
		return(str);
	}

	u = WS_Reserve(sp->http->ws, 0);
	res.e = res.b = b0 = sp->http->ws->f;
	res.e += u;

	do {
		/* Copy prefix to match */
		Tadd(&res, str, ovector[0]);
		for (s = sub ; *s != '\0'; s++ ) {
			if (*s != '\\' || s[1] == '\0') {
				if (res.b < res.e)
					*res.b++ = *s;
				continue;
			}
			s++;
			if (isdigit(*s)) {
				x = *s - '0';
				l = ovector[2*x+1] - ovector[2*x];
				Tadd(&res, str + ovector[2*x], l);
				continue;
			} else {
				if (res.b < res.e)
					*res.b++ = *s;
			}
		}
		str += ovector[1];
		if (!all)
			break;
		memset(&ovector, 0, sizeof(ovector));
		i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
		    &params->vre_limits);
		if (i < VRE_ERROR_NOMATCH ) {
			WSP(sp, SLT_VCL_Error,
			    "Regexp matching returned %d", i);
			return(str);
		}
	} while (i != VRE_ERROR_NOMATCH);

	/* Copy suffix to match */
	l = strlen(str) + 1;
	Tadd(&res, str, l);
	if (res.b >= res.e) {
		WS_Release(sp->http->ws, 0);
		return (str);
	}
	Tcheck(res);
	WS_ReleaseP(sp->http->ws, res.b);
	return (b0);
}
コード例 #20
0
static uint16_t
htc_splitline(struct http *hp, const struct http_conn *htc, int req)
{
	char *p;
	int h1, h2, h3;

	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	Tcheck(htc->rxbuf);

	if (req) {
		h1 = HTTP_HDR_METHOD;
		h2 = HTTP_HDR_URL;
		h3 = HTTP_HDR_PROTO;
	} else {
		h1 = HTTP_HDR_PROTO;
		h2 = HTTP_HDR_STATUS;
		h3 = HTTP_HDR_RESPONSE;
	}

	/* Skip leading LWS */
	for (p = htc->rxbuf.b ; vct_islws(*p); p++)
		continue;
	hp->hd[h1].b = p;

	/* First field cannot contain SP or CTL */
	for (; !vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h1].e = p;
	assert(Tlen(hp->hd[h1]));

	/* Skip SP */
	for (; vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h2].b = p;

	/* Second field cannot contain LWS or CTL */
	for (; !vct_islws(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h2].e = p;

	if (!Tlen(hp->hd[h2]))
		return (400);

	/* Skip SP */
	for (; vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h3].b = p;

	/* Third field is optional and cannot contain CTL except TAB */
	for (; !vct_iscrlf(p); p++) {
		if (vct_isctl(*p) && !vct_issp(*p)) {
			hp->hd[h3].b = NULL;
			return (400);
		}
	}
	hp->hd[h3].e = p;

	/* Skip CRLF */
	p += vct_skipcrlf(p);

	*hp->hd[h1].e = '\0';
	*hp->hd[h2].e = '\0';

	if (hp->hd[h3].e != NULL)
		*hp->hd[h3].e = '\0';

	return (htc_dissect_hdrs(hp, p, htc));
}
コード例 #21
0
const char *
VRT_regsub(struct req *req, int all, const char *str, void *re,
    const char *sub)
{
	int ovector[30];
	vre_t *t;
	int i, l;
	txt res;
	char *b0;
	const char *s;
	unsigned u, x;
	int options = 0;
	size_t len;

	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	AN(re);
	if (str == NULL)
		str = "";
	if (sub == NULL)
		sub = "";
	t = re;
	memset(ovector, 0, sizeof(ovector));
	len = strlen(str);
	i = VRE_exec(t, str, len, 0, options, ovector, 30,
	    &cache_param->vre_limits);

	/* If it didn't match, we can return the original string */
	if (i == VRE_ERROR_NOMATCH)
		return(str);
	if (i < VRE_ERROR_NOMATCH ) {
		VSLb(req->vsl, SLT_VCL_Error, "Regexp matching returned %d", i);
		return(str);
	}

	u = WS_Reserve(req->http->ws, 0);
	res.e = res.b = b0 = req->http->ws->f;
	res.e += u;

	do {
		/* Copy prefix to match */
		Tadd(&res, str, ovector[0]);
		for (s = sub ; *s != '\0'; s++ ) {
			if (*s != '\\' || s[1] == '\0') {
				if (res.b < res.e)
					*res.b++ = *s;
				continue;
			}
			s++;
			if (isdigit(*s)) {
				x = *s - '0';
				l = ovector[2*x+1] - ovector[2*x];
				Tadd(&res, str + ovector[2*x], l);
				continue;
			} else {
				if (res.b < res.e)
					*res.b++ = *s;
			}
		}
		str += ovector[1];
		len -= ovector[1];
		if (!all)
			break;
		memset(&ovector, 0, sizeof(ovector));
		options |= VRE_NOTEMPTY;
		i = VRE_exec(t, str, len, 0, options, ovector, 30,
		    &cache_param->vre_limits);
		if (i < VRE_ERROR_NOMATCH ) {
			WS_Release(req->http->ws, 0);
			VSLb(req->vsl, SLT_VCL_Error,
			    "Regexp matching returned %d", i);
			return(str);
		}
	} while (i != VRE_ERROR_NOMATCH);

	/* Copy suffix to match */
	Tadd(&res, str, len+1);
	if (res.b >= res.e) {
		WS_Release(req->http->ws, 0);
		return (str);
	}
	Tcheck(res);
	WS_ReleaseP(req->http->ws, res.b);
	return (b0);
}
コード例 #22
0
void
http_CollectHdr(struct http *hp, const char *hdr)
{
	unsigned u, l, ml, f, x, d;
	char *b = NULL, *e = NULL;

	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	if (WS_Overflowed(hp->ws))
		return;
	l = hdr[0];
	assert(l == strlen(hdr + 1));
	assert(hdr[l] == ':');
	f = http_findhdr(hp, l - 1, hdr + 1);
	if (f == 0)
		return;

	for (d = u = f + 1; u < hp->nhd; u++) {
		Tcheck(hp->hd[u]);
		if (!http_IsHdr(&hp->hd[u], hdr)) {
			if (d != u) {
				hp->hd[d] = hp->hd[u];
				hp->hdf[d] = hp->hdf[u];
			}
			d++;
			continue;
		}
		if (b == NULL) {
			/* Found second header, start our collection */
			ml = WS_Reserve(hp->ws, 0);
			b = hp->ws->f;
			e = b + ml;
			x = Tlen(hp->hd[f]);
			if (b + x >= e) {
				http_fail(hp);
				VSLb(hp->vsl, SLT_LostHeader, "%s", hdr + 1);
				WS_Release(hp->ws, 0);
				return;
			}
			memcpy(b, hp->hd[f].b, x);
			b += x;
		}

		AN(b);
		AN(e);

		/* Append the Nth header we found */
		if (b < e)
			*b++ = ',';
		x = Tlen(hp->hd[u]) - l;
		if (b + x >= e) {
			http_fail(hp);
			VSLb(hp->vsl, SLT_LostHeader, "%s", hdr + 1);
			WS_Release(hp->ws, 0);
			return;
		}
		memcpy(b, hp->hd[u].b + *hdr, x);
		b += x;
	}
	if (b == NULL)
		return;
	hp->nhd = (uint16_t)d;
	AN(e);
	*b = '\0';
	hp->hd[f].b = hp->ws->f;
	hp->hd[f].e = b;
	WS_ReleaseP(hp->ws, b + 1);
}
コード例 #23
0
ファイル: cache_http.c プロジェクト: BabyOnlineSG/pkg-varnish
static uint16_t
http_splitline(struct worker *w, int fd, struct http *hp,
    const struct http_conn *htc, int h1, int h2, int h3)
{
	char *p, *q;

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

	/* XXX: Assert a NUL at rx.e ? */
	Tcheck(htc->rxbuf);

	/* Skip leading LWS */
	for (p = htc->rxbuf.b ; vct_islws(*p); p++)
		continue;

	/* First field cannot contain SP, CRLF or CTL */
	q = p;
	for (; !vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h1].b = q;
	hp->hd[h1].e = p;

	/* Skip SP */
	for (; vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}

	/* Second field cannot contain LWS or CTL */
	q = p;
	for (; !vct_islws(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}
	hp->hd[h2].b = q;
	hp->hd[h2].e = p;

	if (!Tlen(hp->hd[h2]))
		return (413);

	/* Skip SP */
	for (; vct_issp(*p); p++) {
		if (vct_isctl(*p))
			return (400);
	}

	/* Third field is optional and cannot contain CTL */
	q = p;
	if (!vct_iscrlf(*p)) {
		for (; !vct_iscrlf(*p); p++)
			if (!vct_issep(*p) && vct_isctl(*p))
				return (400);
	}
	hp->hd[h3].b = q;
	hp->hd[h3].e = p;

	/* Skip CRLF */
	p += vct_skipcrlf(p);

	*hp->hd[h1].e = '\0';
	WSLH(w, fd, hp, h1);

	*hp->hd[h2].e = '\0';
	WSLH(w, fd, hp, h2);

	if (hp->hd[h3].e != NULL) {
		*hp->hd[h3].e = '\0';
		WSLH(w, fd, hp, h3);
	}

	return (http_dissect_hdrs(w, hp, fd, p, htc));
}