static enum VCLI_status_e
varnish_ask_cli(const struct varnish *v, const char *cmd, char **repl)
{
	int i;
	unsigned retval;
	char *r;

	if (cmd != NULL) {
		vtc_dump(v->vl, 4, "CLI TX", cmd, -1);
		i = write(v->cli_fd, cmd, strlen(cmd));
		assert(i == strlen(cmd));
		i = write(v->cli_fd, "\n", 1);
		assert(i == 1);
	}
	i = VCLI_ReadResult(v->cli_fd, &retval, &r, 20.0);
	if (i != 0) {
		vtc_log(v->vl, 0, "CLI failed (%s) = %d %u %s",
		    cmd, i, retval, r);
		return ((enum VCLI_status_e)retval);
	}
	assert(i == 0);
	vtc_log(v->vl, 3, "CLI RX  %u", retval);
	vtc_dump(v->vl, 4, "CLI RX", r, -1);
	if (repl != NULL)
		*repl = r;
	else
		free(r);
	return ((enum VCLI_status_e)retval);
}
Ejemplo n.º 2
0
static void
http_swallow_body(struct http *hp, char * const *hh, int body)
{
	char *p, *q;
	int i, l, ll;


	ll = 0;
	p = http_find_header(hh, "content-length");
	if (p != NULL) {
		l = strtoul(p, NULL, 0);
		hp->body = hp->rxbuf + hp->prxbuf;
		http_rxchar(hp, l);
		vtc_dump(hp->vl, 4, "body", hp->body);
		sprintf(hp->bodylen, "%d", l);
		return;
	}
	p = http_find_header(hh, "transfer-encoding");
	if (p != NULL && !strcmp(p, "chunked")) {
		hp->body = hp->rxbuf + hp->prxbuf;
		while (1) {
			l = hp->prxbuf;
			do
				http_rxchar(hp, 1);
			while (hp->rxbuf[hp->prxbuf - 1] != '\n');
			vtc_dump(hp->vl, 4, "len", hp->rxbuf + l);
			i = strtoul(hp->rxbuf + l, &q, 16);
			assert(q != hp->rxbuf + l);
			assert(*q == '\0' || vct_islws(*q));
			hp->prxbuf = l;
			if (i > 0) {
				ll += i;
				http_rxchar(hp, i);
				vtc_dump(hp->vl, 4, "chunk", hp->rxbuf + l);
			}
			l = hp->prxbuf;
			http_rxchar(hp, 2);
			assert(vct_iscrlf(hp->rxbuf[l]));
			assert(vct_iscrlf(hp->rxbuf[l + 1]));
			hp->prxbuf = l;
			hp->rxbuf[l] = '\0';
			if (i == 0)
				break;
		}
		vtc_dump(hp->vl, 4, "body", hp->body);
		sprintf(hp->bodylen, "%d", ll);
		return;
	}
	if (body) {
		hp->body = hp->rxbuf + hp->prxbuf;
		do  {
			i = http_rxchar_eof(hp, 1);
			ll += i;
		} while (i > 0);
		vtc_dump(hp->vl, 4, "rxeof", hp->body);
	}
	sprintf(hp->bodylen, "%d", ll);
}
static void *
varnish_thread(void *priv)
{
	struct varnish *v;
	char buf[BUFSIZ];
	struct pollfd *fds, fd;
	int i;

	CAST_OBJ_NOTNULL(v, priv, VARNISH_MAGIC);
	(void)VTCP_nonblocking(v->fds[0]);
	while (1) {
		fds = &fd;
		memset(fds, 0, sizeof *fds);
		fds->fd = v->fds[0];
		fds->events = POLLIN;
		i = poll(fds, 1, 1000);
		if (i == 0)
			continue;
		if (fds->revents & (POLLERR|POLLHUP))
			break;
		i = read(v->fds[0], buf, sizeof buf - 1);
		if (i <= 0)
			break;
		buf[i] = '\0';
		vtc_dump(v->vl, 3, "debug", buf, -2);
	}
	return (NULL);
}
Ejemplo n.º 4
0
static void
http_rxhdr(struct http *hp)
{
	int i;
	char *p;

	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	hp->prxbuf = 0;
	hp->body = NULL;
	while (1) {
		(void)http_rxchar(hp, 1, 0);
		p = hp->rxbuf + hp->prxbuf - 1;
		for (i = 0; p > hp->rxbuf; p--) {
			if (*p != '\n')
				break;
			if (p - 1 > hp->rxbuf && p[-1] == '\r')
				p--;
			if (++i == 2)
				break;
		}
		if (i == 2)
			break;
	}
	vtc_dump(hp->vl, 4, "rxhdr", hp->rxbuf, -1);
}
Ejemplo n.º 5
0
void *
vtc_record(struct vtclog *vl, int fd, struct vsb *vsb)
{
	char buf[65536];
	struct pollfd fds[1];
	int i;

	(void)VTCP_nonblocking(fd);
	while (1) {
		memset(fds, 0, sizeof fds);
		fds->fd = fd;
		fds->events = POLLIN;
		i = poll(fds, 1, 10000);
		if (i == 0)
			continue;
		if (fds->revents & POLLIN) {
			i = read(fd, buf, sizeof buf - 1);
			if (i > 0) {
				if (vsb != NULL)
					VSB_bcat(vsb, buf, i);
				buf[i] = '\0';
				vtc_dump(vl, 3, "debug", buf, -2);
			}
		}
		if (fds->revents & (POLLERR|POLLHUP)) {
			vtc_log(vl, 4, "STDOUT poll 0x%x", fds->revents);
			break;
		}
	}
	return (NULL);
}
Ejemplo n.º 6
0
static void
cmd_err_shell(CMD_ARGS)
{
	(void)priv;
	(void)cmd;
	struct vsb *vsb;
	FILE *fp;
	int r, c;

	if (av == NULL)
		return;
	AN(av[1]);
	AN(av[2]);
	AZ(av[3]);
	vsb = VSB_new_auto();
	AN(vsb);
	vtc_dump(vl, 4, "cmd", av[2], -1);
	fp = popen(av[2], "r");
	if (fp == NULL)
		vtc_log(vl, 0, "popen fails: %s", strerror(errno));
	do {
		c = getc(fp);
		if (c != EOF)
			VSB_putc(vsb, c);
	} while (c != EOF);
	r = pclose(fp);
	vtc_log(vl, 4, "Status = %d", WEXITSTATUS(r));
	if (WIFSIGNALED(r))
		vtc_log(vl, 4, "Signal = %d", WTERMSIG(r));
	if (WEXITSTATUS(r) == 0) {
		vtc_log(vl, 0,
		    "expected error from shell");
	}
	AZ(VSB_finish(vsb));
	vtc_dump(vl, 4, "stdout", VSB_data(vsb), VSB_len(vsb));
	if (strstr(VSB_data(vsb), av[1]) == NULL)
		vtc_log(vl, 0,
		    "Did not find expected string: (\"%s\")", av[1]);
	else
		vtc_log(vl, 4,
		    "Found expected string: (\"%s\")", av[1]);
	VSB_delete(vsb);
}
Ejemplo n.º 7
0
static void
cmd_http_gunzip_body(CMD_ARGS)
{
	int i;
	z_stream vz;
	struct http *hp;
	char *p;
	unsigned l;

	(void)av;
	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);

	memset(&vz, 0, sizeof vz);

	AN(hp->body);
	if (hp->body[0] != (char)0x1f || hp->body[1] != (char)0x8b)
		vtc_log(hp->vl, hp->fatal,
		    "Gunzip error: Body lacks gzip magics");
	vz.next_in = TRUST_ME(hp->body);
	vz.avail_in = hp->bodyl;

	l = hp->bodyl * 10;
	p = calloc(l, 1);
	AN(p);

	vz.next_out = TRUST_ME(p);
	vz.avail_out = l;

	assert(Z_OK == inflateInit2(&vz, 31));
	i = inflate(&vz, Z_FINISH);
	assert(vz.total_out < l);
	hp->bodyl = vz.total_out;
	memcpy(hp->body, p, hp->bodyl);
	free(p);
	vtc_log(hp->vl, 3, "new bodylen %u", hp->bodyl);
	vtc_dump(hp->vl, 4, "body", hp->body, hp->bodyl);
	bprintf(hp->bodylen, "%u", hp->bodyl);
	vtc_log(hp->vl, 4, "startbit = %ju %ju/%ju",
	    (uintmax_t)vz.start_bit,
	    (uintmax_t)vz.start_bit >> 3, (uintmax_t)vz.start_bit & 7);
	vtc_log(hp->vl, 4, "lastbit = %ju %ju/%ju",
	    (uintmax_t)vz.last_bit,
	    (uintmax_t)vz.last_bit >> 3, (uintmax_t)vz.last_bit & 7);
	vtc_log(hp->vl, 4, "stopbit = %ju %ju/%ju",
	    (uintmax_t)vz.stop_bit,
	    (uintmax_t)vz.stop_bit >> 3, (uintmax_t)vz.stop_bit & 7);
	if (i != Z_STREAM_END)
		vtc_log(hp->vl, hp->fatal,
		    "Gunzip error = %d (%s) in:%jd out:%jd",
		    i, vz.msg, (intmax_t)vz.total_in, (intmax_t)vz.total_out);
	assert(Z_OK == inflateEnd(&vz));
	hp->body[hp->bodyl] = '\0';
}
Ejemplo n.º 8
0
static void
http_write(const struct http *hp, int lvl, const char *pfx)
{
	int l;

	AZ(VSB_finish(hp->vsb));
	vtc_dump(hp->vl, lvl, pfx, VSB_data(hp->vsb), VSB_len(hp->vsb));
	l = write(hp->fd, VSB_data(hp->vsb), VSB_len(hp->vsb));
	if (l != VSB_len(hp->vsb))
		vtc_log(hp->vl, hp->fatal, "Write failed: (%d vs %d) %s",
		    l, VSB_len(hp->vsb), strerror(errno));
}
Ejemplo n.º 9
0
static void
http_write(const struct http *hp, int lvl, const char *pfx)
{
	int l;

	vsb_finish(hp->vsb);
	AZ(vsb_overflowed(hp->vsb));
	vtc_dump(hp->vl, lvl, pfx, vsb_data(hp->vsb));
	l = write(hp->fd, vsb_data(hp->vsb), vsb_len(hp->vsb));
	if (l != vsb_len(hp->vsb))
		vtc_log(hp->vl, 0, "Write failed: %s", strerror(errno));
}
Ejemplo n.º 10
0
static int
http_rxchunk(struct http *hp)
{
	char *q;
	int l, i;

	l = hp->prxbuf;
	do
		(void)http_rxchar(hp, 1, 0);
	while (hp->rxbuf[hp->prxbuf - 1] != '\n');
	vtc_dump(hp->vl, 4, "len", hp->rxbuf + l, -1);
	i = strtoul(hp->rxbuf + l, &q, 16);
	bprintf(hp->chunklen, "%d", i);
	if ((q == hp->rxbuf + l) ||
		(*q != '\0' && !vct_islws(*q))) {
		vtc_log(hp->vl, hp->fatal, "chunked fail %02x @ %d",
		    *q, q - (hp->rxbuf + l));
	}
	assert(q != hp->rxbuf + l);
	assert(*q == '\0' || vct_islws(*q));
	hp->prxbuf = l;
	if (i > 0) {
		(void)http_rxchar(hp, i, 0);
		vtc_dump(hp->vl, 4, "chunk",
		    hp->rxbuf + l, i);
	}
	l = hp->prxbuf;
	(void)http_rxchar(hp, 2, 0);
	if(!vct_iscrlf(hp->rxbuf[l]))
		vtc_log(hp->vl, hp->fatal,
		    "Wrong chunk tail[0] = %02x",
		    hp->rxbuf[l] & 0xff);
	if(!vct_iscrlf(hp->rxbuf[l + 1]))
		vtc_log(hp->vl, hp->fatal,
		    "Wrong chunk tail[1] = %02x",
		    hp->rxbuf[l + 1] & 0xff);
	hp->prxbuf = l;
	hp->rxbuf[l] = '\0';
	return (i);
}
Ejemplo n.º 11
0
static void
http_swallow_body(struct http *hp, char * const *hh, int body)
{
    char *p;
    int i, l, ll;

    ll = 0;
    p = http_find_header(hh, "content-length");
    if (p != NULL) {
        hp->body = hp->rxbuf + hp->prxbuf;
        l = strtoul(p, NULL, 0);
        (void)http_rxchar(hp, l, 0);
        vtc_dump(hp->vl, 4, "body", hp->body, l);
        hp->bodyl = l;
        sprintf(hp->bodylen, "%d", l);
        return;
    }
    p = http_find_header(hh, "transfer-encoding");
    if (p != NULL && !strcmp(p, "chunked")) {
        while (http_rxchunk(hp) != 0)
            continue;
        vtc_dump(hp->vl, 4, "body", hp->body, ll);
        ll = hp->rxbuf + hp->prxbuf - hp->body;
        hp->bodyl = ll;
        sprintf(hp->bodylen, "%d", ll);
        return;
    }
    if (body) {
        hp->body = hp->rxbuf + hp->prxbuf;
        do  {
            i = http_rxchar(hp, 1, 1);
            ll += i;
        } while (i > 0);
        vtc_dump(hp->vl, 4, "rxeof", hp->body, ll);
    }
    hp->bodyl = ll;
    sprintf(hp->bodylen, "%d", ll);
}
Ejemplo n.º 12
0
static void
cmd_shell(CMD_ARGS)
{
	(void)priv;
	(void)cmd;
	int r;

	if (av == NULL)
		return;
	AN(av[1]);
	AZ(av[2]);
	vtc_dump(vl, 4, "shell", av[1], -1);
	r = system(av[1]);
	AZ(WEXITSTATUS(r));
}
Ejemplo n.º 13
0
static void
cmd_http_send(CMD_ARGS)
{
	struct http *hp;
	int i;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AN(av[1]);
	AZ(av[2]);
	vtc_dump(hp->vl, 4, "send", av[1]);
	i = write(hp->fd, av[1], strlen(av[1]));
	assert(i == strlen(av[1]));

}
Ejemplo n.º 14
0
static void
cmd_http_send(CMD_ARGS)
{
	struct http *hp;
	int i;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AN(av[1]);
	AZ(av[2]);
	vtc_dump(hp->vl, 4, "send", av[1], -1);
	i = write(hp->fd, av[1], strlen(av[1]));
	if (i != strlen(av[1]))
		vtc_log(hp->vl, hp->fatal, "Write error in http_send(): %s",
		    strerror(errno));
}
Ejemplo n.º 15
0
static void
cmd_http_recv(CMD_ARGS)
{
	struct http *hp;
	int i, n;
	char u[32];

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AN(av[1]);
	AZ(av[2]);
	n = strtoul(av[1], NULL, 0);
	while (n > 0) {
		i = read(hp->fd, u, n > 32 ? 32 : n);
		if (i > 0)
			vtc_dump(hp->vl, 4, "recv", u, i);
		else
			vtc_log(hp->vl, hp->fatal, "recv() got %d (%s)", i,
			    strerror(errno));
		n -= i;
	}
}
Ejemplo n.º 16
0
static void
cmd_http_send_n(CMD_ARGS)
{
	struct http *hp;
	int i, n, l;

	(void)cmd;
	(void)vl;
	CAST_OBJ_NOTNULL(hp, priv, HTTP_MAGIC);
	AN(av[1]);
	AN(av[2]);
	AZ(av[3]);
	n = strtoul(av[1], NULL, 0);
		vtc_dump(hp->vl, 4, "send_n", av[2], -1);
	l = strlen(av[2]);
	while (n--) {
		i = write(hp->fd, av[2], l);
		if (i != l)
			vtc_log(hp->vl, hp->fatal,
			    "Write error in http_send(): %s",
			    strerror(errno));
	}
}
Ejemplo n.º 17
0
static void
http_splitheader(struct http *hp, int req)
{
	char *p, *q, **hh;
	int n;
	char buf[20];

	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
	if (req) {
		memset(hp->req, 0, sizeof hp->req);
		hh = hp->req;
	} else {
		memset(hp->resp, 0, sizeof hp->resp);
		hh = hp->resp;
	}

	n = 0;
	p = hp->rxbuf;

	/* REQ/PROTO */
	while (vct_islws(*p))
		p++;
	hh[n++] = p;
	while (!vct_islws(*p))
		p++;
	assert(!vct_iscrlf(*p));
	*p++ = '\0';

	/* URL/STATUS */
	while (vct_issp(*p))		/* XXX: H space only */
		p++;
	assert(!vct_iscrlf(*p));
	hh[n++] = p;
	while (!vct_islws(*p))
		p++;
	if (vct_iscrlf(*p)) {
		hh[n++] = NULL;
		q = p;
		p += vct_skipcrlf(p);
		*q = '\0';
	} else {
		*p++ = '\0';
		/* PROTO/MSG */
		while (vct_issp(*p))		/* XXX: H space only */
			p++;
		hh[n++] = p;
		while (!vct_iscrlf(*p))
			p++;
		q = p;
		p += vct_skipcrlf(p);
		*q = '\0';
	}
	assert(n == 3);

	while (*p != '\0') {
		assert(n < MAX_HDR);
		if (vct_iscrlf(*p))
			break;
		hh[n++] = p++;
		while (*p != '\0' && !vct_iscrlf(*p))
			p++;
		q = p;
		p += vct_skipcrlf(p);
		*q = '\0';
	}
	p += vct_skipcrlf(p);
	assert(*p == '\0');

	for (n = 0; n < 3 || hh[n] != NULL; n++) {
		sprintf(buf, "http[%2d] ", n);
		vtc_dump(hp->vl, 4, buf, hh[n], -1);
	}
}