cache_acceptor.c \
cache_backend.c \
cache_fetch.c \
- cache_httpd.c \
+ cache_http.c \
cache_main.c \
cache_pool.c \
cache_pass.c \
/* cache_fetch.c */
int FetchSession(struct worker *w, struct sess *sp);
-/* cache_httpd.c */
-void HttpdAnalyze(struct sess *sp, int rr);
-void HttpdGetHead(struct sess *sp, struct event_base *eb, sesscb_f *func);
-void HttpdBuildSbuf(int resp, int filter, struct sbuf *sb, struct sess *sp);
+/* cache_http.c */
+typedef void http_callback_f(void *, int good);
+struct http;
+struct http *http_New(void);
+void http_Delete(struct http *hp);
+int http_GetHdr(struct http *hp, const char *hdr, char **ptr);
+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);
+void http_Dissect(struct http *sp, int fd, int rr);
+void http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp);
/* cache_main.c */
pthread_mutex_t sessmtx;
/* cache_pool.c */
void CacheInitPool(void);
-void DealWithSession(struct sess *sp);
+void DealWithSession(void *arg, int good);
/* cache_shmlog.c */
void VSL_Init(void);
i = read(fd, &sp, sizeof sp);
assert(i == sizeof sp);
- HttpdGetHead(sp, evb, DealWithSession);
+ http_RecvHead(sp->http, sp->fd, evb, DealWithSession, sp);
}
static void
strlcat(sp->addr, ":", VCA_ADDRBUFSIZE);
strlcat(sp->addr, port, VCA_ADDRBUFSIZE);
VSL(SLT_SessionOpen, sp->fd, "%s", sp->addr);
- HttpdGetHead(sp, evb, DealWithSession);
+ sp->http = http_New();
+ http_RecvHead(sp->http, sp->fd, evb, DealWithSession, sp);
}
void *
vca_retire_session(struct sess *sp)
{
- VSL(SLT_SessionClose, sp->fd, "%s", sp->addr);
- if (sp->fd >= 0)
+ if (sp->http != NULL)
+ http_Delete(sp->http);
+ if (sp->fd >= 0) {
+ VSL(SLT_SessionClose, sp->fd, "%s", sp->addr);
close(sp->fd);
+ }
free(sp);
}
#include "vcl_lang.h"
#include "cache.h"
-static void
-FetchReturn(struct sess *sp)
-{
-
- /* do nothing */
-}
-
/*--------------------------------------------------------------------*/
int
FetchSession(struct worker *w, struct sess *sp)
off_t cl;
struct storage *st;
unsigned char *p;
+ char *b, *e;
+ struct http *hp;
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
- VSL(SLT_HandlingFetch, sp->fd, "%d", fd);
- HttpdBuildSbuf(0, 1, w->sb, sp);
+ hp = http_New();
+ http_BuildSbuf(0, w->sb, sp->http);
i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
* XXX: It might be cheaper to avoid the event_engine and simply
* XXX: read(2) the header
*/
- HttpdGetHead(&sp2, w->eb, FetchReturn);
+ http_RecvHead(hp, sp2.fd, w->eb, NULL, NULL);
event_base_loop(w->eb, 0);
- HttpdAnalyze(&sp2, 2);
+ http_Dissect(hp, sp2.fd, 2);
/* XXX: fill in object from headers */
sp->obj->valid = 1;
/* XXX: unbusy, and kick other sessions into action */
sp->obj->busy = 0;
- assert (sp2.http.H_Content_Length != NULL); /* XXX */
+ assert(http_GetHdr(hp, "Content-Length", &b));
- cl = strtoumax(sp2.http.H_Content_Length, NULL, 0);
+ cl = strtoumax(b, NULL, 0);
+ VSL(SLT_Debug, 0, "cl %jd (%s)", cl, b);
sp->handling = HND_Unclass;
sp->vcl->fetch_func(sp);
i &= ~O_NONBLOCK;
i = fcntl(sp2.fd, F_SETFL, i);
- i = sp2.rcv_len - sp2.rcv_ptr;
- if (i > 0) {
- memcpy(p, sp2.rcv + sp2.rcv_ptr, i);
+ if (http_GetTail(hp, cl, &b, &e)) {
+ i = e - b;
+ VSL(SLT_Debug, 0, "T i %d cl %jd", i, cl);
+ memcpy(p, b, i);
p += i;
cl -= i;
}
while (cl != 0) {
i = read(sp2.fd, p, cl);
- assert(i > 0);
VSL(SLT_Debug, 0, "R i %d cl %jd", i, cl);
+ assert(i > 0);
p += i;
cl -= i;
}
- HttpdBuildSbuf(1, 1, w->sb, &sp2);
+ http_BuildSbuf(1, w->sb, hp);
i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
i = write(sp->fd, st->ptr, st->len);
- VSL(SLT_Debug, 0, "W i %d st->len %u", i, st->len);
assert(i == st->len);
hash->deref(sp->obj);
- if (sp2.http.H_Connection != NULL &&
- !strcmp(sp2.http.H_Connection, "close")) {
+ if (http_GetHdr(sp->http, "Connection", &b) &&
+ !strcasecmp(b, "close")) {
close(fd);
VBE_ClosedFd(fd_token);
} 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;
return (1);
}
--- /dev/null
+/*
+ * $Id$
+ *
+ * HTTP request storage and manipulation
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <event.h>
+#include <sbuf.h>
+
+#include "libvarnish.h"
+#include "shmlog.h"
+#include "vcl_lang.h"
+#include "cache.h"
+
+static unsigned http_bufsize = 4096;
+static unsigned http_nhdr = 128;
+
+/*--------------------------------------------------------------------*/
+
+struct http {
+ struct event ev;
+ http_callback_f *callback;
+ void *arg;
+
+ char *s; /* start of buffer */
+ char *v; /* valid bytes */
+ char *t; /* start of trailing data */
+
+
+ char *req;
+ char *url;
+ char *proto;
+ char *status;
+ char *response;
+
+ char **hdr;
+ unsigned nhdr;
+};
+
+/*--------------------------------------------------------------------*/
+
+struct http *
+http_New(void)
+{
+ struct http *hp;
+
+ hp = calloc(sizeof *hp, 1);
+ assert(hp != NULL);
+
+ hp->s = malloc(http_bufsize);
+ assert(hp->s != NULL);
+
+ hp->v = hp->s;
+
+ hp->hdr = malloc(sizeof *hp->hdr * http_nhdr);
+ assert(hp->hdr != NULL);
+
+ return (hp);
+}
+
+void
+http_Delete(struct http *hp)
+{
+
+ free(hp->hdr);
+ free(hp->s);
+ free(hp);
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+http_GetHdr(struct http *hp, const char *hdr, char **ptr)
+{
+ unsigned u, l;
+ char *p;
+
+ l = strlen(hdr);
+ for (u = 0; u < hp->nhdr; u++) {
+ if (strncasecmp(hdr, hp->hdr[u], l))
+ continue;
+ p = hp->hdr[u];
+ if (p[l] != ':')
+ continue;
+ p += l + 1;
+ while (isspace(*p))
+ p++;
+ *ptr = p;
+ return (1);
+ }
+ return (0);
+}
+
+int
+http_GetURL(struct http *hp, char **b)
+{
+ if (hp->url == NULL)
+ return (0);
+ *b = hp->url;
+ return (1);
+}
+
+int
+http_GetTail(struct http *hp, unsigned len, char **b, char **e)
+{
+
+ if (hp->t >= hp->v)
+ return (0);
+
+ if (len == 0)
+ len = hp->v - hp->t;
+
+ if (hp->t + len > hp->v)
+ len = hp->v - hp->t;
+ if (len == 0)
+ return (0);
+ *b = hp->t;
+ *e = hp->t + len;
+ hp->t += len;
+ return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+http_Dissect(struct http *hp, int fd, int rr)
+{
+ char *p, *q, *r;
+
+ if (rr == 1) {
+ /* First, isolate and possibly identify request type */
+ hp->req = hp->s;
+ for (p = hp->s; isalpha(*p); p++)
+ ;
+ VSLR(SLT_Request, fd, hp->req, p);
+ *p++ = '\0';
+
+ /* Next find the URI */
+ while (isspace(*p))
+ p++;
+ hp->url = p;
+ while (!isspace(*p))
+ p++;
+ VSLR(SLT_URL, fd, hp->url, p);
+ *p++ = '\0';
+
+ /* Finally, look for protocol, if any */
+ while (isspace(*p) && *p != '\n')
+ p++;
+ hp->proto = p;
+ if (*p != '\n') {
+ while (!isspace(*p))
+ p++;
+ }
+ VSLR(SLT_Protocol, fd, hp->proto, p);
+ *p++ = '\0';
+
+ while (isspace(*p) && *p != '\n')
+ p++;
+ p++;
+ } else {
+ /* First, protocol */
+ hp->proto = hp->s;
+ p = hp->s;
+ while (!isspace(*p))
+ p++;
+ VSLR(SLT_Protocol, fd, hp->proto, p);
+ *p++ = '\0';
+
+ /* Next find the status */
+ while (isspace(*p))
+ p++;
+ hp->status = p;
+ while (!isspace(*p))
+ p++;
+ VSLR(SLT_Status, fd, hp->status, p);
+ *p++ = '\0';
+
+ /* Next find the response */
+ while (isspace(*p))
+ p++;
+ hp->response = p;
+ while (*p != '\n')
+ p++;
+ for (q = p; q > hp->response && isspace(q[-1]); q--)
+ continue;
+ *q = '\0';
+ VSLR(SLT_Response, fd, hp->response, q);
+ p++;
+ }
+
+ if (*p == '\r')
+ p++;
+
+ for (; p < hp->v; p = r) {
+ q = strchr(p, '\n');
+ assert(q != NULL);
+ r = q + 1;
+ if (q > p && q[-1] == '\r')
+ q--;
+ *q = '\0';
+ if (p == q)
+ break;
+
+ if (hp->nhdr < http_nhdr) {
+ hp->hdr[hp->nhdr++] = p;
+ VSLR(SLT_Header, fd, p, q);
+ } else {
+ VSLR(SLT_LostHeader, fd, p, q);
+ }
+ }
+ if (*++p == '\r')
+ p++;
+ hp->t = ++p;
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+http_read_f(int fd, short event, void *arg)
+{
+ struct http *hp = arg;
+ char *p;
+ int i;
+
+ assert(hp->v < hp->s + http_bufsize);
+ i = read(fd, hp->v, (hp->s + http_bufsize) - hp->v);
+ if (i <= 0) {
+ if (hp->v != hp->s)
+ VSL(SLT_SessionClose, fd,
+ "remote had %d bytes", hp->v - hp->s);
+ else
+ VSL(SLT_SessionClose, fd, "remote");
+ hp->t = NULL;
+ event_del(&hp->ev);
+ if (hp->callback != NULL)
+ hp->callback(hp->arg, 0);
+ return;
+ }
+
+ hp->v += i;
+ *hp->v = '\0';
+
+ p = hp->s;
+ while (1) {
+ /* XXX: we could save location of all linebreaks for later */
+ p = strchr(p, '\n');
+ if (p == NULL)
+ return;
+ p++;
+ if (*p == '\r')
+ p++;
+ if (*p != '\n')
+ continue;
+ break;
+ }
+ hp->t = ++p;
+
+ event_del(&hp->ev);
+ if (hp->callback != NULL)
+ hp->callback(hp->arg, 1);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg)
+{
+
+ assert(hp != NULL);
+ hp->callback = func;
+ hp->arg = arg;
+ hp->t = hp->s;
+ event_set(&hp->ev, fd, EV_READ | EV_PERSIST, http_read_f, hp);
+ event_base_set(eb, &hp->ev);
+ event_add(&hp->ev, NULL); /* XXX: timeout */
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+http_supress(const char *hdr, int flag)
+{
+
+#define HTTPH_0(a,d)
+#define HTTPH_1(a,d) \
+ if ((flag & d) && !strncasecmp(hdr, a, strlen(a))) { \
+ return (1); \
+ }
+#define HTTPH_2(a,d) HTTPH_1(a,d)
+#define HTTPH_3(a,d) HTTPH_1(a,d)
+
+#define HTTPH(a,b,c,d,e,f,g) HTTPH_ ## d(a ":",d)
+#include "http_headers.h"
+#undef HTTPH
+#undef HTTPH_0
+#undef HTTPH_1
+#undef HTTPH_2
+#undef HTTPH_3
+
+ return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp)
+{
+ unsigned u;
+
+ sbuf_clear(sb);
+ assert(sb != NULL);
+ if (resp) {
+ sbuf_cat(sb, hp->proto);
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->status);
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->response);
+ } else {
+ sbuf_cat(sb, hp->req);
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->url);
+ sbuf_cat(sb, " ");
+ sbuf_cat(sb, hp->proto);
+ }
+ sbuf_cat(sb, "\r\n");
+
+ for (u = 0; u < hp->nhdr; u++) {
+ if (http_supress(hp->hdr[u], resp))
+ continue;
+ sbuf_cat(sb, hp->hdr[u]);
+ sbuf_cat(sb, "\r\n");
+ }
+ sbuf_cat(sb, "\r\n");
+ sbuf_finish(sb);
+}
+++ /dev/null
-/*
- * $Id$
- *
- * Stuff relating to HTTP server side
- */
-
-#include <stdio.h>
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <ctype.h>
-#include <event.h>
-#include <sbuf.h>
-
-#include "libvarnish.h"
-#include "shmlog.h"
-#include "vcl_lang.h"
-#include "cache.h"
-
-/*--------------------------------------------------------------------*/
-
-void
-HttpdAnalyze(struct sess *sp, int rr)
-{
- char *p, *q, *r;
-
- sp->handling = HND_Unclass;
-
- memset(&sp->http, 0, sizeof sp->http);
-
- if (rr == 1) {
- /* First, isolate and possibly identify request type */
- sp->http.req = sp->rcv;
- for (p = sp->rcv; isalpha(*p); p++)
- ;
- VSLR(SLT_Request, sp->fd, sp->http.req, p);
- *p++ = '\0';
-
- /* Next find the URI */
- while (isspace(*p))
- p++;
- sp->http.url = p;
- while (!isspace(*p))
- p++;
- VSLR(SLT_URL, sp->fd, sp->http.url, p);
- *p++ = '\0';
-
- /* Finally, look for protocol, if any */
- while (isspace(*p) && *p != '\n')
- p++;
- sp->http.proto = p;
- if (*p != '\n') {
- while (!isspace(*p))
- p++;
- }
- VSLR(SLT_Protocol, sp->fd, sp->http.proto, p);
- *p++ = '\0';
-
- while (isspace(*p) && *p != '\n')
- p++;
- p++;
- } else {
- /* First, protocol */
- sp->http.proto = sp->rcv;
- p = sp->rcv;
- while (!isspace(*p))
- p++;
- VSLR(SLT_Protocol, sp->fd, sp->http.proto, p);
- *p++ = '\0';
-
- /* Next find the status */
- while (isspace(*p))
- p++;
- sp->http.status = p;
- while (!isspace(*p))
- p++;
- VSLR(SLT_Status, sp->fd, sp->http.status, p);
- *p++ = '\0';
-
- /* Next find the response */
- while (isspace(*p))
- p++;
- sp->http.response = p;
- while (*p != '\n')
- p++;
- for (q = p; q > sp->http.response && isspace(q[-1]); q--)
- continue;
- *q = '\0';
- VSLR(SLT_Response, sp->fd, sp->http.response, q);
- p++;
- }
-
- if (*p == '\r')
- p++;
-
- for (; p < sp->rcv + sp->rcv_len; p = r) {
- q = strchr(p, '\n');
- assert(q != NULL);
- r = q + 1;
- if (q > p && q[-1] == '\r')
- q--;
- *q = '\0';
- if (p == q)
- break;
-
-#define W(a, b, p, q, sp) \
- if (!strncasecmp(p, a, strlen(a))) { \
- for (p += strlen(a); p < q && isspace(*p); p++) \
- continue; \
- sp->http.b = p; \
- VSLR(SLT_##b, sp->fd, p, q); \
- continue; \
- }
-
-#define HTTPH(a, b, c, d, e, f, g) \
- if (c & rr) { \
- W(a ":", b, p, q, sp); \
- }
-#include "http_headers.h"
-#undef HTTPH
-#undef W
- if (sp->http.nuhdr < VCA_UNKNOWNHDR) {
- sp->http.uhdr[sp->http.nuhdr++] = p;
- VSLR(SLT_HD_Unknown, sp->fd, p, q);
- } else {
- VSLR(SLT_HD_Lost, sp->fd, p, q);
- }
- }
-}
-
-/*--------------------------------------------------------------------*/
-
-static void
-http_read_f(int fd, short event, void *arg)
-{
- struct sess *sp = arg;
- const char *p;
- int i;
-
- assert(VCA_RXBUFSIZE - sp->rcv_len > 0);
- i = read(fd, sp->rcv + sp->rcv_len, VCA_RXBUFSIZE - sp->rcv_len);
- if (i <= 0) {
- VSL(SLT_SessionClose, sp->fd, "remote %d", sp->rcv_len);
- event_del(sp->rd_e);
- close(sp->fd);
- free(sp->mem);
- return;
- }
-
- sp->rcv_len += i;
- sp->rcv[sp->rcv_len] = '\0';
-
- p = sp->rcv;
- while (1) {
- /* XXX: we could save location of all linebreaks for later */
- p = strchr(p, '\n');
- if (p == NULL)
- return;
- p++;
- if (*p == '\r')
- p++;
- if (*p != '\n')
- continue;
- break;
- }
- sp->rcv_ptr = ++p - sp->rcv;
-
- event_del(sp->rd_e);
- sp->sesscb(sp);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-HttpdGetHead(struct sess *sp, struct event_base *eb, sesscb_f *func)
-{
-
- sp->sesscb = func;
- assert(sp->rd_e != NULL);
- event_set(sp->rd_e, sp->fd, EV_READ | EV_PERSIST, http_read_f, sp);
- event_base_set(eb, sp->rd_e);
- event_add(sp->rd_e, NULL); /* XXX: timeout */
-}
-
-/*--------------------------------------------------------------------*/
-
-void
-HttpdBuildSbuf(int resp, int filter, struct sbuf *sb, struct sess *sp)
-{
-
- sbuf_clear(sb);
- assert(sb != NULL);
- if (resp) {
- sbuf_cat(sb, sp->http.proto);
- sbuf_cat(sb, " ");
- sbuf_cat(sb, sp->http.status);
- sbuf_cat(sb, " ");
- sbuf_cat(sb, sp->http.response);
- } else {
- sbuf_cat(sb, sp->http.req);
- sbuf_cat(sb, " ");
- sbuf_cat(sb, sp->http.url);
- sbuf_cat(sb, " ");
- sbuf_cat(sb, sp->http.proto);
- }
- sbuf_cat(sb, "\r\n");
-#define HTTPH(a, b, c, d, e, f, g) \
- do { \
- if ((!filter || d) && sp->http.b != NULL) { \
- sbuf_cat(sb, a ": "); \
- sbuf_cat(sb, sp->http.b); \
- sbuf_cat(sb, "\r\n"); \
- } \
- } while (0);
-#include "http_headers.h"
-#undef HTTPH
- sbuf_cat(sb, "\r\n");
- sbuf_finish(sb);
-}
#include "vcl_lang.h"
#include "cache.h"
-static void
-PassReturn(struct sess *sp)
-{
-
- /* do nothing */
-}
-
/*--------------------------------------------------------------------*/
void
PassSession(struct worker *w, struct sess *sp)
struct sess sp2;
char buf[BUFSIZ];
off_t cl;
+ char *b;
- if (sp->http.H_Connection != NULL &&
- !strcmp(sp->http.H_Connection, "close")) {
+ if (http_GetHdr(sp->http, "Connection", &b) && !strcmp(b, "close")) {
/*
* If client wants only this one request, piping is safer
* and cheaper
*/
- VSL(SLT_HandlingPass, sp->fd, "pipe");
PipeSession(w, sp);
return;
}
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
- VSL(SLT_HandlingPass, sp->fd, "%d", fd);
- HttpdBuildSbuf(0, 1, w->sb, sp);
+ http_BuildSbuf(0, w->sb, sp->http);
i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
* XXX: It might be cheaper to avoid the event_engine and simply
* XXX: read(2) the header
*/
- HttpdGetHead(&sp2, w->eb, PassReturn);
+ http_RecvHead(sp2.http, sp2.fd, w->eb, NULL, NULL);
event_base_loop(w->eb, 0);
- HttpdAnalyze(&sp2, 2);
+ http_Dissect(sp2.http, sp2.fd, 2);
- HttpdBuildSbuf(1, 1, w->sb, &sp2);
+ http_BuildSbuf(1, w->sb, sp2.http);
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);
sp->rcv_len - sp->rcv_ptr);
sp->rcv_len -= sp->rcv_ptr;
sp->rcv_ptr = 0;
+#endif
}
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
- VSL(SLT_HandlingPipe, sp->fd, "%d", fd);
- HttpdBuildSbuf(0, 0, w->sb, sp);
+ http_BuildSbuf(0, w->sb, sp->http);
i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
assert(i == sbuf_len(w->sb));
+ assert(__LINE__ == 0);
+ j = 0;
+#if 0
i = sp->rcv_len - sp->rcv_ptr;
if (i > 0) {
j = write(sp->fd, sp->rcv + sp->rcv_ptr, i);
assert(j == i);
}
+#endif
e1.fd = fd;
e2.fd = sp->fd;
struct object *o;
unsigned char key[16];
MD5_CTX ctx;
+ char *b;
if (w->nobj == NULL) {
w->nobj = calloc(sizeof *w->nobj, 1);
TAILQ_INIT(&w->nobj->store);
}
+ assert(http_GetURL(sp->http, &b));
MD5Init(&ctx);
- MD5Update(&ctx, sp->http.url, strlen(sp->http.url));
+ MD5Update(&ctx, b, strlen(b));
MD5Final(key, &ctx);
o = hash->lookup(key, w->nobj);
if (o == w->nobj) {
- VSL(SLT_Debug, 0, "Lookup new %p %s", o, sp->http.url);
+ VSL(SLT_Debug, 0, "Lookup new %p %s", o, b);
w->nobj = NULL;
} else {
- VSL(SLT_Debug, 0, "Lookup found %p %s", o, sp->http.url);
+ VSL(SLT_Debug, 0, "Lookup found %p %s", o, b);
}
/*
* XXX: if obj is busy, park session on it
struct sess *sp;
struct worker w;
int done;
+ char *b;
memset(&w, 0, sizeof w);
w.eb = event_init();
sp->vcl = GetVCL();
AZ(pthread_mutex_unlock(&sessmtx));
- HttpdAnalyze(sp, 1);
+ http_Dissect(sp->http, sp->fd, 1);
sp->backend = sp->vcl->default_backend;
sp->vcl->recv_func(sp);
for (done = 0; !done; ) {
- printf("Handling: %d\n", sp->handling);
switch(sp->handling) {
case HND_Lookup:
+ VSL(SLT_Handling, sp->fd, "Lookup");
done = LookupSession(&w, sp);
break;
case HND_Fetch:
+ VSL(SLT_Handling, sp->fd, "Fetch");
done = FetchSession(&w, sp);
break;
case HND_Deliver:
+ VSL(SLT_Handling, sp->fd, "Deliver");
done = DeliverSession(&w, sp);
break;
case HND_Pipe:
+ VSL(SLT_Handling, sp->fd, "Pipe");
PipeSession(&w, sp);
done = 1;
break;
case HND_Pass:
+ VSL(SLT_Handling, sp->fd, "Pass");
PassSession(&w, sp);
done = 1;
break;
case HND_Unclass:
+ VSL(SLT_Handling, sp->fd, "Unclass");
assert(sp->handling == HND_Unclass);
+ assert(sp->handling != HND_Unclass);
}
}
- if (sp->http.H_Connection != NULL &&
- !strcmp(sp->http.H_Connection, "close")) {
+ if (http_GetHdr(sp->http, "Connection", &b) &&
+ !strcmp(b, "close")) {
+ VSL(SLT_SessionClose, sp->fd, "hdr");
close(sp->fd);
sp->fd = -1;
}
}
void
-DealWithSession(struct sess *sp)
+DealWithSession(void *arg, int good)
{
+ struct sess *sp = arg;
+
+ if (!good) {
+ vca_retire_session(sp);
+ return;
+ }
AZ(pthread_mutex_lock(&sessmtx));
TAILQ_INSERT_TAIL(&shd, sp, list);
AZ(pthread_mutex_unlock(&sessmtx));
#include "cli.h"
#include "cli_priv.h"
+#include "shmlog.h"
#include "vcl_lang.h"
#include "libvarnish.h"
#include "cache.h"
void VCL_error(VCL_FARGS, unsigned err, const char *str) {
}
+
+void
+VCL_count(unsigned u)
+{
+
+ VSL(SLT_VCL, 0, "%u", u);
+}
+
#include <printf.h>
#include <err.h>
-void
-VCL_count(unsigned u)
-{
-}
-
int
main(int argc, char *argv[])
{
* a Http header name
* b session field name
* c Request(1)/Response(2) bitfield
- * d Pass header
+ * d Supress header to backend (1) / Supress header to client (2)
* e unused
* f unused
* g unused
*--------------------------------------------------------------------
*/
-HTTPH("Keep-Alive", H_Keep_Alive, 3, 0, 0, 0, 0) /* RFC2068 */
+HTTPH("Keep-Alive", H_Keep_Alive, 3, 3, 0, 0, 0) /* RFC2068 */
-HTTPH("Accept", H_Accept, 1, 1, 0, 0, 0) /* RFC2616 14.1 */
-HTTPH("Accept-Charset", H_Accept_Charset, 1, 1, 0, 0, 0) /* RFC2616 14.2 */
-HTTPH("Accept-Encoding", H_Accept_Encoding, 1, 1, 0, 0, 0) /* RFC2616 14.3 */
-HTTPH("Accept-Language", H_Accept_Language, 1, 1, 0, 0, 0) /* RFC2616 14.4 */
-HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 1, 0, 0, 0) /* RFC2616 14.5 */
-HTTPH("Age", H_Age, 2, 1, 0, 0, 0) /* RFC2616 14.6 */
-HTTPH("Allow", H_Allow, 2, 1, 0, 0, 0) /* RFC2616 14.7 */
-HTTPH("Authorization", H_Authorization, 1, 1, 0, 0, 0) /* RFC2616 14.8 */
-HTTPH("Cache-Control", H_Cache_Control, 3, 1, 0, 0, 0) /* RFC2616 14.9 */
-HTTPH("Connection", H_Connection, 3, 0, 0, 0, 0) /* RFC2616 14.10 */
-HTTPH("Content-Encoding", H_Content_Encoding, 2, 1, 0, 0, 0) /* RFC2616 14.11 */
-HTTPH("Content-Langugae", H_Content_Language, 2, 1, 0, 0, 0) /* RFC2616 14.12 */
-HTTPH("Content-Length", H_Content_Length, 2, 1, 0, 0, 0) /* RFC2616 14.13 */
-HTTPH("Content-Location", H_Content_Location, 2, 1, 0, 0, 0) /* RFC2616 14.14 */
-HTTPH("Content-MD5", H_Content_MD5, 2, 1, 0, 0, 0) /* RFC2616 14.15 */
-HTTPH("Content-Range", H_Content_Range, 2, 1, 0, 0, 0) /* RFC2616 14.16 */
-HTTPH("Content-Type", H_Content_Type, 2, 1, 0, 0, 0) /* RFC2616 14.17 */
-HTTPH("Date", H_Date, 2, 1, 0, 0, 0) /* RFC2616 14.18 */
-HTTPH("ETag", H_ETag, 2, 1, 0, 0, 0) /* RFC2616 14.19 */
-HTTPH("Expect", H_Expect, 1, 1, 0, 0, 0) /* RFC2616 14.20 */
-HTTPH("Expires", H_Expires, 2, 1, 0, 0, 0) /* RFC2616 14.21 */
-HTTPH("From", H_From, 1, 1, 0, 0, 0) /* RFC2616 14.22 */
-HTTPH("Host", H_Host, 1, 1, 0, 0, 0) /* RFC2616 14.23 */
-HTTPH("If-Match", H_If_Match, 1, 1, 0, 0, 0) /* RFC2616 14.24 */
-HTTPH("If-Modified-Since", H_If_Modified_Since, 1, 1, 0, 0, 0) /* RFC2616 14.25 */
-HTTPH("If-None-Match", H_If_None_Match, 1, 1, 0, 0, 0) /* RFC2616 14.26 */
-HTTPH("If-Range", H_If_Range, 1, 1, 0, 0, 0) /* RFC2616 14.27 */
-HTTPH("If-Unmodified-Since", H_If_Unmodifed_Since, 1, 1, 0, 0, 0) /* RFC2616 14.28 */
-HTTPH("Last-Modified", H_Last_Modified, 2, 1, 0, 0, 0) /* RFC2616 14.29 */
-HTTPH("Location", H_Location, 2, 1, 0, 0, 0) /* RFC2616 14.30 */
-HTTPH("Max-Forwards", H_Max_Forwards, 1, 1, 0, 0, 0) /* RFC2616 14.31 */
-HTTPH("Pragma", H_Pragma, 1, 1, 0, 0, 0) /* RFC2616 14.32 */
-HTTPH("Proxy-Authenticate", H_Proxy_Authenticate, 2, 1, 0, 0, 0) /* RFC2616 14.33 */
-HTTPH("Proxy-Authorization", H_Proxy_Authorization, 1, 1, 0, 0, 0) /* RFC2616 14.34 */
-HTTPH("Range", H_Range, 1, 1, 0, 0, 0) /* RFC2616 14.35 */
-HTTPH("Referer", H_Referer, 1, 1, 0, 0, 0) /* RFC2616 14.36 */
-HTTPH("Retry-After", H_Retry_After, 2, 1, 0, 0, 0) /* RFC2616 14.37 */
-HTTPH("Server", H_Server, 2, 1, 0, 0, 0) /* RFC2616 14.38 */
-HTTPH("TE", H_TE, 1, 1, 0, 0, 0) /* RFC2616 14.39 */
-HTTPH("Trailer", H_Trailer, 1, 1, 0, 0, 0) /* RFC2616 14.40 */
-HTTPH("Transfer-Encoding", H_Transfer_Encoding, 2, 1, 0, 0, 0) /* RFC2616 14.41 */
-HTTPH("Upgrade", H_Upgrade, 2, 1, 0, 0, 0) /* RFC2616 14.42 */
-HTTPH("User-Agent", H_User_Agent, 1, 1, 0, 0, 0) /* RFC2616 14.43 */
-HTTPH("Vary", H_Vary, 2, 1, 0, 0, 0) /* RFC2616 14.44 */
-HTTPH("Via", H_Via, 2, 1, 0, 0, 0) /* RFC2616 14.45 */
-HTTPH("Warning", H_Warning, 2, 1, 0, 0, 0) /* RFC2616 14.46 */
-HTTPH("WWW-Authenticate", H_WWW_Authenticate, 2, 1, 0, 0, 0) /* RFC2616 14.47 */
+HTTPH("Accept", H_Accept, 1, 0, 0, 0, 0) /* RFC2616 14.1 */
+HTTPH("Accept-Charset", H_Accept_Charset, 1, 0, 0, 0, 0) /* RFC2616 14.2 */
+HTTPH("Accept-Encoding", H_Accept_Encoding, 1, 0, 0, 0, 0) /* RFC2616 14.3 */
+HTTPH("Accept-Language", H_Accept_Language, 1, 0, 0, 0, 0) /* RFC2616 14.4 */
+HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 0, 0, 0, 0) /* RFC2616 14.5 */
+HTTPH("Age", H_Age, 2, 0, 0, 0, 0) /* RFC2616 14.6 */
+HTTPH("Allow", H_Allow, 2, 0, 0, 0, 0) /* RFC2616 14.7 */
+HTTPH("Authorization", H_Authorization, 1, 0, 0, 0, 0) /* RFC2616 14.8 */
+HTTPH("Cache-Control", H_Cache_Control, 3, 0, 0, 0, 0) /* RFC2616 14.9 */
+HTTPH("Connection", H_Connection, 3, 3, 0, 0, 0) /* RFC2616 14.10 */
+HTTPH("Content-Encoding", H_Content_Encoding, 2, 0, 0, 0, 0) /* RFC2616 14.11 */
+HTTPH("Content-Langugae", H_Content_Language, 2, 0, 0, 0, 0) /* RFC2616 14.12 */
+HTTPH("Content-Length", H_Content_Length, 2, 0, 0, 0, 0) /* RFC2616 14.13 */
+HTTPH("Content-Location", H_Content_Location, 2, 0, 0, 0, 0) /* RFC2616 14.14 */
+HTTPH("Content-MD5", H_Content_MD5, 2, 0, 0, 0, 0) /* RFC2616 14.15 */
+HTTPH("Content-Range", H_Content_Range, 2, 0, 0, 0, 0) /* RFC2616 14.16 */
+HTTPH("Content-Type", H_Content_Type, 2, 0, 0, 0, 0) /* RFC2616 14.17 */
+HTTPH("Date", H_Date, 2, 0, 0, 0, 0) /* RFC2616 14.18 */
+HTTPH("ETag", H_ETag, 2, 0, 0, 0, 0) /* RFC2616 14.19 */
+HTTPH("Expect", H_Expect, 1, 0, 0, 0, 0) /* RFC2616 14.20 */
+HTTPH("Expires", H_Expires, 2, 0, 0, 0, 0) /* RFC2616 14.21 */
+HTTPH("From", H_From, 1, 0, 0, 0, 0) /* RFC2616 14.22 */
+HTTPH("Host", H_Host, 1, 0, 0, 0, 0) /* RFC2616 14.23 */
+HTTPH("If-Match", H_If_Match, 1, 0, 0, 0, 0) /* RFC2616 14.24 */
+HTTPH("If-Modified-Since", H_If_Modified_Since, 1, 0, 0, 0, 0) /* RFC2616 14.25 */
+HTTPH("If-None-Match", H_If_None_Match, 1, 0, 0, 0, 0) /* RFC2616 14.26 */
+HTTPH("If-Range", H_If_Range, 1, 0, 0, 0, 0) /* RFC2616 14.27 */
+HTTPH("If-Unmodified-Since", H_If_Unmodifed_Since, 1, 0, 0, 0, 0) /* RFC2616 14.28 */
+HTTPH("Last-Modified", H_Last_Modified, 2, 0, 0, 0, 0) /* RFC2616 14.29 */
+HTTPH("Location", H_Location, 2, 0, 0, 0, 0) /* RFC2616 14.30 */
+HTTPH("Max-Forwards", H_Max_Forwards, 1, 0, 0, 0, 0) /* RFC2616 14.31 */
+HTTPH("Pragma", H_Pragma, 1, 0, 0, 0, 0) /* RFC2616 14.32 */
+HTTPH("Proxy-Authenticate", H_Proxy_Authenticate, 2, 0, 0, 0, 0) /* RFC2616 14.33 */
+HTTPH("Proxy-Authorization", H_Proxy_Authorization, 1, 0, 0, 0, 0) /* RFC2616 14.34 */
+HTTPH("Range", H_Range, 1, 0, 0, 0, 0) /* RFC2616 14.35 */
+HTTPH("Referer", H_Referer, 1, 0, 0, 0, 0) /* RFC2616 14.36 */
+HTTPH("Retry-After", H_Retry_After, 2, 0, 0, 0, 0) /* RFC2616 14.37 */
+HTTPH("Server", H_Server, 2, 0, 0, 0, 0) /* RFC2616 14.38 */
+HTTPH("TE", H_TE, 1, 0, 0, 0, 0) /* RFC2616 14.39 */
+HTTPH("Trailer", H_Trailer, 1, 0, 0, 0, 0) /* RFC2616 14.40 */
+HTTPH("Transfer-Encoding", H_Transfer_Encoding, 2, 0, 0, 0, 0) /* RFC2616 14.41 */
+HTTPH("Upgrade", H_Upgrade, 2, 0, 0, 0, 0) /* RFC2616 14.42 */
+HTTPH("User-Agent", H_User_Agent, 1, 0, 0, 0, 0) /* RFC2616 14.43 */
+HTTPH("Vary", H_Vary, 2, 0, 0, 0, 0) /* RFC2616 14.44 */
+HTTPH("Via", H_Via, 2, 0, 0, 0, 0) /* RFC2616 14.45 */
+HTTPH("Warning", H_Warning, 2, 0, 0, 0, 0) /* RFC2616 14.46 */
+HTTPH("WWW-Authenticate", H_WWW_Authenticate, 2, 0, 0, 0, 0) /* RFC2616 14.47 */
SLTM(SessionReuse)
SLTM(SessionClose)
SLTM(ClientAddr)
-SLTM(HandlingFetch)
-SLTM(HandlingPass)
-SLTM(HandlingPipe)
+SLTM(Handling)
SLTM(Request)
SLTM(Response)
SLTM(Status)
SLTM(URL)
SLTM(Protocol)
-SLTM(HD_Unknown)
-SLTM(HD_Lost)
-#define HTTPH(a, b, c, d, e, f, g) SLTM(b)
-#include "http_headers.h"
-#undef HTTPH
+SLTM(Header)
+SLTM(LostHeader)
+SLTM(VCL)
unsigned mask;
};
-#define VCA_RXBUFSIZE 1024
#define VCA_ADDRBUFSIZE 32
-#define VCA_UNKNOWNHDR 10
-
-struct httphdr {
- const char *req;
- const char *url;
- const char *proto;
- const char *status;
- const char *response;
-#define HTTPH(a, b, c, d, e, f, g) const char *b;
-#include <http_headers.h>
-#undef HTTPH
- const char *uhdr[VCA_UNKNOWNHDR];
- unsigned nuhdr;
-};
struct object {
unsigned char hash[16];
/* formatted ascii client address */
char addr[VCA_ADDRBUFSIZE];
- /* Receive buffer for HTTP header */
- char rcv[VCA_RXBUFSIZE + 1];
- unsigned rcv_len;
- unsigned rcv_ptr;
-
- /* HTTP request info, points into rcv */
- struct httphdr http;
+ /* HTTP request */
+ struct http *http;
enum {
HND_Unclass,
static struct var vars[] = {
- { "req.request", STRING, 0, "sess->http.req" },
+ { "req.request", STRING, 0, "\"GET\"" },
{ "obj.valid", BOOL, 0, "sess->obj->valid" },
{ "obj.cacheable", BOOL, 0, "sess->obj->cacheable" },
#if 0
fputs(" unsigned mask;\n", f);
fputs("};\n", f);
fputs("\n", f);
- fputs("#define VCA_RXBUFSIZE 1024\n", f);
fputs("#define VCA_ADDRBUFSIZE 32\n", f);
- fputs("#define VCA_UNKNOWNHDR 10\n", f);
- fputs("\n", f);
- fputs("struct httphdr {\n", f);
- fputs(" const char *req;\n", f);
- fputs(" const char *url;\n", f);
- fputs(" const char *proto;\n", f);
- fputs(" const char *status;\n", f);
- fputs(" const char *response;\n", f);
- fputs("#define HTTPH(a, b, c, d, e, f, g) const char *b;\n", f);
- fputs("/*\n", f);
- fputs(" * $Id$\n", f);
- fputs(" *\n", f);
- fputs(" * a Http header name\n", f);
- fputs(" * b session field name\n", f);
- fputs(" * c Request(1)/Response(2) bitfield\n", f);
- fputs(" * d Pass header\n", f);
- fputs(" * e unused\n", f);
- fputs(" * f unused\n", f);
- fputs(" * g unused\n", f);
- fputs(" *\n", f);
- fputs(" * a b c d e f g \n", f);
- fputs(" *--------------------------------------------------------------------\n", f);
- fputs(" */\n", f);
- fputs("HTTPH(\"Connection\", H_Connection, 3, 0, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Keep-Alive\", H_Keep_Alive, 3, 0, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Cache-Control\", H_Cache_Control, 3, 1, 0, 0, 0)\n", f);
- fputs("\n", f);
- fputs("HTTPH(\"Accept-Charset\", H_Accept_Charset, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Accept-Encoding\", H_Accept_Encoding, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Accept-Language\", H_Accept_Language, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Accept\", H_Accept, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Authorization\", H_Authorization, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Expect\", H_Expect, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"From\", H_From, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Host\", H_Host, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"If-Match\", H_If_Match, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"If-Modified-Since\", H_If_Modified_Since, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"If-None-Match\", H_If_None_Match, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"If-Range\", H_If_Range, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"If-Unmodified-Since\", H_If_Unmodifed_Since, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Max-Forwards\", H_Max_Forwards, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Proxy-Authorization\", H_Proxy_Authorization, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Range\", H_Range, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Referer\", H_Referer, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"TE\", H_TE, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"User-Agent\", H_User_Agent, 1, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Pragma\", H_Pragma, 1, 1, 0, 0, 0)\n", f);
- fputs("\n", f);
- fputs("HTTPH(\"Server\", H_Server, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Content-Type\", H_Content_Type, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Date\", H_Date, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Last-Modified\", H_Last_Modified, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Accept-Ranges\", H_Accept_Ranges, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Content-Length\", H_Content_Length, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Vary\", H_Vary, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Expires\", H_Expires, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Location\", H_Location, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"Content-Encoding\", H_Content_Encoding, 2, 1, 0, 0, 0)\n", f);
- fputs("HTTPH(\"ETag:\", H_ETag, 2, 1, 0, 0, 0)\n", f);
- fputs("\n", f);
- fputs("#undef HTTPH\n", f);
- fputs(" const char *uhdr[VCA_UNKNOWNHDR];\n", f);
- fputs(" unsigned nuhdr;\n", f);
- fputs("};\n", f);
fputs("\n", f);
fputs("struct object { \n", f);
fputs(" unsigned char hash[16];\n", f);
fputs(" /* formatted ascii client address */\n", f);
fputs(" char addr[VCA_ADDRBUFSIZE];\n", f);
fputs("\n", f);
- fputs(" /* Receive buffer for HTTP header */\n", f);
- fputs(" char rcv[VCA_RXBUFSIZE + 1];\n", f);
- fputs(" unsigned rcv_len;\n", f);
- fputs(" unsigned rcv_ptr;\n", f);
- fputs("\n", f);
- fputs(" /* HTTP request info, points into rcv */\n", f);
- fputs(" struct httphdr http;\n", f);
+ fputs(" /* HTTP request */\n", f);
+ fputs(" struct http *http;\n", f);
fputs("\n", f);
fputs(" enum {\n", f);
fputs(" HND_Unclass,\n", f);