Index: include/vsb.h =================================================================== --- include/vsb.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/vsb.h (.../branches/2.0/varnish-cache) @@ -77,7 +77,8 @@ int vsb_len(struct vsb *); int vsb_done(const struct vsb *); void vsb_delete(struct vsb *); -void vsb_quote(struct vsb *s, const char *p, int how); +void vsb_quote(struct vsb *s, const char *p, int len, int how); +const char *vsb_unquote(struct vsb *s, const char *p, int len, int how); #ifdef __cplusplus }; #endif Index: include/compat/execinfo.h =================================================================== --- include/compat/execinfo.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/compat/execinfo.h (.../branches/2.0/varnish-cache) @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2003 Maxim Sobolev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifndef COMPAT_EXECINFO_H_INCLUDED +#define COMPAT_EXECINFO_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +int backtrace(void **, int); +char ** backtrace_symbols(void *const *, int); +void backtrace_symbols_fd(void *const *, int, int); + +#ifdef __cplusplus +} +#endif + +#endif /* COMPAT_EXECINFO_H_INCLUDED */ Index: include/libvarnish.h =================================================================== --- include/libvarnish.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/libvarnish.h (.../branches/2.0/varnish-cache) @@ -42,6 +42,8 @@ /* from libvarnish/argv.c */ void FreeArgv(char **argv); char **ParseArgv(const char *s, int flag); +char *BackSlashDecode(const char *s, const char *e); +int BackSlash(const char *s, char *res); #define ARGV_COMMENT (1 << 0) #define ARGV_COMMA (1 << 1) @@ -65,6 +67,7 @@ int TCP_filter_http(int sock); void TCP_blocking(int sock); void TCP_nonblocking(int sock); +void TCP_linger(int sock, int linger); #ifdef SOL_SOCKET void TCP_name(const struct sockaddr *addr, unsigned l, char *abuf, unsigned alen, char *pbuf, unsigned plen); Index: include/vrt_obj.h =================================================================== --- include/vrt_obj.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/vrt_obj.h (.../branches/2.0/varnish-cache) @@ -24,6 +24,8 @@ double VRT_r_req_grace(struct sess *); void VRT_l_req_grace(struct sess *, double); const char * VRT_r_req_xid(struct sess *); +unsigned VRT_r_req_esi(struct sess *); +void VRT_l_req_esi(struct sess *, unsigned); const char * VRT_r_bereq_request(const struct sess *); void VRT_l_bereq_request(const struct sess *, const char *, ...); const char * VRT_r_bereq_url(const struct sess *); Index: include/shmlog_tags.h =================================================================== --- include/shmlog_tags.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/shmlog_tags.h (.../branches/2.0/varnish-cache) @@ -101,3 +101,5 @@ SLTM(Hash) SLTM(Backend_health) + +SLTM(FetchError) Index: include/vrt.h =================================================================== --- include/vrt.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/vrt.h (.../branches/2.0/varnish-cache) @@ -54,6 +54,7 @@ double interval; unsigned window; unsigned threshold; + unsigned initial; }; /* Index: include/stat_field.h =================================================================== --- include/stat_field.h (.../tags/varnish-2.0.4/varnish-cache) +++ include/stat_field.h (.../branches/2.0/varnish-cache) @@ -30,21 +30,33 @@ */ MAC_STAT(client_conn, uint64_t, 'a', "Client connections accepted") +MAC_STAT(client_drop, uint64_t, 'a', "Connection dropped, no sess") MAC_STAT(client_req, uint64_t, 'a', "Client requests received") MAC_STAT(cache_hit, uint64_t, 'a', "Cache hits") MAC_STAT(cache_hitpass, uint64_t, 'a', "Cache hits for pass") MAC_STAT(cache_miss, uint64_t, 'a', "Cache misses") -MAC_STAT(backend_conn, uint64_t, 'a', "Backend connections success") -MAC_STAT(backend_unhealthy, uint64_t, 'a', - "Backend connections not attempted") -MAC_STAT(backend_busy, uint64_t, 'a', "Backend connections too many") -MAC_STAT(backend_fail, uint64_t, 'a', "Backend connections failures") -MAC_STAT(backend_reuse, uint64_t, 'a', "Backend connections reuses") -MAC_STAT(backend_recycle, uint64_t, 'a', "Backend connections recycles") -MAC_STAT(backend_unused, uint64_t, 'a', "Backend connections unused") +MAC_STAT(backend_conn, uint64_t, 'a', "Backend conn. success") +MAC_STAT(backend_unhealthy, uint64_t, 'a', "Backend conn. not attempted") +MAC_STAT(backend_busy, uint64_t, 'a', "Backend conn. too many") +MAC_STAT(backend_fail, uint64_t, 'a', "Backend conn. failures") +MAC_STAT(backend_reuse, uint64_t, 'a', "Backend conn. reuses") +MAC_STAT(backend_toolate, uint64_t, 'a', "Backend conn. was closed") +MAC_STAT(backend_recycle, uint64_t, 'a', "Backend conn. recycles") +MAC_STAT(backend_unused, uint64_t, 'a', "Backend conn. unused") + +MAC_STAT(fetch_head, uint64_t, 'a', "Fetch head") +MAC_STAT(fetch_length, uint64_t, 'a', "Fetch with Length") +MAC_STAT(fetch_chunked, uint64_t, 'a', "Fetch chunked") +MAC_STAT(fetch_eof, uint64_t, 'a', "Fetch EOF") +MAC_STAT(fetch_bad, uint64_t, 'a', "Fetch had bad headers") +MAC_STAT(fetch_close, uint64_t, 'a', "Fetch wanted close") +MAC_STAT(fetch_oldhttp, uint64_t, 'a', "Fetch pre HTTP/1.1 closed") +MAC_STAT(fetch_zero, uint64_t, 'a', "Fetch zero len") +MAC_STAT(fetch_failed, uint64_t, 'a', "Fetch failed") + MAC_STAT(n_srcaddr, uint64_t, 'i', "N struct srcaddr") MAC_STAT(n_srcaddr_act, uint64_t, 'i', "N active struct srcaddr") MAC_STAT(n_sess_mem, uint64_t, 'i', "N struct sess_mem") Index: include/Makefile.am =================================================================== --- include/Makefile.am (.../tags/varnish-2.0.4/varnish-cache) +++ include/Makefile.am (.../branches/2.0/varnish-cache) @@ -14,6 +14,7 @@ cli_priv.h \ compat/asprintf.h \ compat/daemon.h \ + compat/execinfo.h \ compat/setproctitle.h \ compat/srandomdev.h \ compat/strlcat.h \ Index: configure.ac =================================================================== --- configure.ac (.../tags/varnish-2.0.4/varnish-cache) +++ configure.ac (.../branches/2.0/varnish-cache) @@ -81,6 +81,7 @@ AC_CHECK_HEADERS([sys/statvfs.h]) AC_CHECK_HEADERS([sys/vfs.h]) AC_CHECK_HEADERS([endian.h]) +AC_CHECK_HEADERS([execinfo.h]) AC_CHECK_HEADERS([netinet/in.h]) AC_CHECK_HEADERS([pthread_np.h]) AC_CHECK_HEADERS([stddef.h]) @@ -102,6 +103,7 @@ AC_FUNC_VPRINTF AC_CHECK_FUNCS([strerror]) AC_FUNC_STRERROR_R +AC_CHECK_FUNCS([dladdr]) AC_CHECK_FUNCS([socket]) AC_CHECK_FUNCS([strptime]) AC_CHECK_FUNCS([fmtcheck]) @@ -360,6 +362,15 @@ fi AC_DEFINE_UNQUOTED([VCC_CC],"$VCC_CC",[C compiler command line for VCL code]) +# Define HTTP_HDR_MAX_VAL +AC_ARG_WITH(max-header-fields, + AS_HELP_STRING([--with-max-header-fields=NUM], + [How many header fields to support (default=32)]), + [], + [with_max_header_fields=32]) + +AC_DEFINE_UNQUOTED(HTTP_HDR_MAX_VAL, $with_max_header_fields, [Define maximum number of header fields supported by varnish ]) + # Use jemalloc on Linux JEMALLOC_SUBDIR= JEMALLOC_LDADD= Index: lib/libvarnish/argv.c =================================================================== --- lib/libvarnish/argv.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnish/argv.c (.../branches/2.0/varnish-cache) @@ -43,11 +43,12 @@ #include #include #include +#include #include #include "libvarnish.h" -static int +int BackSlash(const char *s, char *res) { int r; @@ -103,13 +104,16 @@ return (r); } -static char * +char * BackSlashDecode(const char *s, const char *e) { const char *q; char *p, *r; int i; + if (e == NULL) + e = strchr(s, '\0'); + assert(e != NULL); p = calloc((e - s) + 1, 1); if (p == NULL) return (p); Index: lib/libvarnish/cli_common.c =================================================================== --- lib/libvarnish/cli_common.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnish/cli_common.c (.../branches/2.0/varnish-cache) @@ -73,7 +73,7 @@ cli_quote(struct cli *cli, const char *s) { - vsb_quote(cli->sb, s, 0); + vsb_quote(cli->sb, s, -1, 0); } void Index: lib/libvarnish/tcp.c =================================================================== --- lib/libvarnish/tcp.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnish/tcp.c (.../branches/2.0/varnish-cache) @@ -36,6 +36,10 @@ #include +#ifdef __linux +#include +#endif + #include #include #ifdef HAVE_SYS_FILIO_H @@ -113,6 +117,10 @@ printf("Acceptfilter(%d, httpready): %d %s\n", sock, i, strerror(errno)); return (i); +#elif defined(__linux) + int defer = 1; + setsockopt(sock, SOL_TCP,TCP_DEFER_ACCEPT,(char *) &defer, sizeof(int)); + return (0); #else (void)sock; return (0); @@ -222,3 +230,17 @@ AZ(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)); #endif } + +/*-------------------------------------------------------------------- + * Set or reset SO_LINGER flag + */ + +void +TCP_linger(int sock, int linger) +{ + struct linger lin; + + memset(&lin, 0, sizeof lin); + lin.l_onoff = linger; + AZ(setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof lin)); +} Index: lib/libvarnish/vsb.c =================================================================== --- lib/libvarnish/vsb.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnish/vsb.c (.../branches/2.0/varnish-cache) @@ -481,25 +481,27 @@ * Quote a string */ void -vsb_quote(struct vsb *s, const char *p, int how) +vsb_quote(struct vsb *s, const char *p, int len, int how) { const char *q; int quote = 0; (void)how; /* For future enhancements */ + if (len == -1) + len = strlen(p); - for (q = p; *q != '\0'; q++) { + for (q = p; q < p + len; q++) { if (!isgraph(*q) || *q == '"') { quote++; break; } } if (!quote) { - (void)vsb_cat(s, p); + (void)vsb_bcat(s, p, len); return; } (void)vsb_putc(s, '"'); - for (q = p; *q != '\0'; q++) { + for (q = p; q < p + len; q++) { switch (*q) { case ' ': (void)vsb_putc(s, *q); @@ -522,9 +524,66 @@ if (isgraph(*q)) (void)vsb_putc(s, *q); else - (void)vsb_printf(s, "\\%o", *q); + (void)vsb_printf(s, "\\%o", *q & 0xff); break; } } (void)vsb_putc(s, '"'); } + +/* + * Unquote a string + */ +const char * +vsb_unquote(struct vsb *s, const char *p, int len, int how) +{ + const char *q; + char *r; + unsigned long u; + char c; + + (void)how; /* For future enhancements */ + + if (len == -1) + len = strlen(p); + + for (q = p; q < p + len; q++) { + if (*q != '\\') { + (void)vsb_bcat(s, q, 1); + continue; + } + if (++q >= p + len) + return ("Incomplete '\\'-sequence at end of string"); + + switch(*q) { + case 'n': + (void)vsb_bcat(s, "\n", 1); + continue; + case 'r': + (void)vsb_bcat(s, "\r", 1); + continue; + case 't': + (void)vsb_bcat(s, "\t", 1); + continue; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + errno = 0; + u = strtoul(q, &r, 8); + if (errno != 0 || (u & ~0xff)) + return ("\\ooo sequence out of range"); + c = (char)u; + (void)vsb_bcat(s, &c, 1); + q = r - 1; + continue; + default: + (void)vsb_bcat(s, q, 1); + } + } + return (NULL); +} Index: lib/libvarnishcompat/execinfo.c =================================================================== --- lib/libvarnishcompat/execinfo.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnishcompat/execinfo.c (.../branches/2.0/varnish-cache) @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2003 Maxim Sobolev + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "execinfo.h" + +void *getreturnaddr(int); +void *getframeaddr(int); + +#define D10(x) ceil(log10(((x) == 0) ? 2 : ((x) + 1))) + +inline static void * +realloc_safe(void *ptr, size_t size) +{ + void *nptr; + + nptr = realloc(ptr, size); + if (nptr == NULL) + free(ptr); + return nptr; +} + +int +backtrace(void **buffer, int size) +{ + int i; + + for (i = 1; getframeaddr(i + 1) != NULL && i != size + 1; i++) { + buffer[i - 1] = getreturnaddr(i); + if (buffer[i - 1] == NULL) + break; + } + + return i - 1; +} + +char ** +backtrace_symbols(void *const *buffer, int size) +{ + size_t clen, alen; + int i; + char **rval; + + clen = size * sizeof(char *); + rval = malloc(clen); + if (rval == NULL) + return NULL; + for (i = 0; i < size; i++) { + +#ifdef HAVE_DLADDR + { + Dl_info info; + int offset; + + if (dladdr(buffer[i], &info) != 0) { + if (info.dli_sname == NULL) + info.dli_sname = "???"; + if (info.dli_saddr == NULL) + info.dli_saddr = buffer[i]; + offset = (const char*)buffer[i] - (const char*)info.dli_saddr; + /* "0x01234567 at filename" */ + alen = 2 + /* "0x" */ + (sizeof(void *) * 2) + /* "01234567" */ + 2 + /* " <" */ + strlen(info.dli_sname) + /* "function" */ + 1 + /* "+" */ + 10 + /* "offset */ + 5 + /* "> at " */ + strlen(info.dli_fname) + /* "filename" */ + 1; /* "\0" */ + rval = realloc_safe(rval, clen + alen); + if (rval == NULL) + return NULL; + snprintf((char *) rval + clen, alen, "%p <%s+%d> at %s", + buffer[i], info.dli_sname, offset, info.dli_fname); + rval[i] = (char *) clen; + clen += alen; + continue; + } + } +#endif + alen = 2 + /* "0x" */ + (sizeof(void *) * 2) + /* "01234567" */ + 1; /* "\0" */ + rval = realloc_safe(rval, clen + alen); + if (rval == NULL) + return NULL; + snprintf((char *) rval + clen, alen, "%p", buffer[i]); + rval[i] = (char *) clen; + clen += alen; + } + + for (i = 0; i < size; i++) + rval[i] += (long) rval; + + return rval; +} + +#if 0 +void +backtrace_symbols_fd(void *const *buffer, int size, int fd) +{ + int i, len, offset; + char *buf; + Dl_info info; + + for (i = 0; i < size; i++) { + if (dladdr(buffer[i], &info) != 0) { + if (info.dli_sname == NULL) + info.dli_sname = "???"; + if (info.dli_saddr == NULL) + info.dli_saddr = buffer[i]; + offset = (const char *)buffer[i] - (const char *)info.dli_saddr; + /* "0x01234567 at filename" */ + len = 2 + /* "0x" */ + (sizeof(void *) * 2) + /* "01234567" */ + 2 + /* " <" */ + strlen(info.dli_sname) + /* "function" */ + 1 + /* "+" */ + D10(offset) + /* "offset */ + 5 + /* "> at " */ + strlen(info.dli_fname) + /* "filename" */ + 2; /* "\n\0" */ + buf = alloca(len); + if (buf == NULL) + return; + snprintf(buf, len, "%p <%s+%d> at %s\n", + buffer[i], info.dli_sname, offset, info.dli_fname); + } else { + len = 2 + /* "0x" */ + (sizeof(void *) * 2) + /* "01234567" */ + 2; /* "\n\0" */ + buf = alloca(len); + if (buf == NULL) + return; + snprintf(buf, len, "%p\n", buffer[i]); + } + write(fd, buf, len - 1); + } +} +#endif + +void * +getreturnaddr(int level) +{ + + switch(level) { + case 0: return __builtin_return_address(1); + case 1: return __builtin_return_address(2); + case 2: return __builtin_return_address(3); + case 3: return __builtin_return_address(4); + case 4: return __builtin_return_address(5); + case 5: return __builtin_return_address(6); + case 6: return __builtin_return_address(7); + case 7: return __builtin_return_address(8); + case 8: return __builtin_return_address(9); + case 9: return __builtin_return_address(10); + case 10: return __builtin_return_address(11); + case 11: return __builtin_return_address(12); + case 12: return __builtin_return_address(13); + case 13: return __builtin_return_address(14); + case 14: return __builtin_return_address(15); + case 15: return __builtin_return_address(16); + case 16: return __builtin_return_address(17); + case 17: return __builtin_return_address(18); + case 18: return __builtin_return_address(19); + case 19: return __builtin_return_address(20); + case 20: return __builtin_return_address(21); + case 21: return __builtin_return_address(22); + case 22: return __builtin_return_address(23); + case 23: return __builtin_return_address(24); + case 24: return __builtin_return_address(25); + case 25: return __builtin_return_address(26); + case 26: return __builtin_return_address(27); + case 27: return __builtin_return_address(28); + case 28: return __builtin_return_address(29); + case 29: return __builtin_return_address(30); + case 30: return __builtin_return_address(31); + case 31: return __builtin_return_address(32); + case 32: return __builtin_return_address(33); + case 33: return __builtin_return_address(34); + case 34: return __builtin_return_address(35); + case 35: return __builtin_return_address(36); + case 36: return __builtin_return_address(37); + case 37: return __builtin_return_address(38); + case 38: return __builtin_return_address(39); + case 39: return __builtin_return_address(40); + case 40: return __builtin_return_address(41); + case 41: return __builtin_return_address(42); + case 42: return __builtin_return_address(43); + case 43: return __builtin_return_address(44); + case 44: return __builtin_return_address(45); + case 45: return __builtin_return_address(46); + case 46: return __builtin_return_address(47); + case 47: return __builtin_return_address(48); + case 48: return __builtin_return_address(49); + case 49: return __builtin_return_address(50); + case 50: return __builtin_return_address(51); + case 51: return __builtin_return_address(52); + case 52: return __builtin_return_address(53); + case 53: return __builtin_return_address(54); + case 54: return __builtin_return_address(55); + case 55: return __builtin_return_address(56); + case 56: return __builtin_return_address(57); + case 57: return __builtin_return_address(58); + case 58: return __builtin_return_address(59); + case 59: return __builtin_return_address(60); + case 60: return __builtin_return_address(61); + case 61: return __builtin_return_address(62); + case 62: return __builtin_return_address(63); + case 63: return __builtin_return_address(64); + case 64: return __builtin_return_address(65); + case 65: return __builtin_return_address(66); + case 66: return __builtin_return_address(67); + case 67: return __builtin_return_address(68); + case 68: return __builtin_return_address(69); + case 69: return __builtin_return_address(70); + case 70: return __builtin_return_address(71); + case 71: return __builtin_return_address(72); + case 72: return __builtin_return_address(73); + case 73: return __builtin_return_address(74); + case 74: return __builtin_return_address(75); + case 75: return __builtin_return_address(76); + case 76: return __builtin_return_address(77); + case 77: return __builtin_return_address(78); + case 78: return __builtin_return_address(79); + case 79: return __builtin_return_address(80); + case 80: return __builtin_return_address(81); + case 81: return __builtin_return_address(82); + case 82: return __builtin_return_address(83); + case 83: return __builtin_return_address(84); + case 84: return __builtin_return_address(85); + case 85: return __builtin_return_address(86); + case 86: return __builtin_return_address(87); + case 87: return __builtin_return_address(88); + case 88: return __builtin_return_address(89); + case 89: return __builtin_return_address(90); + case 90: return __builtin_return_address(91); + case 91: return __builtin_return_address(92); + case 92: return __builtin_return_address(93); + case 93: return __builtin_return_address(94); + case 94: return __builtin_return_address(95); + case 95: return __builtin_return_address(96); + case 96: return __builtin_return_address(97); + case 97: return __builtin_return_address(98); + case 98: return __builtin_return_address(99); + case 99: return __builtin_return_address(100); + case 100: return __builtin_return_address(101); + case 101: return __builtin_return_address(102); + case 102: return __builtin_return_address(103); + case 103: return __builtin_return_address(104); + case 104: return __builtin_return_address(105); + case 105: return __builtin_return_address(106); + case 106: return __builtin_return_address(107); + case 107: return __builtin_return_address(108); + case 108: return __builtin_return_address(109); + case 109: return __builtin_return_address(110); + case 110: return __builtin_return_address(111); + case 111: return __builtin_return_address(112); + case 112: return __builtin_return_address(113); + case 113: return __builtin_return_address(114); + case 114: return __builtin_return_address(115); + case 115: return __builtin_return_address(116); + case 116: return __builtin_return_address(117); + case 117: return __builtin_return_address(118); + case 118: return __builtin_return_address(119); + case 119: return __builtin_return_address(120); + case 120: return __builtin_return_address(121); + case 121: return __builtin_return_address(122); + case 122: return __builtin_return_address(123); + case 123: return __builtin_return_address(124); + case 124: return __builtin_return_address(125); + case 125: return __builtin_return_address(126); + case 126: return __builtin_return_address(127); + case 127: return __builtin_return_address(128); + default: return NULL; + } +} + +void * +getframeaddr(int level) +{ + + switch(level) { + case 0: return __builtin_frame_address(1); + case 1: return __builtin_frame_address(2); + case 2: return __builtin_frame_address(3); + case 3: return __builtin_frame_address(4); + case 4: return __builtin_frame_address(5); + case 5: return __builtin_frame_address(6); + case 6: return __builtin_frame_address(7); + case 7: return __builtin_frame_address(8); + case 8: return __builtin_frame_address(9); + case 9: return __builtin_frame_address(10); + case 10: return __builtin_frame_address(11); + case 11: return __builtin_frame_address(12); + case 12: return __builtin_frame_address(13); + case 13: return __builtin_frame_address(14); + case 14: return __builtin_frame_address(15); + case 15: return __builtin_frame_address(16); + case 16: return __builtin_frame_address(17); + case 17: return __builtin_frame_address(18); + case 18: return __builtin_frame_address(19); + case 19: return __builtin_frame_address(20); + case 20: return __builtin_frame_address(21); + case 21: return __builtin_frame_address(22); + case 22: return __builtin_frame_address(23); + case 23: return __builtin_frame_address(24); + case 24: return __builtin_frame_address(25); + case 25: return __builtin_frame_address(26); + case 26: return __builtin_frame_address(27); + case 27: return __builtin_frame_address(28); + case 28: return __builtin_frame_address(29); + case 29: return __builtin_frame_address(30); + case 30: return __builtin_frame_address(31); + case 31: return __builtin_frame_address(32); + case 32: return __builtin_frame_address(33); + case 33: return __builtin_frame_address(34); + case 34: return __builtin_frame_address(35); + case 35: return __builtin_frame_address(36); + case 36: return __builtin_frame_address(37); + case 37: return __builtin_frame_address(38); + case 38: return __builtin_frame_address(39); + case 39: return __builtin_frame_address(40); + case 40: return __builtin_frame_address(41); + case 41: return __builtin_frame_address(42); + case 42: return __builtin_frame_address(43); + case 43: return __builtin_frame_address(44); + case 44: return __builtin_frame_address(45); + case 45: return __builtin_frame_address(46); + case 46: return __builtin_frame_address(47); + case 47: return __builtin_frame_address(48); + case 48: return __builtin_frame_address(49); + case 49: return __builtin_frame_address(50); + case 50: return __builtin_frame_address(51); + case 51: return __builtin_frame_address(52); + case 52: return __builtin_frame_address(53); + case 53: return __builtin_frame_address(54); + case 54: return __builtin_frame_address(55); + case 55: return __builtin_frame_address(56); + case 56: return __builtin_frame_address(57); + case 57: return __builtin_frame_address(58); + case 58: return __builtin_frame_address(59); + case 59: return __builtin_frame_address(60); + case 60: return __builtin_frame_address(61); + case 61: return __builtin_frame_address(62); + case 62: return __builtin_frame_address(63); + case 63: return __builtin_frame_address(64); + case 64: return __builtin_frame_address(65); + case 65: return __builtin_frame_address(66); + case 66: return __builtin_frame_address(67); + case 67: return __builtin_frame_address(68); + case 68: return __builtin_frame_address(69); + case 69: return __builtin_frame_address(70); + case 70: return __builtin_frame_address(71); + case 71: return __builtin_frame_address(72); + case 72: return __builtin_frame_address(73); + case 73: return __builtin_frame_address(74); + case 74: return __builtin_frame_address(75); + case 75: return __builtin_frame_address(76); + case 76: return __builtin_frame_address(77); + case 77: return __builtin_frame_address(78); + case 78: return __builtin_frame_address(79); + case 79: return __builtin_frame_address(80); + case 80: return __builtin_frame_address(81); + case 81: return __builtin_frame_address(82); + case 82: return __builtin_frame_address(83); + case 83: return __builtin_frame_address(84); + case 84: return __builtin_frame_address(85); + case 85: return __builtin_frame_address(86); + case 86: return __builtin_frame_address(87); + case 87: return __builtin_frame_address(88); + case 88: return __builtin_frame_address(89); + case 89: return __builtin_frame_address(90); + case 90: return __builtin_frame_address(91); + case 91: return __builtin_frame_address(92); + case 92: return __builtin_frame_address(93); + case 93: return __builtin_frame_address(94); + case 94: return __builtin_frame_address(95); + case 95: return __builtin_frame_address(96); + case 96: return __builtin_frame_address(97); + case 97: return __builtin_frame_address(98); + case 98: return __builtin_frame_address(99); + case 99: return __builtin_frame_address(100); + case 100: return __builtin_frame_address(101); + case 101: return __builtin_frame_address(102); + case 102: return __builtin_frame_address(103); + case 103: return __builtin_frame_address(104); + case 104: return __builtin_frame_address(105); + case 105: return __builtin_frame_address(106); + case 106: return __builtin_frame_address(107); + case 107: return __builtin_frame_address(108); + case 108: return __builtin_frame_address(109); + case 109: return __builtin_frame_address(110); + case 110: return __builtin_frame_address(111); + case 111: return __builtin_frame_address(112); + case 112: return __builtin_frame_address(113); + case 113: return __builtin_frame_address(114); + case 114: return __builtin_frame_address(115); + case 115: return __builtin_frame_address(116); + case 116: return __builtin_frame_address(117); + case 117: return __builtin_frame_address(118); + case 118: return __builtin_frame_address(119); + case 119: return __builtin_frame_address(120); + case 120: return __builtin_frame_address(121); + case 121: return __builtin_frame_address(122); + case 122: return __builtin_frame_address(123); + case 123: return __builtin_frame_address(124); + case 124: return __builtin_frame_address(125); + case 125: return __builtin_frame_address(126); + case 126: return __builtin_frame_address(127); + case 127: return __builtin_frame_address(128); + default: return NULL; + } +} Index: lib/libvarnishcompat/Makefile.am =================================================================== --- lib/libvarnishcompat/Makefile.am (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvarnishcompat/Makefile.am (.../branches/2.0/varnish-cache) @@ -9,6 +9,7 @@ libvarnishcompat_la_SOURCES = \ asprintf.c \ daemon.c \ + execinfo.c \ vasprintf.c \ setproctitle.c \ srandomdev.c \ Index: lib/libvcl/vcc_gen_obj.tcl =================================================================== --- lib/libvcl/vcc_gen_obj.tcl (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_gen_obj.tcl (.../branches/2.0/varnish-cache) @@ -116,6 +116,12 @@ "struct sess *" } + { req.esi + RW BOOL + {recv fetch deliver error} + "struct sess *" + } + # Request sent to backend { bereq.request RW STRING Index: lib/libvcl/vcc_parse.c =================================================================== --- lib/libvcl/vcc_parse.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_parse.c (.../branches/2.0/varnish-cache) @@ -263,10 +263,11 @@ Fb(tl, 1, "%sVRT_strcmp(%s, ", tl->t->tok == T_EQ ? "!" : "", vp->rname); vcc_NextToken(tl); - ExpectErr(tl, CSTR); - EncToken(tl->fb, tl->t); + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + break; + } Fb(tl, 0, ")\n"); - vcc_NextToken(tl); break; default: Fb(tl, 1, "%s != (void*)0\n", vp->rname); Index: lib/libvcl/vcc_obj.c =================================================================== --- lib/libvcl/vcc_obj.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_obj.c (.../branches/2.0/varnish-cache) @@ -102,6 +102,11 @@ | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_ERROR }, + { "req.esi", BOOL, 7, + "VRT_r_req_esi(sp)", "VRT_l_req_esi(sp, ", + V_RW, 0, + VCL_MET_RECV | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_ERROR + }, { "bereq.request", STRING, 13, "VRT_r_bereq_request(sp)", "VRT_l_bereq_request(sp, ", V_RW, 0, Index: lib/libvcl/vcc_backend.c =================================================================== --- lib/libvcl/vcc_backend.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_backend.c (.../branches/2.0/varnish-cache) @@ -340,7 +340,8 @@ struct fld_spec *fs; struct token *t_field; struct token *t_did = NULL, *t_window = NULL, *t_threshold = NULL; - unsigned window, threshold; + struct token *t_initial = NULL; + unsigned window, threshold, initial; fs = vcc_FldSpec(tl, "?url", @@ -349,6 +350,7 @@ "?interval", "?window", "?threshold", + "?initial", NULL); ExpectErr(tl, '{'); @@ -356,6 +358,7 @@ window = 0; threshold = 0; + initial = 0; Fb(tl, 0, "\t.probe = {\n"); while (tl->t->tok != '}') { @@ -396,6 +399,11 @@ window = vcc_UintVal(tl); vcc_NextToken(tl); ERRCHK(tl); + } else if (vcc_IdIs(t_field, "initial")) { + t_initial = tl->t; + initial = vcc_UintVal(tl); + vcc_NextToken(tl); + ERRCHK(tl); } else if (vcc_IdIs(t_field, "threshold")) { t_threshold = tl->t; threshold = vcc_UintVal(tl); @@ -441,8 +449,12 @@ vcc_ErrWhere(tl, t_window); } Fb(tl, 0, "\t\t.window = %u,\n", window); - Fb(tl, 0, "\t\t.threshold = %u\n", threshold); + Fb(tl, 0, "\t\t.threshold = %u,\n", threshold); } + if (t_initial != NULL) + Fb(tl, 0, "\t\t.initial = %u,\n", initial); + else + Fb(tl, 0, "\t\t.initial = ~0U,\n", initial); Fb(tl, 0, "\t},\n"); ExpectErr(tl, '}'); vcc_NextToken(tl); Index: lib/libvcl/vcc_fixed_token.c =================================================================== --- lib/libvcl/vcc_fixed_token.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_fixed_token.c (.../branches/2.0/varnish-cache) @@ -235,8 +235,8 @@ vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI"); vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT"); vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3724 2009-02-10 14:"); - vsb_cat(sb, "58:17Z tfheen $\n *\n * Runtime support for compiled V"); + vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 4303 2009-10-08 13:"); + vsb_cat(sb, "58:25Z tfheen $\n *\n * Runtime support for compiled V"); vsb_cat(sb, "CL programs.\n *\n * XXX: When this file is changed, l"); vsb_cat(sb, "ib/libvcl/vcc_gen_fixed_token.tcl\n"); vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n"); @@ -247,12 +247,12 @@ vsb_cat(sb, "\nstruct vrt_backend_probe {\n\tconst char\t*url;\n"); vsb_cat(sb, "\tconst char\t*request;\n\tdouble\t\ttimeout;\n"); vsb_cat(sb, "\tdouble\t\tinterval;\n\tunsigned\twindow;\n"); - vsb_cat(sb, "\tunsigned\tthreshold;\n};\n\n/*\n"); - vsb_cat(sb, " * A backend is a host+port somewhere on the network\n"); - vsb_cat(sb, " */\nstruct vrt_backend {\n\tconst char\t\t\t*vcl_name"); - vsb_cat(sb, ";\n\tconst char\t\t\t*ident;\n\n"); - vsb_cat(sb, "\tconst char\t\t\t*hosthdr;\n\n"); - vsb_cat(sb, "\tconst unsigned char\t\t*ipv4_sockaddr;\n"); + vsb_cat(sb, "\tunsigned\tthreshold;\n\tunsigned\tinitial;\n"); + vsb_cat(sb, "};\n\n/*\n * A backend is a host+port somewhere on the"); + vsb_cat(sb, " network\n */\nstruct vrt_backend {\n"); + vsb_cat(sb, "\tconst char\t\t\t*vcl_name;\n\tconst char\t\t\t*ident"); + vsb_cat(sb, ";\n\n\tconst char\t\t\t*hosthdr;\n"); + vsb_cat(sb, "\n\tconst unsigned char\t\t*ipv4_sockaddr;\n"); vsb_cat(sb, "\tconst unsigned char\t\t*ipv6_sockaddr;\n"); vsb_cat(sb, "\n\tdouble\t\t\t\tconnect_timeout;\n"); vsb_cat(sb, "\tdouble\t\t\t\tfirst_byte_timeout;\n"); @@ -324,9 +324,9 @@ /* ../../include/vrt_obj.h */ - vsb_cat(sb, "/*\n * $Id: vrt_obj.h 3990 2009-03-23 12:37:42Z tfheen"); - vsb_cat(sb, " $\n *\n * NB: This file is machine generated, DO NOT"); - vsb_cat(sb, " EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); + vsb_cat(sb, "/*\n * $Id: vcc_gen_obj.tcl 4082 2009-05-19 07:14:00Z "); + vsb_cat(sb, "sky $\n *\n * NB: This file is machine generated, DO "); + vsb_cat(sb, "NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct "); vsb_cat(sb, "sess *);\nstruct sockaddr * VRT_r_server_ip(struct ses"); vsb_cat(sb, "s *);\nconst char * VRT_r_server_hostname(struct sess "); @@ -345,6 +345,8 @@ vsb_cat(sb, "uct sess *);\ndouble VRT_r_req_grace(struct sess *);\n"); vsb_cat(sb, "void VRT_l_req_grace(struct sess *, double);\n"); vsb_cat(sb, "const char * VRT_r_req_xid(struct sess *);\n"); + vsb_cat(sb, "unsigned VRT_r_req_esi(struct sess *);\n"); + vsb_cat(sb, "void VRT_l_req_esi(struct sess *, unsigned);\n"); vsb_cat(sb, "const char * VRT_r_bereq_request(const struct sess *);"); vsb_cat(sb, "\nvoid VRT_l_bereq_request(const struct sess *, const "); vsb_cat(sb, "char *, ...);\nconst char * VRT_r_bereq_url(const stru"); Index: lib/libvcl/vcc_acl.c =================================================================== --- lib/libvcl/vcc_acl.c (.../tags/varnish-2.0.4/varnish-cache) +++ lib/libvcl/vcc_acl.c (.../branches/2.0/varnish-cache) @@ -250,14 +250,18 @@ { unsigned char b[4]; int i, j, k; + unsigned u; const char *p; memset(b, 0, sizeof b); p = ae->t_addr->dec; for (i = 0; i < 4; i++) { - j = sscanf(p, "%hhu%n", &b[i], &k); + j = sscanf(p, "%u%n", &u, &k); if (j != 1) return (0); + if (u & ~0xff) + return (0); + b[i] = (unsigned char)u; if (p[k] == '\0') break; if (p[k] != '.') Index: bin/varnishreplay/varnishreplay.c =================================================================== --- bin/varnishreplay/varnishreplay.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishreplay/varnishreplay.c (.../branches/2.0/varnish-cache) @@ -190,7 +190,7 @@ pthread_mutex_unlock(&log_mutex); } -struct thread { +struct replay_thread { pthread_t thread_id; struct mailbox mbox; @@ -212,14 +212,14 @@ char temp[2048]; }; -static struct thread **threads; +static struct replay_thread **threads; static size_t nthreads; /* * Clear thread state */ static void -thread_clear(struct thread *thr) +thread_clear(struct replay_thread *thr) { thr->method = thr->proto = thr->url = NULL; @@ -236,17 +236,17 @@ thr->sock = -1; } -#define THREAD_FAIL ((struct thread *)-1) +#define THREAD_FAIL ((struct replay_thread *)-1) static pthread_attr_t thread_attr; -static struct thread * +static struct replay_thread * thread_get(int fd, void *(*thread_main)(void *)) { assert(fd != 0); if (fd >= nthreads) { - struct thread **newthreads = threads; + struct replay_thread **newthreads = threads; size_t newnthreads = nthreads; while (fd >= newnthreads) @@ -309,7 +309,7 @@ * Allocate from thread arena */ static void * -thread_alloc(struct thread *thr, size_t len) +thread_alloc(struct replay_thread *thr, size_t len) { void *ptr; @@ -325,7 +325,7 @@ * trimmed. */ static char * -trimline(struct thread *thr, const char *str) +trimline(struct replay_thread *thr, const char *str) { size_t len; char *p; @@ -355,7 +355,7 @@ * A line is terminated by \r\n */ static int -read_line(struct thread *thr) +read_line(struct replay_thread *thr) { int i, len; @@ -389,7 +389,7 @@ * the number of bytes read. */ static int -read_block(struct thread *thr, int len) +read_block(struct replay_thread *thr, int len) { int n, r, tot; @@ -412,7 +412,7 @@ /* Receive the response after sending a request. */ static int -receive_response(struct thread *thr) +receive_response(struct replay_thread *thr) { const char *next; int line_len; @@ -496,7 +496,7 @@ { struct iovec iov[6]; char space[1] = " ", crlf[2] = "\r\n"; - struct thread *thr = arg; + struct replay_thread *thr = arg; struct message *msg; enum shmlogtag tag; size_t len; @@ -642,7 +642,7 @@ gen_traffic(void *priv, enum shmlogtag tag, unsigned fd, unsigned len, unsigned spec, const char *ptr) { - struct thread *thr; + struct replay_thread *thr; const char *end; struct message *msg; Index: bin/varnishtest/tests/r00354.vtc =================================================================== --- bin/varnishtest/tests/r00354.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00354.vtc (.../branches/2.0/varnish-cache) @@ -1,16 +0,0 @@ -# $Id$ - -test "#354 Segfault in strcmp in http_DissectRequest()" - -server s1 { - rxreq - txresp -} - -varnish v1 -vcl+backend {} -start - -client c1 { - send "FOO\r\n\r\n" - rxresp - expect resp.status == 400 -} -run Index: bin/varnishtest/tests/r00494.vtc =================================================================== --- bin/varnishtest/tests/r00494.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00494.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,27 @@ +# $Id$ + +test "HTTP continuation lines" + +#NB: careful about spaces and tabs in this test. + +server s1 { + rxreq + txresp -hdr {Foo: bar, + barf: fail} -body "xxx" +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set obj.http.bar = obj.http.foo; + remove obj.http.foo; + } +} -start + +client c1 { + txreq + rxresp + expect resp.http.bar == "bar, barf: fail" + expect resp.http.barf == resp.http.barf + expect resp.http.foo == resp.http.foo +} -run + Index: bin/varnishtest/tests/r00498.vtc =================================================================== --- bin/varnishtest/tests/r00498.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00498.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,18 @@ +# $Id$ + +test "very very very long return header" + +server s1 { + rxreq + expect req.url == "/" + txresp -hdr "Location: 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" -body {foo} +} -start + +varnish v1 -vcl+backend { +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 3 +} -run Index: bin/varnishtest/tests/b00029.vtc =================================================================== --- bin/varnishtest/tests/b00029.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/b00029.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,18 @@ +# $Id$ + +test "Test orderly connection closure" + + +server s1 { + rxreq + txresp -bodylen 130000 +} -start + +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -hdr "Connection: close" + delay 3 + rxresp + expect resp.bodylen == 130000 +} -run Index: bin/varnishtest/tests/r00502.vtc =================================================================== --- bin/varnishtest/tests/r00502.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00502.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,30 @@ +# $Id$ + +test "multi element purge" + +server s1 { + rxreq + txresp -hdr "foo: bar1" -body "1" + rxreq + txresp -hdr "foo: bar2" -body "22" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + purge("req.url == / && obj.http.foo ~ bar1"); + } +} -start + +client c1 { + txreq + rxresp + expect resp.http.foo == "bar1" + txreq + rxresp + expect resp.http.foo == "bar2" + txreq + rxresp + expect resp.http.foo == "bar2" +} -run + +varnish v1 -cliok purge.list Index: bin/varnishtest/tests/v00024.vtc =================================================================== --- bin/varnishtest/tests/v00024.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/v00024.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,27 @@ +# $Id$ + +test "Test that headers can be compared" + +server s1 { + rxreq + expect req.url == "/foo" + txresp -status 200 -body "1" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + if (req.http.etag == req.http.if-none-match) { + error 400 "FOO"; + } + } +} -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.bodylen == 1 + txreq -url "/foo" -hdr "etag: foo" -hdr "if-none-match: foo" + rxresp + expect resp.status == 400 +} -run Index: bin/varnishtest/tests/r00506.vtc =================================================================== --- bin/varnishtest/tests/r00506.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00506.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,18 @@ +# $Id$ + +test "Illegal HTTP status from backend" + +server s1 { + rxreq + send "HTTP/1.1 1000\n\nFoo" +} -start + +varnish v1 -vcl+backend { + sub vcl_recv { + } +} -start + +client c1 { + txreq + rxresp +} -run Index: bin/varnishtest/tests/r00549.vtc =================================================================== --- bin/varnishtest/tests/r00549.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00549.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,15 @@ +# $Id$ + +# Regression test for bad backend reply with ctrl char. + +server s1 { + rxreq + send "HTTP/1.1 200 OK\013\r\n\r\nTest" +} -start + +varnish v1 -vcl+backend {} -start + +client c1 { + txreq + rxresp +} -run Index: bin/varnishtest/tests/c00025.vtc =================================================================== --- bin/varnishtest/tests/c00025.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/c00025.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,33 @@ +# $Id$ + +test "Test If-None-Match" + +server s1 { + rxreq + expect req.url == "/foo" + txresp -hdr "ETag: 123456789" \ + -body "11111\n" +} -start + +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 6 + + txreq -url "/foo" \ + -hdr "If-None-Match: 12345678" + rxresp + expect resp.status == 200 + + txreq -url "/foo" \ + -hdr "If-None-Match: 123456789" + rxresp + expect resp.status == 304 +} + +client c1 -run + +client c1 -run Index: bin/varnishtest/tests/r00558.vtc =================================================================== --- bin/varnishtest/tests/r00558.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00558.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,19 @@ +# $Id$ + +test "error from vcl_recv{} has no numeric code" + + +server s1 { +} + +varnish v1 -vcl+backend { + sub vcl_recv { + return (error); + } +} -start + +client c1 { + txreq + rxresp + expect resp.status == 501 +} -run Index: bin/varnishtest/tests/e00016.vtc =================================================================== --- bin/varnishtest/tests/e00016.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/e00016.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,49 @@ +# $Id$ + +test "ESI request can't be turned off midstream" + +server s1 { + rxreq + txresp -body { + + Before include + + + After include + } + rxreq + expect req.url == "/body" + txresp -body { + + } + rxreq + expect req.url == "/body2" + txresp -body { + included + } + rxreq + expect req.url == "/body3" + txresp -body { + included body3 + } +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + set req.esi = true; + if(req.url == "/body") { + set req.esi = false; + } + esi; + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 105 + expect resp.status == 200 +} + +client c1 -run +varnish v1 -expect esi_errors == 0 Index: bin/varnishtest/tests/r00561.vtc =================================================================== --- bin/varnishtest/tests/r00561.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00561.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,25 @@ +# $Id$ + +test "Junk request should not go to vcl_error" + +server s1 { + rxreq + txresp +} -start + +varnish v1 -vcl+backend { + sub vcl_error { + return (restart); + } +} -start + +client c1 { + send "sljdslf\r\n\r\n" + delay .1 +} -run + +client c1 { + txreq + rxresp +} -run + Index: bin/varnishtest/tests/c00008.vtc =================================================================== --- bin/varnishtest/tests/c00008.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/c00008.vtc (.../branches/2.0/varnish-cache) @@ -6,6 +6,7 @@ rxreq expect req.url == "/foo" txresp -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "ETag: foo" \ -body "11111\n" } -start @@ -15,22 +16,26 @@ txreq -url "/foo" rxresp expect resp.status == 200 + expect resp.http.etag == "foo" expect resp.http.content-length == 6 txreq -url "/foo" \ -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:00 GMT" rxresp expect resp.status == 200 + expect resp.http.etag == "foo" txreq -url "/foo" \ -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" rxresp expect resp.status == 304 + expect resp.http.etag == "foo" txreq -url "/foo" \ -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:02 GMT" rxresp expect resp.status == 304 + expect resp.http.etag == "foo" } client c1 -run Index: bin/varnishtest/tests/s00002.vtc =================================================================== --- bin/varnishtest/tests/s00002.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/s00002.vtc (.../branches/2.0/varnish-cache) @@ -18,6 +18,7 @@ .interval = 1s; .window = 2; .threshold = 1; + .initial = 0; } } sub vcl_fetch { Index: bin/varnishtest/tests/v00014.vtc =================================================================== --- bin/varnishtest/tests/v00014.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/v00014.vtc (.../branches/2.0/varnish-cache) @@ -20,6 +20,7 @@ .interval = 1s; .window = 3; .threshold = 2; + .initial = 0; } } Index: bin/varnishtest/tests/r00306.vtc =================================================================== --- bin/varnishtest/tests/r00306.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/r00306.vtc (.../branches/2.0/varnish-cache) @@ -27,6 +27,7 @@ .host = "127.0.0.1"; .port = "9180"; .probe = { .url = "/"; + .initial = 0; } } director foo random { Index: bin/varnishtest/tests/c00026.vtc =================================================================== --- bin/varnishtest/tests/c00026.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/c00026.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,53 @@ +# $Id$ + +test "Test Combination of If-None-Match and If-Modified-Since" + +server s1 { + rxreq + expect req.url == "/foo" + txresp -hdr "ETag: 123456789" \ + -hdr "Last-Modified: Thu, 26 Jun 2008 12:00:01 GMT" \ + -body "11111\n" +} -start + +varnish v1 -vcl+backend { } -start + +client c1 { + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.content-length == 6 + + txreq -url "/foo" \ + -hdr "If-None-Match: 123456789" + rxresp + expect resp.status == 304 + + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" + rxresp + expect resp.status == 304 + + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:00 GMT" \ + -hdr "If-None-Match: 123456789" + rxresp + expect resp.status == 200 + + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "If-None-Match: 12345678" + rxresp + expect resp.status == 200 + + txreq -url "/foo" \ + -hdr "If-Modified-Since: Thu, 26 Jun 2008 12:00:01 GMT" \ + -hdr "If-None-Match: 123456789" + rxresp + expect resp.status == 304 + +} + +client c1 -run + +client c1 -run Index: bin/varnishtest/tests/c00028.vtc =================================================================== --- bin/varnishtest/tests/c00028.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/c00028.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,24 @@ +# $Id$ + +test "Test that we can't recurse restarts forever" + +varnish v1 -vcl { + backend bad { + .host = "127.0.0.1"; + .port = "9090"; + } + + sub vcl_recv { + set req.backend = bad; + } + sub vcl_error { + restart; + } + } -start + +client c1 { + txreq -url "/" + rxresp + expect resp.status == 503 +} -run + Index: bin/varnishtest/tests/e00013.vtc =================================================================== --- bin/varnishtest/tests/e00013.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/e00013.vtc (.../branches/2.0/varnish-cache) @@ -6,7 +6,7 @@ rxreq expect req.url == "/foo" txresp -hdr "Connection: close" - send { } + send { } } -start varnish v1 -vcl+backend { Index: bin/varnishtest/tests/e00015.vtc =================================================================== --- bin/varnishtest/tests/e00015.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/e00015.vtc (.../branches/2.0/varnish-cache) @@ -0,0 +1,48 @@ +# $Id$ + +test "ESI requests turned off" + +server s1 { + rxreq + txresp -body { + + Before include + + After include + } + rxreq + txresp -body { + + Before include + + After include + } + rxreq + expect req.url == "/body" + txresp -body { + Included file + } +} -start + +varnish v1 -vcl+backend { + sub vcl_fetch { + if(req.url == "/") { + set req.esi = false; + } + esi; + } +} -start + +client c1 { + txreq + rxresp + expect resp.bodylen == 73 + expect resp.status == 200 + txreq -url "/esi" + rxresp + expect resp.bodylen == 65 + expect resp.status == 200 +} + +client c1 -run +varnish v1 -expect esi_errors == 0 Property changes on: bin/varnishtest/tests/e00015.vtc ___________________________________________________________________ Added: svn:keywords + Id Index: bin/varnishtest/tests/c00001.vtc =================================================================== --- bin/varnishtest/tests/c00001.vtc (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/tests/c00001.vtc (.../branches/2.0/varnish-cache) @@ -36,7 +36,7 @@ expect resp.http.snafu2 == "_frap_" expect resp.http.snafu3 == "_f\\rap_" expect resp.http.snafu4 == "_f&rap_" - expect resp.http.snafu5 == "_barffra\p_" - # NB: have to escape the \\ in the next line + # NB: have to escape the \\ in the next two lines + expect resp.http.snafu5 == "_barffra\\p_" expect resp.http.snafu6 == "_f&rap\\_" } -run Index: bin/varnishtest/vtc_varnish.c =================================================================== --- bin/varnishtest/vtc_varnish.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/vtc_varnish.c (.../branches/2.0/varnish-cache) @@ -326,9 +326,14 @@ vtc_log(v->vl, 2, "R %d Status: %04x", r, status); if (WIFEXITED(status) && WEXITSTATUS(status) == 2) return; +#ifdef WCOREDUMP vtc_log(v->vl, 0, "Bad exit code: %04x sig %x exit %x core %x", status, WTERMSIG(status), WEXITSTATUS(status), WCOREDUMP(status)); +#else + vtc_log(v->vl, 0, "Bad exit code: %04x sig %x exit %x", + status, WTERMSIG(status), WEXITSTATUS(status)); +#endif } /********************************************************************** Index: bin/varnishtest/vtc_http.c =================================================================== --- bin/varnishtest/vtc_http.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/vtc_http.c (.../branches/2.0/varnish-cache) @@ -322,11 +322,13 @@ pfd[0].revents = 0; i = poll(pfd, 1, hp->timeout); assert(i > 0); - assert(hp->prxbuf < hp->nrxbuf); + assert(hp->prxbuf + n < hp->nrxbuf); i = read(hp->fd, hp->rxbuf + hp->prxbuf, n); if (i == 0) return (i); - assert(i > 0); + if (i <= 0) + vtc_log(hp->vl, 0, "HTTP rx failed (%s)", + strerror(errno)); hp->prxbuf += i; hp->rxbuf[hp->prxbuf] = '\0'; n -= i; @@ -781,7 +783,7 @@ hp->vl = vl; hp->client = client; hp->timeout = 3000; - hp->nrxbuf = 8192; + hp->nrxbuf = 640*1024; hp->vsb = vsb_newauto(); hp->rxbuf = malloc(hp->nrxbuf); /* XXX */ AN(hp->rxbuf); Index: bin/varnishtest/vtc.c =================================================================== --- bin/varnishtest/vtc.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtest/vtc.c (.../branches/2.0/varnish-cache) @@ -130,19 +130,9 @@ for (; *p != '\0'; p++) { if (*p == '"') break; - - if (*p == '\\' && p[1] == 'n') { - *q++ = '\n'; - p++; - } else if (*p == '\\' && p[1] == 'r') { - *q++ = '\r'; - p++; - } else if (*p == '\\' && p[1] == '\\') { - *q++ = '\\'; - p++; - } else if (*p == '\\' && p[1] == '"') { - *q++ = '"'; - p++; + if (*p == '\\') { + p += BackSlash(p, q) - 1; + q++; } else { if (*p == '\n') fprintf(stderr, Index: bin/varnishtop/varnishtop.c =================================================================== --- bin/varnishtop/varnishtop.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishtop/varnishtop.c (.../branches/2.0/varnish-cache) @@ -54,7 +54,8 @@ #include "varnishapi.h" struct top { - unsigned char rec[4 + 255]; + unsigned char rec[4]; + unsigned char *rec_data; unsigned clen; unsigned hash; VTAILQ_ENTRY(top) list; @@ -99,7 +100,7 @@ continue; if (tp->clen != q - p) continue; - if (memcmp(p + SHMLOG_DATA, tp->rec + SHMLOG_DATA, + if (memcmp(p + SHMLOG_DATA, tp->rec_data, q - (p + SHMLOG_DATA))) continue; tp->count += 1.0; @@ -109,12 +110,15 @@ ntop++; tp = calloc(sizeof *tp, 1); assert(tp != NULL); + tp->rec_data = calloc(l, 1); + assert(tp->rec_data != NULL); tp->hash = u; tp->count = 1.0; tp->clen = q - p; VTAILQ_INSERT_TAIL(&top_head, tp, list); } - memcpy(tp->rec, p, SHMLOG_DATA + l); + memcpy(tp->rec, p, SHMLOG_DATA - 1); + memcpy(tp->rec_data, p + SHMLOG_DATA, l); while (1) { tp2 = VTAILQ_PREV(tp, tophead, list); if (tp2 == NULL || tp2->count >= tp->count) @@ -157,12 +161,13 @@ mvprintw(l, 0, "%9.2f %-*.*s %*.*s\n", tp->count, maxfieldlen, maxfieldlen, VSL_tags[tp->rec[SHMLOG_TAG]], - len, len, tp->rec + SHMLOG_DATA); + len, len, tp->rec_data); t = tp->count; } tp->count *= .999; if (tp->count * 10 < t || l > LINES * 10) { VTAILQ_REMOVE(&top_head, tp, list); + free(tp->rec_data); free(tp); ntop--; } @@ -267,8 +272,8 @@ VTAILQ_FOREACH_SAFE(tp, &top_head, list, tp2) { if (tp->count <= 1.0) break; - len = tp->rec[1]; - printf("%9.2f %*.*s\n", tp->count, len, len, tp->rec + 4); + len = SHMLOG_LEN(tp->rec); + printf("%9.2f %s %*.*s\n", tp->count, VSL_tags[tp->rec[SHMLOG_TAG]], len, len, tp->rec + SHMLOG_DATA); } } Index: bin/varnishd/cache_acceptor_kqueue.c =================================================================== --- bin/varnishd/cache_acceptor_kqueue.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_acceptor_kqueue.c (.../branches/2.0/varnish-cache) @@ -197,6 +197,7 @@ if (sp->t_open > deadline) break; VTAILQ_REMOVE(&sesshead, sp, list); + TCP_linger(sp->fd, 0); vca_close_session(sp, "timeout"); SES_Delete(sp); } Index: bin/varnishd/storage_file.c =================================================================== --- bin/varnishd/storage_file.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/storage_file.c (.../branches/2.0/varnish-cache) @@ -577,6 +577,7 @@ p = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, off); if (p != MAP_FAILED) { + (void) madvise(p, sz, MADV_RANDOM); (*sum) += sz; new_smf(sc, p, off, sz); return; Index: bin/varnishd/steps.h =================================================================== --- bin/varnishd/steps.h (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/steps.h (.../branches/2.0/varnish-cache) @@ -29,7 +29,7 @@ * $Id$ */ -STEP(again, AGAIN) +STEP(wait, WAIT) STEP(first, FIRST) STEP(recv, RECV) STEP(start, START) Index: bin/varnishd/mgt_param.c =================================================================== --- bin/varnishd/mgt_param.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/mgt_param.c (.../branches/2.0/varnish-cache) @@ -692,6 +692,15 @@ "have both IPv4 and IPv6 addresses.", 0, "off", "bool" }, + { "session_max", tweak_uint, + &master.max_sess, 1000, UINT_MAX, + "Maximum number of sessions we will allocate " + "before just dropping connections.\n" + "This is mostly an anti-DoS measure, and setting it plenty " + "high should not hurt, as long as you have the memory for " + "it.\n", + 0, + "100000", "sessions" }, { "session_linger", tweak_uint, &master.session_linger,0, UINT_MAX, "How long time the workerthread lingers on the session " @@ -703,7 +712,7 @@ "anything for their keep, setting it too low just means that " "more sessions take a detour around the acceptor.", EXPERIMENTAL, - "0", "ms" }, + "50", "ms" }, { "cli_buffer", tweak_uint, &master.cli_buffer, 4096, UINT_MAX, "Size of buffer for CLI input." "\nYou may need to increase this if you have big VCL files " @@ -756,7 +765,7 @@ { "purge_dups", tweak_bool, &master.purge_dups, 0, 0, "Detect and eliminate duplicate purges.\n", 0, - "off", "bool" }, + "on", "bool" }, { NULL, NULL, NULL } }; Index: bin/varnishd/cache_vcl.c =================================================================== --- bin/varnishd/cache_vcl.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_vcl.c (.../branches/2.0/varnish-cache) @@ -83,7 +83,13 @@ void VCL_Get(struct VCL_conf **vcc) { + static int once; + while (!once && vcl_active == NULL) { + sleep(1); + } + once = 1; + Lck_Lock(&vcl_mtx); AN(vcl_active); *vcc = vcl_active->conf; Index: bin/varnishd/cache_ws.c =================================================================== --- bin/varnishd/cache_ws.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_ws.c (.../branches/2.0/varnish-cache) @@ -82,6 +82,10 @@ WS_Assert(ws); } +/* + * Reset a WS to start or a given pointer, likely from WS_Snapshot + */ + void WS_Reset(struct ws *ws, char *p) { Index: bin/varnishd/cache_httpconn.c =================================================================== --- bin/varnishd/cache_httpconn.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_httpconn.c (.../branches/2.0/varnish-cache) @@ -92,6 +92,7 @@ (void)WS_Reserve(htc->ws, (htc->ws->e - htc->ws->s) / 2); htc->rxbuf.b = ws->f; htc->rxbuf.e = ws->f; + *htc->rxbuf.e = '\0'; htc->pipeline.b = NULL; htc->pipeline.e = NULL; } Index: bin/varnishd/cache_response.c =================================================================== --- bin/varnishd/cache_response.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_response.c (.../branches/2.0/varnish-cache) @@ -46,6 +46,7 @@ res_do_304(struct sess *sp) { char lm[64]; + char *p; WSP(sp, SLT_Length, "%u", 0); @@ -56,8 +57,23 @@ http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Date: %s", lm); http_SetHeader(sp->wrk, sp->fd, sp->http, "Via: 1.1 varnish"); http_PrintfHeader(sp->wrk, sp->fd, sp->http, "X-Varnish: %u", sp->xid); - TIM_format(sp->obj->last_modified, lm); - http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Last-Modified: %s", lm); + if (sp->obj->last_modified) { + TIM_format(sp->obj->last_modified, lm); + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Last-Modified: %s", lm); + } + + /* http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5 */ + if (http_GetHdr(sp->obj->http, H_Cache_Control, &p)) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Cache-Control: %s", p); + if (http_GetHdr(sp->obj->http, H_Content_Location, &p)) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Content-Location: %s", p); + if (http_GetHdr(sp->obj->http, H_ETag, &p)) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "ETag: %s", p); + if (http_GetHdr(sp->obj->http, H_Expires, &p)) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Expires: %s", p); + if (http_GetHdr(sp->obj->http, H_Vary, &p)) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Vary: %s", p); + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Connection: %s", sp->doclose ? "close" : "keep-alive"); sp->wantbody = 0; @@ -68,17 +84,33 @@ static int res_do_conds(struct sess *sp) { - char *p; + char *p, *e; double ims; + int do_cond = 0; - if (sp->obj->last_modified > 0 && - http_GetHdr(sp->http, H_If_Modified_Since, &p)) { + /* RFC 2616 13.3.4 states we need to match both ETag + and If-Modified-Since if present*/ + + if (http_GetHdr(sp->http, H_If_Modified_Since, &p) ) { + if (!sp->obj->last_modified) + return (0); ims = TIM_parse(p); if (ims > sp->t_req) /* [RFC2616 14.25] */ return (0); if (sp->obj->last_modified > ims) { return (0); } + do_cond = 1; + } + + if (http_GetHdr(sp->http, H_If_None_Match, &p) && + http_GetHdr(sp->obj->http, H_ETag, &e)) { + if (strcmp(p,e) != 0) + return (0); + do_cond = 1; + } + + if (do_cond == 1) { res_do_304(sp); return (1); } @@ -106,9 +138,12 @@ HTTPH_A_DELIVER); /* Only HTTP 1.1 can do Chunked encoding */ - if (sp->http->protover < 1.1 && !VTAILQ_EMPTY(&sp->obj->esibits)) - http_Unset(sp->http, H_Transfer_Encoding); - + if (!sp->disable_esi && !VTAILQ_EMPTY(&sp->obj->esibits)) { + http_Unset(sp->http, H_Content_Length); + if(sp->http->protover >= 1.1) + http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Transfer-Encoding: chunked"); + } + TIM_format(TIM_real(), time_str); http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Date: %s", time_str); @@ -139,10 +174,10 @@ WRW_Reserve(sp->wrk, &sp->fd); - if (sp->esis == 0) + if (sp->disable_esi || sp->esis == 0) sp->acct_req.hdrbytes += http_Write(sp->wrk, sp->http, 1); - if (sp->wantbody && !VTAILQ_EMPTY(&sp->obj->esibits)) { + if (!sp->disable_esi && sp->wantbody && !VTAILQ_EMPTY(&sp->obj->esibits)) { if (WRW_FlushRelease(sp->wrk)) { vca_close_session(sp, "remote closed"); return; @@ -152,7 +187,8 @@ } if (sp->wantbody) { - if (sp->esis > 0 && + if (!sp->disable_esi && + sp->esis > 0 && sp->http->protover >= 1.1 && sp->obj->len > 0) { sprintf(lenbuf, "%x\r\n", sp->obj->len); @@ -183,7 +219,8 @@ (void)WRW_Write(sp->wrk, st->ptr, st->len); } assert(u == sp->obj->len); - if (sp->esis > 0 && + if (!sp->disable_esi && + sp->esis > 0 && sp->http->protover >= 1.1 && sp->obj->len > 0) (void)WRW_Write(sp->wrk, "\r\n", -1); Index: bin/varnishd/cache_cli.c =================================================================== --- bin/varnishd/cache_cli.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_cli.c (.../branches/2.0/varnish-cache) @@ -158,8 +158,7 @@ continue; assert(i == 1); if (pfd[0].revents & POLLHUP) { - fprintf(stderr, - "EOF on CLI connection, exiting\n"); + VSL(SLT_CLI, 0, "EOF on CLI connection, worker stops"); exit(0); } i = VLU_Fd(heritage.cli_in, vlu); Index: bin/varnishd/varnishd.1 =================================================================== --- bin/varnishd/varnishd.1 (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/varnishd.1 (.../branches/2.0/varnish-cache) @@ -326,8 +326,12 @@ address and port. The following commands are available: .Bl -tag -width 4n -.It Cm help +.It Cm help Op Ar command Display a list of available commands. +.Pp +If the +.Ar command +is specified, display help for this command. .It Cm param.set Ar param Ar value Set the parameter specified by .Ar param @@ -336,35 +340,78 @@ See .Sx Run-Time Parameters for a list of parameters. -.It Cm param.show Ar param -Display the value of the parameter specified by -.Ar param . -See -.Sx Run-Time Parameters -for a list of parameters. -.It Cm param.show Op Fl l -Display a list of run-time parameters and their values. +.It Xo +.Cm param.show +.Op Fl l +.Op Ar param +.Xc +Display a list if run-time parameters and their values. +.Pp If the .Fl l option is specified, the list includes a brief explanation of each parameter. +.Pp +If a +.Ar param +is specified, display only the value and explanation for this +parameter. .It Cm ping Op Ns Ar timestamp -Ping the child process. +Ping the Varnish cache process, keeping the connection alive. +.It Cm purge Ar field Ar operator Ar argument Op && Ar field Ar operator Ar argument Op ... +Immediately invalidate all documents matching the purge expression. +See +.Va Purge expressions +for more documentation and examples. +.It Cm purge.hash Ar regex +Immediately invalidate all documents where +.Va obj.hash +matches the +.Va regex . +The default object hash contains the values from +.Va req.url +and either +.Va req.http.host +or +.Va server.ip +depending on the presence of a Host: header in the request sent by the +client. +The object hash may be modified further by +.Va VCL. +.It Cm purge.list +Display the purge list. +.Pp +All requests for objects from the cache are matched against items on +the purge list. +If an object in the cache is older than a matching purge list item, it +is considered +.Qq purged , +and will be fetched from the backend instead. +.Pp +When a purge expression is older than all the objects in the cache, it +is removed from the list. +.It Cm purge.url Ar regexp +Immediately invalidate all documents whose URL matches the specified +regular expression. +.It Cm quit +Close the connection to the varnish admin port. .It Cm start -Start the child process if it is not already running. +Start the Varnish cache process if it is not already running. .It Cm stats -Display server statistics. +Show summary statistics. +.Pp All the numbers presented are totals since server startup; for a better idea of the current situation, use the .Xr varnishstat 1 utility. .It Cm status -Check the status of the child process. +Check the status of the Varnish cache process. .It Cm stop -Stop the child process. +Stop the Varnish cache process. .It Cm url.purge Ar regexp -Immediately invalidate all documents whos URL matches the specified -regular expression. +Deprecated, see +.Cm purge.url +instead. .It Cm vcl.discard Ar configname Discard the configuration specified by .Ar configname . @@ -583,6 +630,65 @@ The default is .Dv off . .El +.Ss Purge expressions +A purge expression consists of one or more conditions. +A condition consists of a field, an operator, and an argument. +Conditions can be ANDed together with +.Qq && . +.Pp +A field can be any of the variables from VCL, for instance +.Va req.url , +.Va req.http.host +or +.Va obj.set-cookie . +.Pp +Operators are +.Qq == +for direct comparision, +.Qq ~ +for a regular expression match, and +.Qq > +or +.Qq < +for size comparisons. +Prepending an operator with +.Qq \&! +negates the expression. +.Pp +The argument could be a quoted string, a regexp, or an integer. +Integers can have +.Qq KB , +.Qq MB , +.Qq GB +or +.Qq TB +appended for size related fields. +.Pp +Simple example: All requests where +.Va req.url +exactly matches the string +.Va /news +are purged from the cache. +.Bd -literal -offset 4n +req.url == "/news" +.Ed +.Pp +Example: Purge all documents where the name does not end with +.Qq .ogg , +and where the size of the object is greater than 10 megabytes. +.Bd -literal -offset 4n +req.url !~ "\\.ogg$" && obj.size > 10MB +.Ed +.Pp +Example: Purge all documents where the serving host is +.Qq example.com +or +.Qq www.example.com , +and where the Set-Cookie header received from the backend contains +.Qq USERID=1663 . +.Bd -literal -offset 4n +req.http.host ~ "^(www\\.)example.com$" && obj.set-cookie ~ "USERID=1663" +.Ed .Sh SEE ALSO .Xr varnishlog 1 , .Xr varnishhist 1 , @@ -609,4 +715,6 @@ .An Poul-Henning Kamp Aq phk@phk.freebsd.dk in cooperation with Verdens Gang AS and Linpro AS. This manual page was written by -.An Dag-Erling Sm\(/orgrav Aq des@des.no . +.An Dag-Erling Sm\(/orgrav Aq des@des.no +with updates by +.An Stig Sandbeck Mathisen Aq ssm@debian.org Index: bin/varnishd/cache_vrt_esi.c =================================================================== --- bin/varnishd/cache_vrt_esi.c (.../tags/varnish-2.0.4/varnish-cache) +++ bin/varnishd/cache_vrt_esi.c (.../branches/2.0/varnish-cache) @@ -304,8 +304,7 @@ in->b++; if (isspace(*in->b)) { - val->e = val->b = in->b;; - *val->e = '\0'; + val->e = val->b = in->b; in->b++; return (1); } @@ -340,7 +339,6 @@ val->e = in->b; in->b++; } - *val->e = '\0'; return (1); } @@ -352,11 +350,11 @@ esi_handle_include(struct esi_work *ew) { struct esi_bit *eb; - char *p, *q; + char *p, *q, *c; txt t = ew->tag; txt tag; txt val; - unsigned u, v; + unsigned u, v, s; struct ws *ws; if (ew->eb == NULL || ew->eb->include.b != NULL) @@ -371,10 +369,24 @@ continue; if (Tlen(val) == 0) { esi_error(ew, tag.b, Tlen(tag), - "ESI esi:include src attribute withou value"); + "ESI esi:include src attribute without value"); continue; } + /* Wee are saving the original string */ + ws = ew->sp->obj->ws_o; + WS_Assert(ws); + s = 0; + + if ( val.b != val.e ) { + s = Tlen(val) + 1; + c = WS_Alloc(ws, s); + memcpy(c, val.b, Tlen(val)); + val.b = c; + val.e = val.b + s; + *val.e = '\0'; + } + if (Tlen(val) > 7 && !memcmp(val.b, "http://", 7)) { /* Rewrite to Host: header inplace */ eb->host.b = val.b; @@ -406,8 +418,6 @@ /* Use the objects WS to store the result */ CHECK_OBJ_NOTNULL(ew->sp->obj, OBJECT_MAGIC); - ws = ew->sp->obj->ws_o; - WS_Assert(ws); /* Look for the last '/' before a '?' */ q = NULL; @@ -747,13 +757,6 @@ if (ew->incmt) esi_error(ew, ew->t.e, -1, "ESI 1.0 unterminated