void
http_CopyHome(struct worker *w, int fd, const struct http *hp)
{
	unsigned u, l;
	char *p;

	for (u = 0; u < hp->nhd; u++) {
		if (hp->hd[u].b == NULL)
			continue;
		if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e) {
			WSLH(w, fd, hp, u);
			continue;
		}
		l = Tlen(hp->hd[u]);
		p = WS_Alloc(hp->ws, l + 1);
		if (p != NULL) {
			WSLH(w, fd, hp, u);
			memcpy(p, hp->hd[u].b, l + 1L);
			hp->hd[u].b = p;
			hp->hd[u].e = p + l;
		} else {
			/* XXX This leaves a slot empty */
			VSC_C_main->losthdr++;
			WSLR(w, SLT_LostHeader, fd, hp->hd[u]);
			hp->hd[u].b = NULL;
			hp->hd[u].e = NULL;
		}
	}
}
Exemple #2
0
static void
WSLH(struct worker *w, unsigned vsl_id, const struct http *hp, unsigned hdr)
{

	AN(vsl_id & (VSL_CLIENTMARKER|VSL_BACKENDMARKER));
	WSLR(w, http2shmlog(hp, hdr), vsl_id, hp->hd[hdr]);
}
static void
wsl(struct worker *wrk, enum VSL_tag_e tag, int id, const char *fmt, va_list ap)
{
	char *p;
	unsigned n, mlen;
	txt t;

	AN(fmt);
	mlen = cache_param->shm_reclen;

	if (strchr(fmt, '%') == NULL) {
		t.b = TRUST_ME(fmt);
		t.e = strchr(t.b, '\0');
		WSLR(wrk, tag, id, t);
	} else {
		assert(wrk->wlp < wrk->wle);

		/* Wrap if we cannot fit a full size record */
		if (VSL_END(wrk->wlp, mlen) >= wrk->wle)
			WSL_Flush(wrk, 1);

		p = VSL_DATA(wrk->wlp);
		n = vsnprintf(p, mlen, fmt, ap);
		if (n > mlen)
			n = mlen;	/* we truncate long fields */
		vsl_hdr(tag, wrk->wlp, n, id);
		wrk->wlp = VSL_END(wrk->wlp, n);
		assert(wrk->wlp < wrk->wle);
		wrk->wlr++;
	}
	if (cache_param->diag_bitmap & 0x10000)
		WSL_Flush(wrk, 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 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]);
	}
}
static void
WSLH(struct worker *w, int fd, const struct http *hp, unsigned hdr)
{

	WSLR(w, http2shmlog(hp, hdr), fd, hp->hd[hdr]);
}