Commit 33ec113b authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Get pass-through working for the first request.

Now we can start to play with multi-request sessions and all that.



git-svn-id: http://www.varnish-cache.org/svn/trunk@112 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent b73e2289
......@@ -36,7 +36,7 @@ void VSL_Init(void);
#ifdef SHMLOGHEAD_MAGIC
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, "%s(%d)", __func__, __LINE__)
#define HERE() VSL(SLT_Debug, 0, "HERE: %s(%d)", __func__, __LINE__)
#endif
/* cache_vcl.c */
......
......@@ -163,6 +163,8 @@ http_read_f(int fd, short event, void *arg)
continue;
break;
}
sp->hdr_end = p - sp->rcv;
VSL(SLT_Debug, 0, "HTTP %u %u", sp->rcv_len, sp->hdr_end);
event_del(sp->rd_e);
sp->sesscb(sp);
}
......
......@@ -4,9 +4,11 @@
#include <assert.h>
#include <stdio.h>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/queue.h>
#include <sys/types.h>
......@@ -24,7 +26,6 @@ static void
PassReturn(struct sess *sp)
{
HERE();
HttpdAnalyze(sp, 2);
}
......@@ -32,12 +33,14 @@ PassReturn(struct sess *sp)
void
PassSession(struct sess *sp)
{
int fd, i;
int fd, i, j;
void *fd_token;
struct sbuf *sb;
struct event_base *eb;
struct sess sp2;
struct event ev;
char buf[BUFSIZ];
off_t cl;
fd = VBE_GetFd(sp->backend, &fd_token);
assert(fd != -1);
......@@ -72,4 +75,56 @@ PassSession(struct sess *sp)
eb = event_init();
HttpdGetHead(&sp2, eb, PassReturn);
event_base_loop(eb, 0);
sbuf_clear(sb);
sbuf_cat(sb, sp2.http.proto);
sbuf_cat(sb, " ");
sbuf_cat(sb, sp2.http.status);
sbuf_cat(sb, " ");
sbuf_cat(sb, sp2.http.response);
sbuf_cat(sb, "\r\n");
#define HTTPH(a, b, c, d, e, f, g) \
do { \
if (d && sp2.http.b != NULL) { \
sbuf_cat(sb, a ": "); \
sbuf_cat(sb, sp2.http.b); \
sbuf_cat(sb, "\r\n"); \
} \
} while (0);
#include "http_headers.h"
#undef HTTPH
sbuf_cat(sb, "\r\n");
sbuf_finish(sb);
i = write(sp->fd, sbuf_data(sb), sbuf_len(sb));
assert(i == sbuf_len(sb));
if (sp2.http.H_Content_Length != NULL) {
cl = strtoumax(sp2.http.H_Content_Length, NULL, 0);
VSL(SLT_Debug, 0, "CL %ju %u %u", cl, sp->rcv_len, sp->hdr_end);
i = fcntl(sp2.fd, F_GETFL);
i &= ~O_NONBLOCK;
i = fcntl(sp2.fd, F_SETFL, i);
assert(i != -1);
i = sp2.rcv_len - sp2.hdr_end;
if (i > 0) {
VSL(SLT_Debug, 0, "Wr1 %d", i);
j = write(sp->fd, sp2.rcv + sp2.hdr_end, i);
assert(j == i);
cl -= 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) {
VSL(SLT_Debug, 0, "Rd %d", i);
cl -= i;
j = write(sp->fd, buf, i);
assert(j == i);
} else if (i == 0) {
VSL(SLT_Debug, 0, "EOF %d", i);
break;
}
}
}
}
......@@ -78,8 +78,10 @@ main(int argc, char **argv)
while (1) {
if (*p == SLT_WRAPMARKER)
break;
while (*p == SLT_ENDMARKER)
while (*p == SLT_ENDMARKER) {
fflush(stdout);
sleep(1);
}
printf("%02x %02d %02x%02x %-12s <",
p[0], p[1], p[2], p[3],
tagnames[p[0]]);
......@@ -90,251 +92,3 @@ main(int argc, char **argv)
}
}
}
#if 0
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <event.h>
#include <sbuf.h>
#include <cli.h>
#include <cli_priv.h>
#include <libvarnish.h>
#include "mgt.h"
#include "heritage.h"
#include "cli_event.h"
/*--------------------------------------------------------------------*/
struct heritage heritage;
struct event_base *eb;
/*--------------------------------------------------------------------
* Generic passthrough for CLI functions
*/
void
cli_passthrough_cb(unsigned u, const char *r, void *priv)
{
struct cli *cli = priv;
cli_out(cli, "%s\n", r);
cli_result(cli, u);
cli_resume(cli);
}
static void
cli_func_passthrough(struct cli *cli, char **av __unused, void *priv)
{
cli_suspend(cli);
mgt_child_request(cli_passthrough_cb, cli, &av[2], av[1]);
}
/*--------------------------------------------------------------------*/
static void
cli_func_server_start(struct cli *cli, char **av __unused, void *priv __unused)
{
mgt_child_start();
}
/*--------------------------------------------------------------------*/
static void
cli_func_server_stop(struct cli *cli, char **av __unused, void *priv __unused)
{
mgt_child_stop();
}
/*--------------------------------------------------------------------*/
static void
cli_func_verbose(struct cli *cli, char **av __unused, void *priv)
{
cli->verbose = !cli->verbose;
}
static void
cli_func_ping(struct cli *cli, char **av, void *priv __unused)
{
time_t t;
if (av[2] != NULL) {
cli_out(cli, "Got your %s\n", av[2]);
}
time(&t);
cli_out(cli, "PONG %ld\n", t);
}
/*--------------------------------------------------------------------*/
static struct cli_proto cli_proto[] = {
/* URL manipulation */
{ CLI_URL_QUERY, cli_func_passthrough, NULL },
{ CLI_URL_PURGE, cli_func_passthrough, NULL },
{ CLI_URL_STATUS, cli_func_passthrough, NULL },
{ CLI_CONFIG_LOAD },
{ CLI_CONFIG_INLINE },
{ CLI_CONFIG_UNLOAD },
{ CLI_CONFIG_LIST },
{ CLI_CONFIG_USE },
{ CLI_SERVER_FREEZE, cli_func_passthrough, NULL },
{ CLI_SERVER_THAW, cli_func_passthrough, NULL },
{ CLI_SERVER_SUSPEND, cli_func_passthrough, NULL },
{ CLI_SERVER_RESUME, cli_func_passthrough, NULL },
{ CLI_SERVER_STOP, cli_func_server_stop, NULL },
{ CLI_SERVER_START, cli_func_server_start, NULL },
{ CLI_SERVER_RESTART },
{ CLI_PING, cli_func_ping, NULL },
{ CLI_STATS },
{ CLI_ZERO },
{ CLI_HELP, cli_func_help, cli_proto },
{ CLI_VERBOSE, cli_func_verbose, NULL },
{ CLI_EXIT },
{ CLI_QUIT },
{ CLI_BYE },
{ NULL }
};
static void
testme(void)
{
struct event e_sigchld;
struct cli *cli;
int i;
eb = event_init();
assert(eb != NULL);
cli = cli_setup(0, 1, 1, cli_proto);
signal_set(&e_sigchld, SIGCHLD, mgt_sigchld, NULL);
signal_add(&e_sigchld, NULL);
i = event_dispatch();
if (i != 0)
printf("event_dispatch() = %d\n", i);
}
/*--------------------------------------------------------------------*/
static void
usage(void)
{
fprintf(stderr, "usage: varnishd [options]\n");
fprintf(stderr, " %-20s # %s\n", "-d", "debug");
fprintf(stderr, " %-20s # %s\n", "-p number", "TCP listen port");
#if 0
-c clusterid@cluster_controller
-f config_file
-m memory_limit
-s kind[,storage-options]
-l logfile,logsize
-b backend ip...
-u uid
-a CLI_port
#endif
exit(1);
}
/*--------------------------------------------------------------------*/
#include "shmlog.h"
static void
init_vsl(const char *fn, unsigned size)
{
struct shmloghead slh;
int i;
heritage.vsl_fd = open(fn, O_RDWR | O_CREAT, 0600);
if (heritage.vsl_fd < 0) {
fprintf(stderr, "Could not open %s: %s\n",
fn, strerror(errno));
exit (1);
}
i = read(heritage.vsl_fd, &slh, sizeof slh);
if (i == sizeof slh && slh.magic == SHMLOGHEAD_MAGIC) {
/* XXX more checks */
heritage.vsl_size = slh.size + slh.start;
return;
}
slh.magic = SHMLOGHEAD_MAGIC;
slh.size = size;
slh.ptr = 0;
slh.start = sizeof slh;
AZ(lseek(heritage.vsl_fd, 0, SEEK_SET));
i = write(heritage.vsl_fd, &slh, sizeof slh);
assert(i == sizeof slh);
AZ(ftruncate(heritage.vsl_fd, sizeof slh + size));
heritage.vsl_size = slh.size + slh.start;
}
/*--------------------------------------------------------------------*/
/* for development purposes */
#include <printf.h>
int
main(int argc, char *argv[])
{
int o;
const char *portnumber = "8080";
unsigned dflag = 1; /* XXX: debug=on for now */
register_printf_render_std((const unsigned char *)"HVQ");
while ((o = getopt(argc, argv, "dp:")) != -1)
switch (o) {
case 'd':
dflag++;
break;
case 'p':
portnumber = optarg;
break;
default:
usage();
}
argc -= optind;
argv += optind;
if (argc != 0)
usage();
/*
* XXX: Lacking the suspend/resume facility (due to the socket API
* missing an unlisten(2) facility) we may want to push this into
* the child to limit the amount of time where the socket(s) exists
* but do not answer. That, on the other hand, would eliminate the
* possibility of doing a "no-glitch" restart of the child process.
*/
open_tcp(portnumber);
init_vsl(SHMLOG_FILENAME, 1024*1024);
testme();
exit(0);
}
#endif
......@@ -14,6 +14,7 @@
*/
HTTPH("Connection", H_Connection, 3, 0, 0, 0, 0)
HTTPH("Keep-Alive", H_Keep_Alive, 3, 0, 0, 0, 0)
HTTPH("Cache-Control", H_Cache_Control, 3, 1, 0, 0, 0)
HTTPH("Accept-Charset", H_Accept_Charset, 1, 1, 0, 0, 0)
HTTPH("Accept-Encoding", H_Accept_Encoding, 1, 1, 0, 0, 0)
......@@ -34,13 +35,14 @@ HTTPH("Range", H_Range, 1, 1, 0, 0, 0)
HTTPH("Referer", H_Referer, 1, 1, 0, 0, 0)
HTTPH("TE", H_TE, 1, 1, 0, 0, 0)
HTTPH("User-Agent", H_User_Agent, 1, 1, 0, 0, 0)
HTTPH("Pragma", H_Pragma, 1, 1, 0, 0, 0)
HTTPH("Server", H_Server, 2, 0, 0, 0, 0)
HTTPH("Content-Type", H_Content_Type, 2, 0, 0, 0, 0)
HTTPH("Date", H_Date, 2, 0, 0, 0, 0)
HTTPH("Last-Modified", H_Last_Modified, 2, 0, 0, 0, 0)
HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 0, 0, 0, 0)
HTTPH("Content-Length", H_Content_Length, 2, 0, 0, 0, 0)
HTTPH("Cache-Control", H_Cache_Control, 2, 0, 0, 0, 0)
HTTPH("Vary", H_Vary, 2, 0, 0, 0, 0)
HTTPH("Expires", H_Expires, 2, 0, 0, 0, 0)
HTTPH("Server", H_Server, 2, 1, 0, 0, 0)
HTTPH("Content-Type", H_Content_Type, 2, 1, 0, 0, 0)
HTTPH("Date", H_Date, 2, 1, 0, 0, 0)
HTTPH("Last-Modified", H_Last_Modified, 2, 1, 0, 0, 0)
HTTPH("Accept-Ranges", H_Accept_Ranges, 2, 1, 0, 0, 0)
HTTPH("Content-Length", H_Content_Length, 2, 1, 0, 0, 0)
HTTPH("Vary", H_Vary, 2, 1, 0, 0, 0)
HTTPH("Expires", H_Expires, 2, 1, 0, 0, 0)
HTTPH("Location", H_Location, 2, 1, 0, 0, 0)
......@@ -49,6 +49,7 @@ struct sess {
/* Receive buffer for HTTP header */
char rcv[VCA_RXBUFSIZE + 1];
unsigned rcv_len;
unsigned hdr_end;
/* HTTP request info, points into rcv */
struct httphdr http;
......
......@@ -431,6 +431,7 @@ vcl_output_lang_h(FILE *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);
......@@ -451,16 +452,17 @@ vcl_output_lang_h(FILE *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, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Content-Type\", H_Content_Type, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Date\", H_Date, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Last-Modified\", H_Last_Modified, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Accept-Ranges\", H_Accept_Ranges, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Content-Length\", H_Content_Length, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Cache-Control\", H_Cache_Control, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Vary\", H_Vary, 2, 0, 0, 0, 0)\n", f);
fputs("HTTPH(\"Expires\", H_Expires, 2, 0, 0, 0, 0)\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("#undef HTTPH\n", f);
fputs(" const char *uhdr[VCA_UNKNOWNHDR];\n", f);
fputs(" unsigned nuhdr;\n", f);
......@@ -475,6 +477,7 @@ vcl_output_lang_h(FILE *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 hdr_end;\n", f);
fputs("\n", f);
fputs(" /* HTTP request info, points into rcv */\n", f);
fputs(" struct httphdr http;\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