Commit fc10311b authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

test backend connections at allocation time.

General bush-wacking in the fetch code.


git-svn-id: http://www.varnish-cache.org/svn/trunk@156 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 2d78b998
......@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include "libvarnish.h"
#include "shmlog.h"
......@@ -90,12 +91,42 @@ connect_to_backend(struct vbe_conn *vc, struct backend *bp)
/*--------------------------------------------------------------------*/
int
tst_fd(int fd)
{
fd_set r,w,e;
int i;
struct timeval tv;
char c;
FD_ZERO(&r);
FD_ZERO(&w);
FD_ZERO(&e);
FD_SET(fd, &r);
FD_SET(fd, &w);
FD_SET(fd, &e);
tv.tv_sec = 0;
tv.tv_usec = 0;
i = select(fd + 1, &r, &w, &e, &tv);
printf("tst_fd fd %d i %d flag %d/%d/%d\n",
fd, i, FD_ISSET(fd, &r), FD_ISSET(fd, &w), FD_ISSET(fd, &e));
if (FD_ISSET(fd, &r)) {
i = read(fd, &c, 1);
if (i == 0)
return (1);
}
return (0);
}
/*--------------------------------------------------------------------*/
int
VBE_GetFd(struct backend *bp, void **ptr)
{
struct vbe *vp;
struct vbe_conn *vc;
again:
AZ(pthread_mutex_lock(&vbemtx));
vp = bp->vbe;
if (vp == NULL) {
......@@ -118,6 +149,10 @@ VBE_GetFd(struct backend *bp, void **ptr)
TAILQ_REMOVE(&vp->fconn, vc, list);
TAILQ_INSERT_TAIL(&vp->bconn, vc, list);
AZ(pthread_mutex_unlock(&vbemtx));
if (tst_fd(vc->fd)) {
VBE_ClosedFd(vc);
goto again;
}
} else {
vc = calloc(sizeof *vc, 1);
assert(vc != NULL);
......
......@@ -23,11 +23,10 @@
#include "cache.h"
static int
fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
fetch_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *b)
{
int i;
char *e;
struct sess sp2;
unsigned char *p;
off_t cl;
struct storage *st;
......@@ -40,25 +39,27 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
sp->obj->len = cl;
p = st->ptr;
i = fcntl(sp2.fd, F_GETFL); /* XXX ? */
i = fcntl(fd, F_GETFL); /* XXX ? */
i &= ~O_NONBLOCK;
i = fcntl(sp2.fd, F_SETFL, i);
i = fcntl(fd, F_SETFL, i);
if (http_GetTail(hp, cl, &b, &e)) {
i = e - b;
VSL(SLT_Debug, 0, "Fetch_Tail %jd %d", cl, i);
memcpy(p, b, i);
p += i;
cl -= i;
}
while (cl != 0) {
i = read(sp2.fd, p, cl);
i = read(fd, p, cl);
VSL(SLT_Debug, 0, "Fetch_Read %jd %d", cl, i);
assert(i > 0);
p += i;
cl -= i;
}
http_BuildSbuf(1, w->sb, hp);
http_BuildSbuf(2, w->sb, hp);
i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
......@@ -76,20 +77,19 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
}
static int
fetch_chunked(struct worker *w, struct sess *sp, struct http *hp)
fetch_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
{
int i;
char *b, *q, *e;
struct sess sp2;
unsigned char *p;
struct storage *st;
unsigned u;
char buf[20];
char *bp, *be;
i = fcntl(sp2.fd, F_GETFL); /* XXX ? */
i = fcntl(fd, F_GETFL); /* XXX ? */
i &= ~O_NONBLOCK;
i = fcntl(sp2.fd, F_SETFL, i);
i = fcntl(fd, F_SETFL, i);
be = buf + sizeof buf;
while (1) {
......@@ -100,7 +100,7 @@ printf("Tail: (H)\n%#H\n", b, e - b);
memcpy(bp, b, e - b);
bp += e - b;
} else {
i = read(sp2.fd, bp, be - bp);
i = read(fd, bp, be - bp);
assert(i >= 0);
bp += i;
}
......@@ -131,7 +131,7 @@ printf("Tail: (B)\n%#H\n", b, e - b);
u -= e - b;
}
if (u > 0) {
i = read(sp2.fd, p, u);
i = read(fd, p, u);
if (0)
printf("u = %u i = %d\n", u, i);
assert(i == u);
......@@ -140,7 +140,7 @@ if (0)
printf("Store:\n%#H\n", st->ptr, st->len);
}
http_BuildSbuf(1, w->sb, hp);
http_BuildSbuf(2, w->sb, hp);
i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
......@@ -165,7 +165,6 @@ FetchSession(struct worker *w, struct sess *sp)
{
int fd, i, cls;
void *fd_token;
struct sess sp2;
struct http *hp;
char *b;
......@@ -174,22 +173,21 @@ FetchSession(struct worker *w, struct sess *sp)
VSL(SLT_Handling, sp->fd, "Fetch fd %d", fd);
hp = http_New();
http_BuildSbuf(0, w->sb, sp->http);
HERE();
http_BuildSbuf(1, w->sb, sp->http);
HERE();
i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
/* XXX: copy any contents */
memset(&sp2, 0, sizeof sp2);
sp2.rd_e = &w->e1;
sp2.fd = fd;
/*
* XXX: It might be cheaper to avoid the event_engine and simply
* XXX: read(2) the header
*/
http_RecvHead(hp, sp2.fd, w->eb, NULL, NULL);
http_RecvHead(hp, fd, w->eb, NULL, NULL);
event_base_loop(w->eb, 0);
http_Dissect(hp, sp2.fd, 2);
http_Dissect(hp, fd, 2);
/* XXX: fill in object from headers */
sp->obj->valid = 1;
......@@ -201,12 +199,12 @@ FetchSession(struct worker *w, struct sess *sp)
assert(sp->handling == HND_Insert);
if (http_GetHdr(hp, "Content-Length", &b)) {
cls = fetch_straight(w, sp, hp, b);
cls = fetch_straight(w, sp, fd, hp, b);
} else if (http_GetHdr(hp, "Transfer-Encoding", &b) &&
!strcasecmp(b, "chunked")) {
cls = fetch_chunked(w, sp, hp);
cls = fetch_chunked(w, sp, fd, hp);
} else {
assert(0 == 1);
VSL(SLT_Debug, fd, "No transfer");
cls = 0;
}
......
......@@ -137,6 +137,7 @@ http_Dissect(struct http *hp, int fd, int rr)
{
char *p, *q, *r;
assert(hp->t != NULL);
if (rr == 1) {
/* First, isolate and possibly identify request type */
hp->req = hp->s;
......@@ -227,6 +228,8 @@ http_Dissect(struct http *hp, int fd, int rr)
/*--------------------------------------------------------------------*/
#include <errno.h>
static void
http_read_f(int fd, short event, void *arg)
{
......@@ -235,13 +238,14 @@ http_read_f(int fd, short event, void *arg)
int i;
assert(hp->v < hp->e);
errno = 0;
i = read(fd, hp->v, hp->e - hp->v);
if (i <= 0) {
if (hp->v != hp->s)
VSL(SLT_SessionClose, fd,
"remote had %d bytes", hp->v - hp->s);
"remote had %d bytes errno %d", hp->v - hp->s, errno);
else
VSL(SLT_SessionClose, fd, "remote");
VSL(SLT_SessionClose, fd, "remote errno %d", errno);
hp->t = NULL;
event_del(&hp->ev);
if (hp->callback != NULL)
......@@ -329,25 +333,27 @@ http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp)
sbuf_clear(sb);
assert(sb != NULL);
if (resp) {
if (resp == 2) {
sbuf_cat(sb, hp->proto);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->status);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->response);
} else {
} else if (resp == 1) {
sbuf_cat(sb, hp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->url);
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->proto);
} else {
assert(resp == 1 || resp == 2);
}
sbuf_cat(sb, "\r\n");
for (u = 0; u < hp->nhdr; u++) {
if (http_supress(hp->hdr[u], resp))
continue;
if (0)
if (1)
VSL(SLT_Debug, 0, "Build %s", hp->hdr[u]);
sbuf_cat(sb, hp->hdr[u]);
sbuf_cat(sb, "\r\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment