r159 - trunk/varnish-cache/bin/varnishd
phk at projects.linpro.no
phk at projects.linpro.no
Mon May 1 12:55:27 CEST 2006
Author: phk
Date: 2006-05-01 12:55:27 +0200 (Mon, 01 May 2006)
New Revision: 159
Modified:
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_acceptor.c
trunk/varnish-cache/bin/varnishd/cache_fetch.c
trunk/varnish-cache/bin/varnishd/cache_http.c
trunk/varnish-cache/bin/varnishd/cache_main.c
trunk/varnish-cache/bin/varnishd/cache_pass.c
trunk/varnish-cache/bin/varnishd/cache_pool.c
Log:
Add INCOMPL() macro to mark missing code.
Add http_HdrIs() to check if we have a given header and if we do
if it has a given value.
Use it.
Ignore SIGPIPE since SO_NOSIGPIPE doesn't work reliably, (but set
it on accepted TCP connections anyway).
Update passing to match fetching, including a chunked encoding method.
Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2006-05-01 10:55:27 UTC (rev 159)
@@ -83,6 +83,7 @@
struct http *http_New(void);
void http_Delete(struct http *hp);
int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
+int http_HdrIs(struct http *hp, const char *hdr, const char *val);
int http_GetTail(struct http *hp, unsigned len, char **b, char **e);
int http_GetURL(struct http *hp, char **b);
void http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg);
@@ -108,6 +109,10 @@
void VSLR(enum shmlogtag tag, unsigned id, const char *b, const char *e);
void VSL(enum shmlogtag tag, unsigned id, const char *fmt, ...);
#define HERE() VSL(SLT_Debug, 0, "HERE: %s(%d)", __func__, __LINE__)
+#define INCOMPL() do { \
+ VSL(SLT_Debug, 0, "INCOMPLETE AT: %s(%d)", __func__, __LINE__); \
+ assert(__LINE__ == 0); \
+ } while (0)
#endif
/* cache_vcl.c */
Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -58,6 +58,7 @@
struct sockaddr addr;
struct sess *sp;
char port[10];
+ int i;
(void)arg;
sm = calloc(sizeof *sm, 1);
@@ -76,6 +77,8 @@
free(sp);
return;
}
+ i = 1;
+ AZ(setsockopt(sp->fd, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i));
AZ(getnameinfo(&addr, l,
sp->addr, VCA_ADDRBUFSIZE,
port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV));
Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -165,9 +165,7 @@
VSL(SLT_Handling, sp->fd, "Fetch fd %d", fd);
hp = http_New();
-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));
@@ -190,12 +188,11 @@
assert(sp->handling == HND_Insert);
- if (http_GetHdr(hp, "Content-Length", &b)) {
+ if (http_GetHdr(hp, "Content-Length", &b))
cls = fetch_straight(w, sp, fd, hp, b);
- } else if (http_GetHdr(hp, "Transfer-Encoding", &b) &&
- !strcasecmp(b, "chunked")) {
+ else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
cls = fetch_chunked(w, sp, fd, hp);
- } else {
+ else {
VSL(SLT_Debug, fd, "No transfer");
cls = 0;
}
Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -102,6 +102,19 @@
}
int
+http_HdrIs(struct http *hp, const char *hdr, const char *val)
+{
+ char *p;
+
+ if (!http_GetHdr(hp, hdr, &p))
+ return (0);
+ assert(p != NULL);
+ if (!strcasecmp(p, val))
+ return (1);
+ return (0);
+}
+
+int
http_GetURL(struct http *hp, char **b)
{
if (hp->url == NULL)
@@ -346,6 +359,7 @@
sbuf_cat(sb, " ");
sbuf_cat(sb, hp->proto);
} else {
+ printf("resp = %d\n", resp);
assert(resp == 1 || resp == 2);
}
sbuf_cat(sb, "\r\n");
Modified: trunk/varnish-cache/bin/varnishd/cache_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_main.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_main.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -6,6 +6,7 @@
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
+#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
@@ -103,6 +104,9 @@
struct cli *cli;
int i;
+ /* XXX: SO_NOSIGPIPE does not work reliably :-( */
+ signal(SIGPIPE, SIG_IGN);
+
setbuf(stdout, NULL);
setbuf(stderr, NULL);
printf("Child starts\n");
Modified: trunk/varnish-cache/bin/varnishd/cache_pass.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pass.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_pass.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -22,25 +22,146 @@
#include "vcl_lang.h"
#include "cache.h"
+
/*--------------------------------------------------------------------*/
+
+static int
+pass_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *bi)
+{
+ int i, j;
+ char *b, *e;
+ off_t cl;
+ unsigned c;
+ char buf[BUFSIZ];
+
+ if (bi != NULL)
+ cl = strtoumax(bi, NULL, 0);
+ else
+ cl = (1<<30); /* XXX */
+
+ i = fcntl(fd, F_GETFL); /* XXX ? */
+ i &= ~O_NONBLOCK;
+ i = fcntl(fd, F_SETFL, i);
+
+ while (cl != 0) {
+ c = cl;
+ if (c > sizeof buf)
+ c = sizeof buf;
+ if (http_GetTail(hp, c, &b, &e)) {
+ i = e - b;
+ j = write(sp->fd, b, i);
+ assert(i == j);
+ cl -= i;
+ continue;
+ }
+ i = read(fd, buf, c);
+ if (i == 0 && bi == NULL)
+ return (1);
+ assert(i > 0);
+ j = write(sp->fd, buf, i);
+ assert(i == j);
+ cl -= i;
+ }
+ return (0);
+}
+
+
+/*--------------------------------------------------------------------*/
+
+static int
+pass_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
+{
+ int i, j;
+ char *b, *q, *e;
+ char *p;
+ unsigned u;
+ char buf[BUFSIZ];
+ char *bp, *be;
+
+ i = fcntl(fd, F_GETFL); /* XXX ? */
+ i &= ~O_NONBLOCK;
+ i = fcntl(fd, F_SETFL, i);
+
+ bp = buf;
+ be = buf + sizeof buf;
+ p = buf;
+ while (1) {
+ if (http_GetTail(hp, be - bp, &b, &e)) {
+ memcpy(bp, b, e - b);
+ bp += e - b;
+ } else {
+ /* XXX: must be safe from backend */
+ i = read(fd, bp, be - bp);
+ assert(i > 0);
+ bp += i;
+ }
+ /* buffer valid from p to bp */
+
+ u = strtoul(p, &q, 16);
+ if (q == NULL || (*q != '\n' && *q != '\r')) {
+ INCOMPL();
+ /* XXX: move bp to buf start, get more */
+ }
+ if (*q == '\r')
+ q++;
+ assert(*q == '\n');
+ q++;
+ if (u == 0)
+ break;
+
+ j = q - p;
+ i = write(sp->fd, q, j);
+ assert(i == j);
+
+ p = q;
+
+ while (u > 0) {
+ j = u;
+ if (bp == p) {
+ bp = p = buf;
+ break;
+ }
+ if (bp - p < j)
+ j = bp - p;
+ i = write(sp->fd, p, j);
+ assert(i == j);
+ p += j;
+ u -= i;
+ }
+ while (u > 0) {
+ if (http_GetTail(hp, u, &b, &e)) {
+ j = e - b;
+ i = write(sp->fd, q, j);
+ assert(i == j);
+ u -= j;
+ } else
+ break;
+ }
+ while (u > 0) {
+ j = u;
+ if (j > sizeof buf)
+ j = sizeof buf;
+ i = read(fd, buf, j);
+ assert(i > 0);
+ j = write(sp->fd, buf, i);
+ assert(j == i);
+ u -= i;
+ }
+ }
+ return (0);
+}
+
+
+/*--------------------------------------------------------------------*/
void
PassSession(struct worker *w, struct sess *sp)
{
- int fd, i, j;
+ int fd, i;
void *fd_token;
- struct sess sp2;
- char buf[BUFSIZ];
- off_t cl;
+ struct http *hp;
char *b;
+ int cls;
- if (http_GetHdr(sp->http, "Connection", &b) && !strcmp(b, "close")) {
- /*
- * If client wants only this one request, piping is safer
- * and cheaper
- */
- PipeSession(w, sp);
- return;
- }
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
@@ -50,69 +171,35 @@
/* 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(sp2.http, sp2.fd, w->eb, NULL, NULL);
+ hp = http_New();
+ http_RecvHead(hp, fd, w->eb, NULL, NULL);
event_base_loop(w->eb, 0);
- http_Dissect(sp2.http, sp2.fd, 2);
+ http_Dissect(hp, fd, 2);
- http_BuildSbuf(2, w->sb, sp2.http);
+ http_BuildSbuf(2, w->sb, hp);
i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
- assert(__LINE__ == 0);
- cl = j = 0;
- *buf = 0;
-
-#if 0
- if (sp2.http.H_Content_Length != NULL) {
- cl = strtoumax(sp2.http.H_Content_Length, NULL, 0);
- i = fcntl(sp2.fd, F_GETFL);
- i &= ~O_NONBLOCK;
- i = fcntl(sp2.fd, F_SETFL, i);
- assert(i != -1);
- i = sp2.rcv_len - sp2.rcv_ptr;
- if (i > 0) {
- j = write(sp->fd, sp2.rcv + sp2.rcv_ptr, i);
- assert(j == i);
- cl -= i;
- sp2.rcv_ptr += i;
- }
- while (cl > 0) {
- j = sizeof buf;
- if (j > cl)
- j = cl;
- i = recv(sp2.fd, buf, j, 0);
- assert(i >= 0);
- if (i > 0) {
- cl -= i;
- j = write(sp->fd, buf, i);
- assert(j == i);
- } else if (i == 0) {
- break;
- }
- }
- assert(cl == 0);
+ if (http_GetHdr(hp, "Content-Length", &b))
+ cls = pass_straight(w, sp, fd, hp, b);
+ else if (http_HdrIs(hp, "Connection", "close"))
+ cls = pass_straight(w, sp, fd, hp, NULL);
+ else if (http_HdrIs(hp, "Transfer-Encoding", "chunked"))
+ cls = pass_chunked(w, sp, fd, hp);
+ else {
+ INCOMPL();
+ cls = 1;
}
- if (sp2.http.H_Connection != NULL &&
- !strcmp(sp2.http.H_Connection, "close")) {
- close(fd);
+ if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close"))
+ cls = 1;
+
+ if (cls)
VBE_ClosedFd(fd_token);
- } else {
+ else
VBE_RecycleFd(fd_token);
- }
-
- /* XXX: this really belongs in the acceptor */
- if (sp->rcv_len > sp->rcv_ptr)
- memmove(sp->rcv, sp->rcv + sp->rcv_ptr,
- sp->rcv_len - sp->rcv_ptr);
- sp->rcv_len -= sp->rcv_ptr;
- sp->rcv_ptr = 0;
-#endif
}
Modified: trunk/varnish-cache/bin/varnishd/cache_pool.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-05-01 07:54:13 UTC (rev 158)
+++ trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-05-01 10:55:27 UTC (rev 159)
@@ -126,6 +126,7 @@
sp->handling = HND_Lookup;
sp->vcl->recv_func(sp);
+ sp->handling = HND_Pass;
for (done = 0; !done; ) {
switch(sp->handling) {
More information about the varnish-commit
mailing list