Hi all, Yesterday we tried to get the backend probe feature of varnish to work with zope. It failed, claiming that a response was not received. Checking the Z2 log showed that the request was received but that zero bytes was transferred. Using tcpdump shows that varnish closes the connection before zope can send the response.
I eventually distilled the check varnish uses into a small C program, and an interesting problem shows up. When you call shutdown(fd, SHUT_WR) on your socket connection, in effect telling zope that you're done talking to it, it looks like zope responds in kind by not talking to you either. I deduce this from the fact that poll() returns POLLHUP in revents and read() returns zero (EOF). POLLHUP, if I understand this correctly, means the other side (zope) has hung up. This effectively makes it impossible to use certain kinds of monitoring software with zope, specifically varnish. I would appreciate it if someone in the know could look at the code, tell me what I (and by extension varnish) am doing wrong, or whether this is perhaps a bug in zope (which I strongly suspect). The attached C code works fine against apache, and it also works fine against zope if you remove the shutdown() call. regards, Izak --- snip: poll.c --- #define URL "/" #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <poll.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv){ struct pollfd fds[1]; int timeout_msecs = 5000; int ret; int i, sd, request_size, offset; struct sockaddr_in addr; char buf[1024]; if(argc < 3){ fprintf(stderr, "Usage: %s ip port\n", argv[0]); return 1; } /* Open network connection */ sd = socket(AF_INET, SOCK_STREAM, 0); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(argv[1]); addr.sin_port = htons(atoi(argv[2])); if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0){ perror("connect"); return 1; } /* Send the request */ request_size = snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\nConnection: close\r\n\r\n", URL); offset = 0; while(offset < request_size){ i = write(sd, buf+offset, request_size-offset); offset += i; } /* Shutdown the write side */ shutdown(sd, SHUT_WR); /* Now wait for data to come back */ do { fds[0].fd = sd; fds[0].events = POLLIN; fds[0].revents = 0; ret = poll(fds, 1, timeout_msecs); if (ret > 0) { printf("%d POLLIN events on fd %d\n", ret, fds[0].fd); printf("revents = %d\n", fds[0].revents); i = read(sd, buf, sizeof(buf)); printf("Read %d bytes from %d\n", i, sd); } else if (ret == 0){ printf("Timeout\n"); } else { perror("poll"); } } while(i>0); } --- snip --- _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )