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

A little step for humanity but a big step for varnish:

Implement pipe-through mode and see the first web-pages actually
pass through varnish.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@95 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 630ea75d
......@@ -10,6 +10,7 @@ varnishd_SOURCES = \
cache_httpd.c \
cache_main.c \
cache_pool.c \
cache_pipe.c \
cache_shmlog.c \
cache_vcl.c \
cli_event.c \
......
......@@ -4,9 +4,13 @@
/* cache_acceptor.c */
void *vca_main(void *arg);
void vca_retire_session(struct sess *sp);
/* cache_backend.c */
void VBE_Init(void);
int VBE_GetFd(struct backend *bp, void **ptr);
void VBE_Pass(struct sess *sp);
void VBE_ClosedFd(void *ptr);
/* cache_httpd.c */
void HttpdAnalyze(struct sess *sp);
......@@ -14,6 +18,9 @@ void HttpdAnalyze(struct sess *sp);
/* cache_main.c */
pthread_mutex_t sessmtx;
/* cache_pipe.c */
void PipeSession(struct sess *sp);
/* cache_pool.c */
void CacheInitPool(void);
void DealWithSession(struct sess *sp);
......
......@@ -137,3 +137,12 @@ vca_main(void *arg)
return ("FOOBAR");
}
void
vca_retire_session(struct sess *sp)
{
if (sp->fd >= 0)
close(sp->fd);
free(sp);
}
......@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sbuf.h>
#include "libvarnish.h"
#include "vcl_lang.h"
......@@ -86,7 +87,7 @@ connect_to_backend(struct vbe_conn *vc, struct backend *bp)
/*--------------------------------------------------------------------*/
int
VBE_GetFd(struct backend *bp)
VBE_GetFd(struct backend *bp, void **ptr)
{
struct vbe *vp;
struct vbe_conn *vc;
......@@ -113,20 +114,81 @@ VBE_GetFd(struct backend *bp)
TAILQ_REMOVE(&vp->fconn, vc, list);
TAILQ_INSERT_TAIL(&vp->bconn, vc, list);
AZ(pthread_mutex_unlock(&vbemtx));
return (vc->fd);
} else {
vc = calloc(sizeof *vc, 1);
assert(vc != NULL);
vc->vbe = vp;
vc->fd = -1;
TAILQ_INSERT_TAIL(&vp->bconn, vc, list);
AZ(pthread_mutex_unlock(&vbemtx));
connect_to_backend(vc, bp);
}
vc = calloc(sizeof *vc, 1);
assert(vc != NULL);
vc->vbe = vp;
vc->fd = -1;
TAILQ_INSERT_TAIL(&vp->bconn, vc, list);
*ptr = vc;
return (vc->fd);
}
void
VBE_ClosedFd(void *ptr)
{
struct vbe_conn *vc;
vc = ptr;
AZ(pthread_mutex_lock(&vbemtx));
TAILQ_REMOVE(&vc->vbe->bconn, vc, list);
AZ(pthread_mutex_unlock(&vbemtx));
connect_to_backend(vc, bp);
free(vc);
}
/*--------------------------------------------------------------------*/
void
VBE_Pass(struct sess *sp)
{
int fd, i;
void *fd_token;
struct sbuf *sb;
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
assert(sb != NULL);
sbuf_cat(sb, sp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, sp->url);
sbuf_cat(sb, " ");
sbuf_cat(sb, sp->proto);
sbuf_cat(sb, "\r\n");
#define HTTPH(a, b, c, d, e, f, g) \
do { \
if (c && sp->b != NULL) { \
sbuf_cat(sb, a ": "); \
sbuf_cat(sb, sp->b); \
sbuf_cat(sb, "\r\n"); \
} \
} while (0);
#include "http_headers.h"
#undef HTTPH
sbuf_cat(sb, "\r\n");
sbuf_finish(sb);
printf("REQ: <%s>\n", sbuf_data(sb));
i = write(fd, sbuf_data(sb), sbuf_len(sb));
assert(i == sbuf_len(sb));
{
char buf[101];
for(;;) {
i = read(fd, buf, 100);
if (i > 0) {
buf[i] = '\0';
printf("RESP: <%s>\n", buf);
}
}
/* XXX */
return (-1);
}
}
/*--------------------------------------------------------------------*/
void
VBE_Init(void)
{
......
......@@ -22,30 +22,30 @@ HttpdAnalyze(struct sess *sp)
sp->handling = HND_Unclass;
/* First, isolate and possibly identify request type */
sp->req_b = sp->rcv;
sp->req = sp->rcv;
for (p = sp->rcv; isalpha(*p); p++)
;
VSLR(SLT_Request, sp->fd, sp->req_b, p);
VSLR(SLT_Request, sp->fd, sp->req, p);
*p++ = '\0';
/* Next find the URI */
while (isspace(*p))
p++;
sp->url_b = p;
sp->url = p;
while (!isspace(*p))
p++;
VSLR(SLT_URL, sp->fd, sp->url_b, p);
VSLR(SLT_URL, sp->fd, sp->url, p);
*p++ = '\0';
/* Finally, look for protocol, if any */
while (isspace(*p) && *p != '\n')
p++;
sp->proto_b = p;
sp->proto = p;
if (*p != '\n') {
while (!isspace(*p))
p++;
}
VSLR(SLT_Protocol, sp->fd, sp->proto_b, p);
VSLR(SLT_Protocol, sp->fd, sp->proto, p);
*p++ = '\0';
while (isspace(*p) && *p != '\n')
......
/*
* $Id$
*/
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sbuf.h>
#include <event.h>
#include "libvarnish.h"
#include "vcl_lang.h"
#include "cache.h"
struct edir {
int fd;
struct event ev;
};
static void
rdf(int fd, short event, void *arg)
{
int i, j;
struct edir *ep;
char buf[BUFSIZ];
ep = arg;
i = read(fd, buf, sizeof buf);
if (i <= 0) {
shutdown(fd, SHUT_RD);
shutdown(ep->fd, SHUT_WR);
event_del(&ep->ev);
} else {
j = write(ep->fd, buf, i);
assert(i == j);
}
}
void
PipeSession(struct sess *sp)
{
int fd, i;
void *fd_token;
struct sbuf *sb;
struct event_base *eb;
struct edir e1, e2;
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
assert(sb != NULL);
sbuf_cat(sb, sp->req);
sbuf_cat(sb, " ");
sbuf_cat(sb, sp->url);
if (sp->proto != NULL) {
sbuf_cat(sb, " ");
sbuf_cat(sb, sp->proto);
}
sbuf_cat(sb, "\r\n");
#define HTTPH(a, b, c, d, e, f, g) \
do { \
if (sp->b != NULL) { \
sbuf_cat(sb, a ": "); \
sbuf_cat(sb, sp->b); \
sbuf_cat(sb, "\r\n"); \
} \
} while (0);
#include "http_headers.h"
#undef HTTPH
sbuf_cat(sb, "\r\n");
sbuf_finish(sb);
printf("REQ: <%s>\n", sbuf_data(sb));
i = write(fd, sbuf_data(sb), sbuf_len(sb));
assert(i == sbuf_len(sb));
e1.fd = fd;
e2.fd = sp->fd;
eb = event_init();
event_set(&e1.ev, sp->fd, EV_READ | EV_PERSIST, rdf, &e1);
event_base_set(eb, &e1.ev);
event_set(&e2.ev, fd, EV_READ | EV_PERSIST, rdf, &e2);
event_base_set(eb, &e2.ev);
event_add(&e1.ev, NULL);
event_add(&e2.ev, NULL);
event_base_loop(eb, 0);
close (fd);
close (sp->fd);
/* XXX: Delete eb */
VBE_ClosedFd(fd_token);
sp->fd = -1;
}
......@@ -39,10 +39,12 @@ CacheWorker(void *priv __unused)
printf("Handling: %d\n", sp->handling);
PipeSession(sp);
AZ(pthread_mutex_lock(&sessmtx));
RelVCL(sp->vcl);
sp->vcl = NULL;
/* XXX send session to acceptor for reuse/disposal */
vca_retire_session(sp);
}
}
......
/*
* $Id$
*
* a Http header name
* b session field name
* c PassThrough handling (0=remove, 1=pass)
* d unused
* e unused
* f unused
* g unused
*
* a b c d e f g
*--------------------------------------------------------------------
*/
HTTPH("Accept-Charset", H_Accept_Charset, 0, 0, 0, 0, 0)
HTTPH("Accept-Encoding", H_Accept_Encoding, 0, 0, 0, 0, 0)
HTTPH("Accept-Language", H_Accept_Language, 0, 0, 0, 0, 0)
HTTPH("Accept", H_Accept, 0, 0, 0, 0, 0)
HTTPH("Authorization", H_Authorization, 0, 0, 0, 0, 0)
HTTPH("Connection", H_Connection, 0, 0, 0, 0, 0)
HTTPH("Connection", H_Connection, 1, 0, 0, 0, 0)
HTTPH("Expect", H_Expect, 0, 0, 0, 0, 0)
HTTPH("From", H_From, 0, 0, 0, 0, 0)
HTTPH("Host", H_Host, 0, 0, 0, 0, 0)
HTTPH("Host", H_Host, 1, 0, 0, 0, 0)
HTTPH("If-Match", H_If_Match, 0, 0, 0, 0, 0)
HTTPH("If-Modified-Since", H_If_Modified_Since, 0, 0, 0, 0, 0)
HTTPH("If-None-Match", H_If_None_Match, 0, 0, 0, 0, 0)
......@@ -22,4 +32,4 @@ HTTPH("Proxy-Authorization", H_Proxy_Authorization, 0, 0, 0, 0, 0)
HTTPH("Range", H_Range, 0, 0, 0, 0, 0)
HTTPH("Referer", H_Referer, 0, 0, 0, 0, 0)
HTTPH("TE", H_TE, 0, 0, 0, 0, 0)
HTTPH("User-Agent", H_User_Agent, 0, 0, 0, 0, 0)
HTTPH("User-Agent", H_User_Agent, 1, 0, 0, 0, 0)
......@@ -34,9 +34,9 @@ struct sess {
unsigned rcv_len;
/* HTTP request info, points into rcv */
const char *req_b;
const char *url_b;
const char *proto_b;
const char *req;
const char *url;
const char *proto;
#define HTTPH(a, b, c, d, e, f, g) const char *b;
#include <http_headers.h>
#undef HTTPH
......@@ -44,7 +44,8 @@ struct sess {
enum {
HND_Unclass,
HND_Handle,
HND_Pass
HND_Pass,
HND_Pipe
} handling;
char done;
......
......@@ -415,23 +415,33 @@ vcl_output_lang_h(FILE *f)
fputs(" unsigned rcv_len;\n", f);
fputs("\n", f);
fputs(" /* HTTP request info, points into rcv */\n", f);
fputs(" const char *req_b;\n", f);
fputs(" const char *url_b;\n", f);
fputs(" const char *proto_b;\n", f);
fputs(" const char *req;\n", f);
fputs(" const char *url;\n", f);
fputs(" const char *proto;\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 PassThrough handling (0=remove, 1=pass)\n", f);
fputs(" * d unused\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("\n", f);
fputs("HTTPH(\"Accept-Charset\", H_Accept_Charset, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Accept-Encoding\", H_Accept_Encoding, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Accept-Language\", H_Accept_Language, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Accept\", H_Accept, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Authorization\", H_Authorization, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Connection\", H_Connection, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Connection\", H_Connection, 1, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Expect\", H_Expect, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"From\", H_From, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Host\", H_Host, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Host\", H_Host, 1, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"If-Match\", H_If_Match, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"If-Modified-Since\", H_If_Modified_Since, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"If-None-Match\", H_If_None_Match, 0, 0, 0, 0, 0)\n", f);
......@@ -443,13 +453,14 @@ vcl_output_lang_h(FILE *f)
fputs("HTTPH(\"Range\", H_Range, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Referer\", H_Referer, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"TE\", H_TE, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"User-Agent\", H_User_Agent, 0, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"User-Agent\", H_User_Agent, 1, 0, 0, 0, 0)\n", f);
fputs("#undef HTTPH\n", f);
fputs("\n", f);
fputs(" enum {\n", f);
fputs(" HND_Unclass,\n", f);
fputs(" HND_Handle,\n", f);
fputs(" HND_Pass\n", f);
fputs(" HND_Pass,\n", f);
fputs(" HND_Pipe\n", f);
fputs(" } handling;\n", f);
fputs("\n", f);
fputs(" char done;\n", f);
......
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