void
http_Merge(const struct http *fm, struct http *to, int not_ce)
{
	unsigned u, v;
	const char *p;

	to->status = fm->status;
	http_linkh(to, fm, HTTP_HDR_PROTO);
	http_linkh(to, fm, HTTP_HDR_STATUS);
	http_linkh(to, fm, HTTP_HDR_REASON);

	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++)
		fm->hdf[u] |= HDF_MARKER;
	if (not_ce) {
		u = http_findhdr(fm,
		    H_Content_Encoding[0] - 1, H_Content_Encoding + 1);
		if (u > 0)
			fm->hdf[u] &= ~HDF_MARKER;
	}
	for (v = HTTP_HDR_FIRST; v < to->nhd; v++) {
		p = strchr(to->hd[v].b, ':');
		AN(p);
		u = http_findhdr(fm, p - to->hd[v].b, to->hd[v].b);
		if (u)
			fm->hdf[u] &= ~HDF_MARKER;
	}
	for (u = HTTP_HDR_FIRST; u < fm->nhd; u++)
		if (fm->hdf[u] & HDF_MARKER)
			http_SetHeader(to, fm->hd[u].b);
}
Exemple #2
0
enum sess_close
http_DoConnection(const struct http *hp)
{
	char *p, *q;
	enum sess_close ret;
	unsigned u;

	if (!http_GetHdr(hp, H_Connection, &p)) {
		if (hp->protover < 11)
			return (SC_REQ_HTTP10);
		return (SC_NULL);
	}
	ret = SC_NULL;
	AN(p);
	for (; *p; p++) {
		if (vct_issp(*p))
			continue;
		if (*p == ',')
			continue;
		for (q = p + 1; *q; q++)
			if (*q == ',' || vct_issp(*q))
				break;
		u = pdiff(p, q);
		if (u == 5 && !strncasecmp(p, "close", u))
			ret = SC_REQ_CLOSE;
		u = http_findhdr(hp, u, p);
		if (u != 0)
			hp->hdf[u] |= HDF_FILTER;
		if (!*q)
			break;
		p = q;
	}
	return (ret);
}
Exemple #3
0
int
http_GetHdr(const struct http *hp, const char *hdr, char **ptr)
{
	unsigned u, l;
	char *p;

	l = hdr[0];
	assert(l == strlen(hdr + 1));
	assert(hdr[l] == ':');
	hdr++;
	u = http_findhdr(hp, l - 1, hdr);
	if (u == 0) {
		if (ptr != NULL)
			*ptr = NULL;
		return (0);
	}
	if (ptr != NULL) {
		p = hp->hd[u].b + l;
		while (vct_issp(*p))
			p++;
		*ptr = p;
	}
	return (1);
}
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);
}