#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/select.h>
#include "libvarnish.h"
#include "shmlog.h"
/*--------------------------------------------------------------------*/
+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) {
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);
#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;
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));
}
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) {
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;
}
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);
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));
{
int fd, i, cls;
void *fd_token;
- struct sess sp2;
struct http *hp;
char *b;
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;
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;
}
{
char *p, *q, *r;
+ assert(hp->t != NULL);
if (rr == 1) {
/* First, isolate and possibly identify request type */
hp->req = hp->s;
/*--------------------------------------------------------------------*/
+#include <errno.h>
+
static void
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)
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");