Revision: 14408
Author: adrian.chadd
Date: Sat Feb 13 23:34:59 2010
Log: Migrate some of the vary support from store.c to store_vary.c
http://code.google.com/p/lusca-cache/source/detail?r=14408
Added:
/branches/LUSCA_HEAD/src/store_vary.c
/branches/LUSCA_HEAD/src/store_vary.h
Modified:
/branches/LUSCA_HEAD/src/Makefile.am
/branches/LUSCA_HEAD/src/client_side.c
/branches/LUSCA_HEAD/src/client_side_body.c
/branches/LUSCA_HEAD/src/client_side_etag.c
/branches/LUSCA_HEAD/src/protos.h
/branches/LUSCA_HEAD/src/store.c
=======================================
--- /dev/null
+++ /branches/LUSCA_HEAD/src/store_vary.c Sat Feb 13 23:34:59 2010
@@ -0,0 +1,601 @@
+
+#include "squid.h"
+
+typedef struct {
+ StoreEntry *oe;
+ StoreEntry *e;
+ store_client *sc;
+ char *url;
+ char *key;
+ char *vary_headers;
+ char *accept_encoding;
+ char *etag;
+ squid_off_t seen_offset;
+ char *buf;
+ size_t buf_size;
+ size_t buf_offset;
+ int done:1;
+ struct {
+ char *key;
+ char *etag;
+ char *accept_encoding;
+ int this_key:1;
+ int key_used:1;
+ int ignore:1;
+ } current;
+} AddVaryState;
+
+CBDATA_TYPE(AddVaryState);
+static void
+free_AddVaryState(void *data)
+{
+ AddVaryState *state = data;
+ debug(11, 2) ("free_AddVaryState: %p\n", data);
+ if (!EBIT_TEST(state->e->flags, ENTRY_ABORTED)) {
+ storeBuffer(state->e);
+ if (!state->done && state->key) {
+ storeAppendPrintf(state->e, "Key: %s\n", state->key);
+ if (state->accept_encoding)
+ storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->accept_encoding);
+ if (state->etag)
+ storeAppendPrintf(state->e, "ETag: %s\n", state->etag);
+ storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers);
+ }
+ storeTimestampsSet(state->e);
+ storeComplete(state->e);
+ storeTimestampsSet(state->e);
+ storeBufferFlush(state->e);
+ }
+ storeUnlockObject(state->e);
+ state->e = NULL;
+ if (state->sc) {
+ storeClientUnregister(state->sc, state->oe, state);
+ state->sc = NULL;
+ }
+ if (state->oe) {
+ storeUnlockObject(state->oe);
+ state->oe = NULL;
+ }
+ safe_free(state->url);
+ safe_free(state->key);
+ safe_free(state->vary_headers);
+ safe_free(state->accept_encoding);
+ safe_free(state->etag);
+ safe_free(state->current.key);
+ safe_free(state->current.etag);
+ safe_free(state->current.accept_encoding);
+ if (state->buf) {
+ memFreeBuf(state->buf_size, state->buf);
+ state->buf = NULL;
+ }
+}
+
+static int inline
+strmatchbeg(const char *search, const char *match, int maxlen)
+{
+ int mlen = strlen(match);
+ if (maxlen < mlen)
+ return -1;
+ return strncmp(search, match, mlen);
+}
+
+static int inline
+strmatch(const char *search, const char *match, int maxlen)
+{
+ int mlen = strlen(match);
+ if (maxlen < mlen)
+ return -1;
+ return strncmp(search, match, maxlen);
+}
+
+static void
+storeAddVaryFlush(AddVaryState * state)
+{
+ if (state->current.ignore || state->current.key_used) {
+ /* do nothing */
+ } else if (state->current.this_key) {
+ if (state->current.key)
+ storeAppendPrintf(state->e, "Key: %s\n", state->current.key);
+ else
+ storeAppendPrintf(state->e, "Key: %s\n", state->key);
+ if (state->accept_encoding)
+ storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->accept_encoding);
+ if (state->etag)
+ storeAppendPrintf(state->e, "ETag: %s\n", state->etag);
+ storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers);
+ state->done = 1;
+ state->current.key_used = 1;
+ } else if (state->current.key) {
+ storeAppendPrintf(state->e, "Key: %s\n", state->current.key);
+ safe_free(state->current.key);
+ if (state->current.accept_encoding)
+ storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->current.accept_encoding);
+ if (state->current.etag) {
+ storeAppendPrintf(state->e, "ETag: %s\n", state->current.etag);
+ safe_free(state->current.etag);
+ }
+ state->current.key_used = 1;
+ }
+}
+
+static int
+strcmpnull(const char *a, const char *b)
+{
+ if (a && b)
+ return strcmp(a, b);
+ else if (a)
+ return 1;
+ else if (b)
+ return -1;
+ return 0;
+}
+
+#if 0
+static int
+strncmpnull(const char *a, const char *b, size_t n)
+{
+ if (a && b)
+ return strncmp(a, b, n);
+ else if (a)
+ return 1;
+ else if (b)
+ return -1;
+ return 0;
+}
+#endif
+
+static void
+storeAddVaryReadOld(void *data, mem_node_ref nr, ssize_t size)
+{
+ AddVaryState *state = data;
+ size_t l = size + state->buf_offset;
+ char *e;
+ char *p = state->buf;
+ const char *buf = nr.node->data + nr.offset;
+
+ debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d size=%d\n", data, state->seen_offset, (int)
state->buf_offset, (int) size);
+ if (size <= 0) {
+ debug(11, 2) ("storeAddVaryReadOld: DONE\n");
+ cbdataFree(state);
+ goto finish;
+ }
+ assert(size <= nr.node->len);
+ /* size should never exceed what we asked for; just make sure first */
+ assert(size + state->buf_offset <= state->buf_size);
+ /* Copy in the data before we do anything else */
+ memcpy(state->buf + state->buf_offset, nr.node->data + nr.offset,
size);
+
+ if (EBIT_TEST(state->e->flags, ENTRY_ABORTED)) {
+ debug(11, 1) ("storeAddVaryReadOld: New index aborted at %d (%d)\n",
(int) state->seen_offset, (int) size);
+ cbdataFree(state);
+ goto finish;
+ }
+ storeBuffer(state->e);
+ if (state->seen_offset != 0) {
+ state->seen_offset = state->seen_offset + size;
+ } else {
+ int hdr_sz;
+ if (!state->oe->mem_obj->reply)
+ goto invalid_marker_obj;
+ if (!strLen2(state->oe->mem_obj->reply->content_type))
+ goto invalid_marker_obj;
+ if
(strCmp(state->oe->mem_obj->reply->content_type, "x-squid-internal/vary") !=
0) {
+ invalid_marker_obj:
+ debug(11, 2) ("storeAddVaryReadOld: %p (%s) is not a Vary maker
object, ignoring\n", data, storeUrl(state->oe));
+ cbdataFree(state);
+ goto finish;
+ }
+ hdr_sz = state->oe->mem_obj->reply->hdr_sz;
+ state->seen_offset = hdr_sz;
+ if (l >= hdr_sz) {
+ state->seen_offset = l;
+ l -= hdr_sz;
+ p += hdr_sz;
+ } else {
+ l = 0;
+ state->seen_offset = hdr_sz;
+ }
+ }
+ while (l && (e = memchr(p, '\n', l)) != NULL) {
+ int l2;
+ char *p2;
+ if (strmatchbeg(p, "Key: ", l) == 0) {
+ /* key field */
+ p2 = p + 5;
+ l2 = e - p2;
+ if (state->current.this_key) {
+ storeAddVaryFlush(state);
+ }
+ safe_free(state->current.key);
+ safe_free(state->current.etag);
+ safe_free(state->current.accept_encoding);
+ memset(&state->current, 0, sizeof(state->current));
+ state->current.key = xmalloc(l2 + 1);
+ memcpy(state->current.key, p2, l2);
+ state->current.key[l2] = '\0';
+ if (state->key) {
+ if (strcmp(state->current.key, state->key) == 0)
+ state->current.this_key = 1;
+ }
+ debug(11, 3) ("storeAddVaryReadOld: Key: %s%s\n", state->current.key,
state->current.this_key ? " (THIS)" : "");
+#if 0 /* This condition is not correct here.. current.key is always
null */
+ } else if (!state->current.key) {
+ debug(11, 1) ("storeAddVaryReadOld: Unexpected data '%s'\n", p);
+#endif
+ } else if (strmatchbeg(p, "ETag: ", l) == 0) {
+ /* etag field */
+ p2 = p + 6;
+ l2 = e - p2;
+ safe_free(state->current.etag);
+ state->current.etag = xmalloc(l2 + 1);
+ memcpy(state->current.etag, p2, l2);
+ state->current.etag[l2] = '\0';
+ if (state->etag && strcmp(state->current.etag, state->etag) == 0) {
+ if (state->accept_encoding && strcmpnull(state->accept_encoding,
state->current.accept_encoding) != 0) {
+ /* Skip this match. It's not ours */
+ } else if (!state->key) {
+ state->current.this_key = 1;
+ } else if (!state->current.this_key) {
+ /* XXX This could use a bit of protection from corrupted entries
where Key had not been seen before ETag.. */
+ const cache_key *oldkey = storeKeyScan(state->current.key);
+ StoreEntry *old_e = storeGet(oldkey);
+ if (old_e)
+ storeRelease(old_e);
+ if (!state->done) {
+ safe_free(state->current.key);
+ state->current.key = xstrdup(state->key);
+ state->current.this_key = 1;
+ } else {
+ state->current.ignore = 1;
+ }
+ }
+ } else if (state->current.this_key) {
+ state->current.ignore = 1;
+ }
+ debug(11, 2) ("storeAddVaryReadOld: ETag: %s%s%s\n",
state->current.etag, state->current.this_key ? " (THIS)" : "",
state->current.ignore ? " (IGNORE)" : "");
+ } else if (!state->current.ignore && strmatchbeg(p, "VaryData: ", l) ==
0) {
+ /* vary field */
+ p2 = p + 10;
+ l2 = e - p2;
+ storeAddVaryFlush(state);
+ if (strmatch(p2, state->vary_headers, l2) != 0) {
+ storeAppend(state->e, p, e - p + 1);
+ debug(11, 3) ("storeAddVaryReadOld: %s\n", p);
+ }
+ } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) {
+ p2 = p + 17;
+ l2 = e - p2;
+ safe_free(state->current.accept_encoding);
+ state->current.accept_encoding = xmalloc(l2 + 1);
+ memcpy(state->current.accept_encoding, p2, l2);
+ state->current.accept_encoding[l2] = '\0';
+ }
+ e += 1;
+ l -= e - p;
+ p = e;
+ if (l == 0)
+ break;
+ assert(p <= (state->buf + state->buf_offset + size));
+ }
+ state->buf_offset = l;
+ if (l && p != state->buf)
+ memmove(state->buf, p, l);
+ if (state->buf_offset == state->buf_size) {
+ /* Oops.. the buffer size is not sufficient. Grow */
+ if (state->buf_size < 65536) {
+ debug(11, 2) ("storeAddVaryReadOld: Increasing entry buffer size
to %d\n", (int) state->buf_size * 2);
+ state->buf = memReallocBuf(state->buf, state->buf_size * 2,
&state->buf_size);
+ } else {
+ /* This does not look good. Bail out. This should match the size <= 0
case above */
+ debug(11, 1) ("storeAddVaryReadOld: Buffer very large and still can't
fit the data.. bailing out\n");
+ cbdataFree(state);
+ goto finish;
+ }
+ }
+ debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset);
+ storeBufferFlush(state->e);
+ storeClientRef(state->sc, state->oe,
+ state->seen_offset,
+ state->seen_offset,
+ state->buf_size - state->buf_offset,
+ storeAddVaryReadOld,
+ state);
+ finish:
+ stmemNodeUnref(&nr);
+ buf = NULL;
+}
+
+/*
+ * Adds/updates a Vary record.
+ * For updates only one of key or etag needs to be specified
+ * At leas one of key or etag must be specified, preferably both.
+ */
+void
+storeAddVary(const char *url, method_t * method, const cache_key * key,
const char *etag, const char *vary, const char *vary_headers, const char
*accept_encoding)
+{
+ AddVaryState *state;
+ request_flags flags = null_request_flags;
+ CBDATA_INIT_TYPE_FREECB(AddVaryState, free_AddVaryState);
+ state = cbdataAlloc(AddVaryState);
+ state->url = xstrdup(url);
+ if (key)
+ state->key = xstrdup(storeKeyText(key));
+ state->vary_headers = xstrdup(vary_headers);
+ if (accept_encoding)
+ state->accept_encoding = xstrdup(accept_encoding);
+ if (etag)
+ state->etag = xstrdup(etag);
+ state->oe = storeGetPublic(url, method);
+ debug(11, 2) ("storeAddVary: %s (%s) %s %s\n",
+ state->url, state->key, state->vary_headers, state->etag);
+ if (state->oe)
+ storeLockObject(state->oe);
+ flags.cachable = 1;
+ state->e = storeCreateEntry(url, flags, method);
+ httpReplySetHeaders(state->e->mem_obj->reply, HTTP_OK, "Internal
marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
+ httpHeaderPutStr(&state->e->mem_obj->reply->header, HDR_VARY, vary);
+ storeSetPublicKey(state->e);
+ storeBuffer(state->e);
+ httpReplySwapOut(state->e->mem_obj->reply, state->e);
+ if (state->oe) {
+ /* Here we need to tack on the old etag/vary information, and we should
+ * merge, clean up etc
+ *
+ * Suggestion:
+ * swap in the old file, looking for ETag, Key and VaryData. If a match
is
+ * found then
+ * - on ETag, update the key, and expire the old object if different
+ * - on Key, drop the old data if ETag is different, else nothing
+ * - on VaryData, remove the line if a different key. If this makes
+ * the searched key "empty" then expire it and remove it from the
+ * map
+ * - VaryData is added last in the Key record it corresponds to (after
+ * modifications above)
+ */
+ /* Swap in the dummy Vary object */
+ if (!state->oe->mem_obj) {
+ storeCreateMemObject(state->oe, state->url);
+ state->oe->mem_obj->method = method;
+ }
+ state->sc = storeClientRegister(state->oe, state);
+ state->buf = memAllocBuf(4096, &state->buf_size);
+ debug(11, 3) ("storeAddVary: %p\n", state);
+ storeClientRef(state->sc, state->oe, 0, 0,
+ state->buf_size,
+ storeAddVaryReadOld,
+ state);
+ return;
+ } else {
+ cbdataFree(state);
+ }
+}
+
+static MemPool *VaryData_pool = NULL;
+
+void
+storeLocateVaryDone(VaryData * data)
+{
+ int i;
+ safe_free(data->key);
+ data->etag = NULL; /* points to an entry in etags */
+ for (i = 0; i < data->etags.count; i++) {
+ safe_free(data->etags.items[i]);
+ }
+ arrayClean(&data->etags);
+ memPoolFree(VaryData_pool, data);
+}
+
+typedef struct {
+ VaryData *data;
+ STLVCB *callback;
+ void *callback_data;
+ StoreEntry *e;
+ store_client *sc;
+ char *buf;
+ size_t buf_size;
+ size_t buf_offset;
+ char *vary_data;
+ String accept_encoding;
+ squid_off_t seen_offset;
+ struct {
+ int ignore;
+ int encoding_ok;
+ char *key;
+ char *etag;
+ } current;
+} LocateVaryState;
+
+CBDATA_TYPE(LocateVaryState);
+
+static void
+storeLocateVaryCallback(LocateVaryState * state)
+{
+ if (cbdataValid(state->callback_data)) {
+ VaryData *data = state->data;
+ if (data->key || data->etags.count) {
+ state->callback(data, state->callback_data);
+ state->data = NULL; /* now owned by the caller */
+ } else {
+ state->callback(NULL, state->callback_data);
+ }
+ }
+ cbdataUnlock(state->callback_data);
+ if (state->data) {
+ storeLocateVaryDone(state->data);
+ state->data = NULL;
+ }
+ state->current.etag = NULL; /* shared by data->entries[x] */
+ safe_free(state->vary_data);
+ stringClean(&state->accept_encoding);
+ safe_free(state->current.key);
+ if (state->sc) {
+ storeClientUnregister(state->sc, state->e, state);
+ state->sc = NULL;
+ }
+ if (state->e) {
+ storeUnlockObject(state->e);
+ state->e = NULL;
+ }
+ if (state->buf) {
+ memFreeBuf(state->buf_size, state->buf);
+ state->buf = NULL;
+ }
+ cbdataFree(state);
+ debug(11, 2) ("storeLocateVaryCallback: DONE\n");
+}
+
+static void
+storeLocateVaryRead(void *data, mem_node_ref nr, ssize_t size)
+{
+ LocateVaryState *state = data;
+ char *e;
+ char *p = state->buf;
+ size_t l = size + state->buf_offset;
+ debug(11, 3) ("storeLocateVaryRead: %s %p seen_offset=%"
PRINTF_OFF_T " buf_offset=%d size=%d\n", state->vary_data, data,
state->seen_offset, (int) state->buf_offset, (int) size);
+ if (size <= 0) {
+ storeLocateVaryCallback(state);
+ goto finish;
+ }
+ assert(size <= nr.node->len);
+ /* size should never exceed what we asked for; just make sure first */
+ assert(size + state->buf_offset <= state->buf_size);
+ /* Copy in the data before we do anything else */
+ if (size > 0)
+ memcpy(state->buf + state->buf_offset, nr.node->data + nr.offset, size);
+
+ state->seen_offset = state->seen_offset + size;
+ while ((e = memchr(p, '\n', l)) != NULL) {
+ int l2;
+ char *p2;
+ if (strmatchbeg(p, "Key: ", l) == 0) {
+ /* key field */
+ p2 = p + 5;
+ l2 = e - p2;
+ safe_free(state->current.key);
+ state->current.etag = NULL; /* saved in data.etags[] */
+ state->current.ignore = 0;
+ state->current.encoding_ok = strIsNotNull(state->accept_encoding);
+ state->current.key = xmalloc(l2 + 1);
+ memcpy(state->current.key, p2, l2);
+ state->current.key[l2] = '\0';
+ debug(11, 3) ("storeLocateVaryRead: Key: %s\n", state->current.key);
+ } else if (state->current.ignore) {
+ /* Skip this entry */
+ } else if (!state->current.key) {
+ char *t1 = xstrndup(p, e - p);
+ char *t2 = xstrndup(state->buf, size + state->buf_offset);
+ debug(11, 1) ("storeLocateVaryRead: Unexpected data '%s' in '%s'",
t1, t2);
+ safe_free(t2);
+ safe_free(t1);
+ } else if (strmatchbeg(p, "ETag: ", l) == 0) {
+ /* etag field */
+ char *etag;
+ if (state->current.encoding_ok) {
+ p2 = p + 6;
+ l2 = e - p2;
+ etag = xmalloc(l2 + 1);
+ memcpy(etag, p2, l2);
+ etag[l2] = '\0';
+ state->current.etag = etag;
+ arrayAppend(&state->data->etags, etag);
+ debug(11, 3) ("storeLocateVaryRead: ETag: %s\n", etag);
+ } else {
+ state->current.ignore = 1;
+ }
+ } else if (strmatchbeg(p, "VaryData: ", l) == 0) {
+ /* vary field */
+ p2 = p + 10;
+ l2 = e - p2;
+ if (strmatch(p2, state->vary_data, l2) == 0) {
+ /* A matching vary header found */
+ safe_free(state->data->key);
+ state->data->key = xstrdup(state->current.key);
+ state->data->etag = state->current.etag;
+ debug(11, 2) ("storeLocateVaryRead: MATCH! %s %s\n", state->current.key,
state->current.etag);
+ }
+ } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) {
+ p2 = p + 17;
+ l2 = e - p2;
+ /*
+ * This used to use strncmpnull(). It returned 0 on both string
equality -and-
+ * both strings being null. Hm! What does this mean if
state->accept_encoding String is NULL?
+ * Could p2 ever be NULL? No; it'll be pointing to -something-.
+ */
+#if 0
+ if (strncmpnull(state->accept_encoding, p2, l2) == 0 &&
state->accept_encoding[l2] == '\0') {
+#endif
+ if (strNCmpNull(&state->accept_encoding, p2, l2) == 0 &&
strLen2(state->accept_encoding) == l2) {
+ state->current.encoding_ok = 1;
+ }
+ }
+ e += 1;
+ l -= e - p;
+ p = e;
+ if (l == 0)
+ break;
+ assert(l > 0);
+ assert(p < (state->buf + state->buf_offset + size));
+ }
+ state->buf_offset = l;
+ if (l)
+ memmove(state->buf, p, l);
+ if (state->buf_offset == state->buf_size) {
+ /* Oops.. the buffer size is not sufficient. Grow */
+ if (state->buf_size < 65536) {
+ debug(11, 2) ("storeLocateVaryRead: Increasing entry buffer size
to %d\n", (int) state->buf_size * 2);
+ state->buf = memReallocBuf(state->buf, state->buf_size * 2,
&state->buf_size);
+ } else {
+ /* This does not look good. Bail out. This should match the size <= 0
case above */
+ debug(11, 1) ("storeLocateVaryRead: Buffer very large and still can't
fit the data.. bailing out\n");
+ storeLocateVaryCallback(state);
+ goto finish;
+ }
+ }
+ debug(11, 3) ("storeLocateVaryRead: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset);
+ storeClientRef(state->sc, state->e,
+ state->seen_offset,
+ state->seen_offset,
+ state->buf_size - state->buf_offset,
+ storeLocateVaryRead,
+ state);
+ finish:
+ stmemNodeUnref(&nr);
+}
+
+void
+storeLocateVary(StoreEntry * e, int offset, const char *vary_data, String
accept_encoding, STLVCB * callback, void *cbdata)
+{
+ LocateVaryState *state;
+ debug(11, 2) ("storeLocateVary: %s\n", vary_data);
+ CBDATA_INIT_TYPE(LocateVaryState);
+ if (!VaryData_pool)
+ VaryData_pool = memPoolCreate("VaryData", sizeof(VaryData));
+ state = cbdataAlloc(LocateVaryState);
+ state->vary_data = xstrdup(vary_data);
+ if (strIsNotNull(accept_encoding))
+ state->accept_encoding = stringDup(&accept_encoding);
+ state->data = memPoolAlloc(VaryData_pool);
+ state->e = e;
+ storeLockObject(state->e);
+ state->callback_data = cbdata;
+ cbdataLock(cbdata);
+ state->callback = callback;
+ state->buf = memAllocBuf(4096, &state->buf_size);
+ state->sc = storeClientRegister(state->e, state);
+ state->seen_offset = offset;
+ if (!strLen2(e->mem_obj->reply->content_type) ||
strCmp(e->mem_obj->reply->content_type, "x-squid-internal/vary") != 0) {
+ /* This is not our Vary marker object. Bail out. */
+ debug(33, 1) ("storeLocateVary: Not our vary marker object, %s
= '%s', '%s'/'%.*s'\n",
+ storeKeyText(e->hash.key), e->mem_obj->url, vary_data,
+ strLen2(accept_encoding) ? strLen2(accept_encoding) : 1,
+ strBuf2(accept_encoding) ? strBuf2(accept_encoding) : "-");
+ storeLocateVaryCallback(state);
+ return;
+ }
+ storeClientRef(state->sc, state->e,
+ state->seen_offset,
+ state->seen_offset,
+ state->buf_size,
+ storeLocateVaryRead,
+ state);
+}
=======================================
--- /dev/null
+++ /branches/LUSCA_HEAD/src/store_vary.h Sat Feb 13 23:34:59 2010
@@ -0,0 +1,11 @@
+#ifndef __STORE_VARY_H__
+#define __STORE_VARY_H__
+
+extern void storeLocateVaryDone(VaryData * data);
+extern void storeLocateVary(StoreEntry * e, int offset, const char
*vary_data,
+ String accept_encoding, STLVCB * callback, void *cbdata);
+extern void storeAddVary(const char *url, method_t * method, const
cache_key * key,
+ const char *etag, const char *vary, const char *vary_headers,
+ const char *accept_encoding);
+
+#endif
=======================================
--- /branches/LUSCA_HEAD/src/Makefile.am Sat Feb 13 23:01:13 2010
+++ /branches/LUSCA_HEAD/src/Makefile.am Sat Feb 13 23:34:59 2010
@@ -205,6 +205,7 @@
store_swapmeta.c \
store_swapout.c \
store_update.c \
+ store_vary.c \
structs.h \
tools.c \
typedefs.h \
=======================================
--- /branches/LUSCA_HEAD/src/client_side.c Sat Feb 13 23:30:54 2010
+++ /branches/LUSCA_HEAD/src/client_side.c Sat Feb 13 23:34:59 2010
@@ -45,6 +45,8 @@
#include "client_side.h"
+#include "store_vary.h"
+
#if LINGERING_CLOSE
#define comm_close comm_lingering_close
#endif
=======================================
--- /branches/LUSCA_HEAD/src/client_side_body.c Thu Feb 11 23:26:11 2010
+++ /branches/LUSCA_HEAD/src/client_side_body.c Sat Feb 13 23:34:59 2010
@@ -1,5 +1,6 @@
#include "squid.h"
#include "client_side_body.h"
+#include "client_side.h"
static void
clientEatRequestBodyHandler(char *buf, ssize_t size, void *data)
=======================================
--- /branches/LUSCA_HEAD/src/client_side_etag.c Sat Feb 13 23:32:26 2010
+++ /branches/LUSCA_HEAD/src/client_side_etag.c Sat Feb 13 23:34:59 2010
@@ -2,6 +2,7 @@
#include "client_side_etag.h"
#include "client_side.h"
+#include "store_vary.h"
static void
clientHandleETagMiss(clientHttpRequest * http)
=======================================
--- /branches/LUSCA_HEAD/src/protos.h Thu Feb 11 01:39:39 2010
+++ /branches/LUSCA_HEAD/src/protos.h Sat Feb 13 23:34:59 2010
@@ -1052,11 +1052,6 @@
extern void errorMapInit(void);
extern int errorMapStart(const errormap * map, request_t * req, HttpReply
* reply, const char *aclname, ERRMAPCB * callback, void *data);
-/* ETag support */
-void storeLocateVaryDone(VaryData * data);
-void storeLocateVary(StoreEntry * e, int offset, const char *vary_data,
String accept_encoding, STLVCB * callback, void *cbdata);
-void storeAddVary(const char *url, method_t * method, const cache_key *
key, const char *etag, const char *vary, const char *vary_headers, const
char *accept_encoding);
-
rewritetoken *rewriteURLCompile(const char *urlfmt);
char *internalRedirectProcessURL(clientHttpRequest * req, rewritetoken *
head);
=======================================
--- /branches/LUSCA_HEAD/src/store.c Mon Oct 26 23:58:33 2009
+++ /branches/LUSCA_HEAD/src/store.c Sat Feb 13 23:34:59 2010
@@ -34,6 +34,7 @@
*/
#include "squid.h"
+#include "store_vary.h"
#define REBUILD_TIMESTAMP_DELTA_MAX 2
@@ -486,75 +487,6 @@
EBIT_SET(e->flags, KEY_PRIVATE);
storeHashInsert(e, newkey);
}
-
-typedef struct {
- StoreEntry *oe;
- StoreEntry *e;
- store_client *sc;
- char *url;
- char *key;
- char *vary_headers;
- char *accept_encoding;
- char *etag;
- squid_off_t seen_offset;
- char *buf;
- size_t buf_size;
- size_t buf_offset;
- int done:1;
- struct {
- char *key;
- char *etag;
- char *accept_encoding;
- int this_key:1;
- int key_used:1;
- int ignore:1;
- } current;
-} AddVaryState;
-
-CBDATA_TYPE(AddVaryState);
-static void
-free_AddVaryState(void *data)
-{
- AddVaryState *state = data;
- debug(11, 2) ("free_AddVaryState: %p\n", data);
- if (!EBIT_TEST(state->e->flags, ENTRY_ABORTED)) {
- storeBuffer(state->e);
- if (!state->done && state->key) {
- storeAppendPrintf(state->e, "Key: %s\n", state->key);
- if (state->accept_encoding)
- storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->accept_encoding);
- if (state->etag)
- storeAppendPrintf(state->e, "ETag: %s\n", state->etag);
- storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers);
- }
- storeTimestampsSet(state->e);
- storeComplete(state->e);
- storeTimestampsSet(state->e);
- storeBufferFlush(state->e);
- }
- storeUnlockObject(state->e);
- state->e = NULL;
- if (state->sc) {
- storeClientUnregister(state->sc, state->oe, state);
- state->sc = NULL;
- }
- if (state->oe) {
- storeUnlockObject(state->oe);
- state->oe = NULL;
- }
- safe_free(state->url);
- safe_free(state->key);
- safe_free(state->vary_headers);
- safe_free(state->accept_encoding);
- safe_free(state->etag);
- safe_free(state->current.key);
- safe_free(state->current.etag);
- safe_free(state->current.accept_encoding);
- if (state->buf) {
- memFreeBuf(state->buf_size, state->buf);
- state->buf = NULL;
- }
-}
static int inline
strmatchbeg(const char *search, const char *match, int maxlen)
@@ -573,518 +505,6 @@
return -1;
return strncmp(search, match, maxlen);
}
-
-static void
-storeAddVaryFlush(AddVaryState * state)
-{
- if (state->current.ignore || state->current.key_used) {
- /* do nothing */
- } else if (state->current.this_key) {
- if (state->current.key)
- storeAppendPrintf(state->e, "Key: %s\n", state->current.key);
- else
- storeAppendPrintf(state->e, "Key: %s\n", state->key);
- if (state->accept_encoding)
- storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->accept_encoding);
- if (state->etag)
- storeAppendPrintf(state->e, "ETag: %s\n", state->etag);
- storeAppendPrintf(state->e, "VaryData: %s\n", state->vary_headers);
- state->done = 1;
- state->current.key_used = 1;
- } else if (state->current.key) {
- storeAppendPrintf(state->e, "Key: %s\n", state->current.key);
- safe_free(state->current.key);
- if (state->current.accept_encoding)
- storeAppendPrintf(state->e, "Accept-Encoding: %s\n",
state->current.accept_encoding);
- if (state->current.etag) {
- storeAppendPrintf(state->e, "ETag: %s\n", state->current.etag);
- safe_free(state->current.etag);
- }
- state->current.key_used = 1;
- }
-}
-
-static int
-strcmpnull(const char *a, const char *b)
-{
- if (a && b)
- return strcmp(a, b);
- else if (a)
- return 1;
- else if (b)
- return -1;
- return 0;
-}
-
-#if 0
-static int
-strncmpnull(const char *a, const char *b, size_t n)
-{
- if (a && b)
- return strncmp(a, b, n);
- else if (a)
- return 1;
- else if (b)
- return -1;
- return 0;
-}
-#endif
-
-static void
-storeAddVaryReadOld(void *data, mem_node_ref nr, ssize_t size)
-{
- AddVaryState *state = data;
- size_t l = size + state->buf_offset;
- char *e;
- char *p = state->buf;
- const char *buf = nr.node->data + nr.offset;
-
- debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d size=%d\n", data, state->seen_offset, (int)
state->buf_offset, (int) size);
- if (size <= 0) {
- debug(11, 2) ("storeAddVaryReadOld: DONE\n");
- cbdataFree(state);
- goto finish;
- }
- assert(size <= nr.node->len);
- /* size should never exceed what we asked for; just make sure first */
- assert(size + state->buf_offset <= state->buf_size);
- /* Copy in the data before we do anything else */
- memcpy(state->buf + state->buf_offset, nr.node->data + nr.offset,
size);
-
- if (EBIT_TEST(state->e->flags, ENTRY_ABORTED)) {
- debug(11, 1) ("storeAddVaryReadOld: New index aborted at %d (%d)\n",
(int) state->seen_offset, (int) size);
- cbdataFree(state);
- goto finish;
- }
- storeBuffer(state->e);
- if (state->seen_offset != 0) {
- state->seen_offset = state->seen_offset + size;
- } else {
- int hdr_sz;
- if (!state->oe->mem_obj->reply)
- goto invalid_marker_obj;
- if (!strLen2(state->oe->mem_obj->reply->content_type))
- goto invalid_marker_obj;
- if
(strCmp(state->oe->mem_obj->reply->content_type, "x-squid-internal/vary") !=
0) {
- invalid_marker_obj:
- debug(11, 2) ("storeAddVaryReadOld: %p (%s) is not a Vary maker
object, ignoring\n", data, storeUrl(state->oe));
- cbdataFree(state);
- goto finish;
- }
- hdr_sz = state->oe->mem_obj->reply->hdr_sz;
- state->seen_offset = hdr_sz;
- if (l >= hdr_sz) {
- state->seen_offset = l;
- l -= hdr_sz;
- p += hdr_sz;
- } else {
- l = 0;
- state->seen_offset = hdr_sz;
- }
- }
- while (l && (e = memchr(p, '\n', l)) != NULL) {
- int l2;
- char *p2;
- if (strmatchbeg(p, "Key: ", l) == 0) {
- /* key field */
- p2 = p + 5;
- l2 = e - p2;
- if (state->current.this_key) {
- storeAddVaryFlush(state);
- }
- safe_free(state->current.key);
- safe_free(state->current.etag);
- safe_free(state->current.accept_encoding);
- memset(&state->current, 0, sizeof(state->current));
- state->current.key = xmalloc(l2 + 1);
- memcpy(state->current.key, p2, l2);
- state->current.key[l2] = '\0';
- if (state->key) {
- if (strcmp(state->current.key, state->key) == 0)
- state->current.this_key = 1;
- }
- debug(11, 3) ("storeAddVaryReadOld: Key: %s%s\n", state->current.key,
state->current.this_key ? " (THIS)" : "");
-#if 0 /* This condition is not correct here.. current.key is always
null */
- } else if (!state->current.key) {
- debug(11, 1) ("storeAddVaryReadOld: Unexpected data '%s'\n", p);
-#endif
- } else if (strmatchbeg(p, "ETag: ", l) == 0) {
- /* etag field */
- p2 = p + 6;
- l2 = e - p2;
- safe_free(state->current.etag);
- state->current.etag = xmalloc(l2 + 1);
- memcpy(state->current.etag, p2, l2);
- state->current.etag[l2] = '\0';
- if (state->etag && strcmp(state->current.etag, state->etag) == 0) {
- if (state->accept_encoding && strcmpnull(state->accept_encoding,
state->current.accept_encoding) != 0) {
- /* Skip this match. It's not ours */
- } else if (!state->key) {
- state->current.this_key = 1;
- } else if (!state->current.this_key) {
- /* XXX This could use a bit of protection from corrupted entries
where Key had not been seen before ETag.. */
- const cache_key *oldkey = storeKeyScan(state->current.key);
- StoreEntry *old_e = storeGet(oldkey);
- if (old_e)
- storeRelease(old_e);
- if (!state->done) {
- safe_free(state->current.key);
- state->current.key = xstrdup(state->key);
- state->current.this_key = 1;
- } else {
- state->current.ignore = 1;
- }
- }
- } else if (state->current.this_key) {
- state->current.ignore = 1;
- }
- debug(11, 2) ("storeAddVaryReadOld: ETag: %s%s%s\n",
state->current.etag, state->current.this_key ? " (THIS)" : "",
state->current.ignore ? " (IGNORE)" : "");
- } else if (!state->current.ignore && strmatchbeg(p, "VaryData: ", l) ==
0) {
- /* vary field */
- p2 = p + 10;
- l2 = e - p2;
- storeAddVaryFlush(state);
- if (strmatch(p2, state->vary_headers, l2) != 0) {
- storeAppend(state->e, p, e - p + 1);
- debug(11, 3) ("storeAddVaryReadOld: %s\n", p);
- }
- } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) {
- p2 = p + 17;
- l2 = e - p2;
- safe_free(state->current.accept_encoding);
- state->current.accept_encoding = xmalloc(l2 + 1);
- memcpy(state->current.accept_encoding, p2, l2);
- state->current.accept_encoding[l2] = '\0';
- }
- e += 1;
- l -= e - p;
- p = e;
- if (l == 0)
- break;
- assert(p <= (state->buf + state->buf_offset + size));
- }
- state->buf_offset = l;
- if (l && p != state->buf)
- memmove(state->buf, p, l);
- if (state->buf_offset == state->buf_size) {
- /* Oops.. the buffer size is not sufficient. Grow */
- if (state->buf_size < 65536) {
- debug(11, 2) ("storeAddVaryReadOld: Increasing entry buffer size
to %d\n", (int) state->buf_size * 2);
- state->buf = memReallocBuf(state->buf, state->buf_size * 2,
&state->buf_size);
- } else {
- /* This does not look good. Bail out. This should match the size <= 0
case above */
- debug(11, 1) ("storeAddVaryReadOld: Buffer very large and still can't
fit the data.. bailing out\n");
- cbdataFree(state);
- goto finish;
- }
- }
- debug(11, 3) ("storeAddVaryReadOld: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset);
- storeBufferFlush(state->e);
- storeClientRef(state->sc, state->oe,
- state->seen_offset,
- state->seen_offset,
- state->buf_size - state->buf_offset,
- storeAddVaryReadOld,
- state);
- finish:
- stmemNodeUnref(&nr);
- buf = NULL;
-}
-
-/*
- * Adds/updates a Vary record.
- * For updates only one of key or etag needs to be specified
- * At leas one of key or etag must be specified, preferably both.
- */
-void
-storeAddVary(const char *url, method_t * method, const cache_key * key,
const char *etag, const char *vary, const char *vary_headers, const char
*accept_encoding)
-{
- AddVaryState *state;
- request_flags flags = null_request_flags;
- CBDATA_INIT_TYPE_FREECB(AddVaryState, free_AddVaryState);
- state = cbdataAlloc(AddVaryState);
- state->url = xstrdup(url);
- if (key)
- state->key = xstrdup(storeKeyText(key));
- state->vary_headers = xstrdup(vary_headers);
- if (accept_encoding)
- state->accept_encoding = xstrdup(accept_encoding);
- if (etag)
- state->etag = xstrdup(etag);
- state->oe = storeGetPublic(url, method);
- debug(11, 2) ("storeAddVary: %s (%s) %s %s\n",
- state->url, state->key, state->vary_headers, state->etag);
- if (state->oe)
- storeLockObject(state->oe);
- flags.cachable = 1;
- state->e = storeCreateEntry(url, flags, method);
- httpReplySetHeaders(state->e->mem_obj->reply, HTTP_OK, "Internal
marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
- httpHeaderPutStr(&state->e->mem_obj->reply->header, HDR_VARY, vary);
- storeSetPublicKey(state->e);
- storeBuffer(state->e);
- httpReplySwapOut(state->e->mem_obj->reply, state->e);
- if (state->oe) {
- /* Here we need to tack on the old etag/vary information, and we should
- * merge, clean up etc
- *
- * Suggestion:
- * swap in the old file, looking for ETag, Key and VaryData. If a match
is
- * found then
- * - on ETag, update the key, and expire the old object if different
- * - on Key, drop the old data if ETag is different, else nothing
- * - on VaryData, remove the line if a different key. If this makes
- * the searched key "empty" then expire it and remove it from the
- * map
- * - VaryData is added last in the Key record it corresponds to (after
- * modifications above)
- */
- /* Swap in the dummy Vary object */
- if (!state->oe->mem_obj) {
- storeCreateMemObject(state->oe, state->url);
- state->oe->mem_obj->method = method;
- }
- state->sc = storeClientRegister(state->oe, state);
- state->buf = memAllocBuf(4096, &state->buf_size);
- debug(11, 3) ("storeAddVary: %p\n", state);
- storeClientRef(state->sc, state->oe, 0, 0,
- state->buf_size,
- storeAddVaryReadOld,
- state);
- return;
- } else {
- cbdataFree(state);
- }
-}
-
-static MemPool *VaryData_pool = NULL;
-
-void
-storeLocateVaryDone(VaryData * data)
-{
- int i;
- safe_free(data->key);
- data->etag = NULL; /* points to an entry in etags */
- for (i = 0; i < data->etags.count; i++) {
- safe_free(data->etags.items[i]);
- }
- arrayClean(&data->etags);
- memPoolFree(VaryData_pool, data);
-}
-
-typedef struct {
- VaryData *data;
- STLVCB *callback;
- void *callback_data;
- StoreEntry *e;
- store_client *sc;
- char *buf;
- size_t buf_size;
- size_t buf_offset;
- char *vary_data;
- String accept_encoding;
- squid_off_t seen_offset;
- struct {
- int ignore;
- int encoding_ok;
- char *key;
- char *etag;
- } current;
-} LocateVaryState;
-
-CBDATA_TYPE(LocateVaryState);
-
-static void
-storeLocateVaryCallback(LocateVaryState * state)
-{
- if (cbdataValid(state->callback_data)) {
- VaryData *data = state->data;
- if (data->key || data->etags.count) {
- state->callback(data, state->callback_data);
- state->data = NULL; /* now owned by the caller */
- } else {
- state->callback(NULL, state->callback_data);
- }
- }
- cbdataUnlock(state->callback_data);
- if (state->data) {
- storeLocateVaryDone(state->data);
- state->data = NULL;
- }
- state->current.etag = NULL; /* shared by data->entries[x] */
- safe_free(state->vary_data);
- stringClean(&state->accept_encoding);
- safe_free(state->current.key);
- if (state->sc) {
- storeClientUnregister(state->sc, state->e, state);
- state->sc = NULL;
- }
- if (state->e) {
- storeUnlockObject(state->e);
- state->e = NULL;
- }
- if (state->buf) {
- memFreeBuf(state->buf_size, state->buf);
- state->buf = NULL;
- }
- cbdataFree(state);
- debug(11, 2) ("storeLocateVaryCallback: DONE\n");
-}
-
-static void
-storeLocateVaryRead(void *data, mem_node_ref nr, ssize_t size)
-{
- LocateVaryState *state = data;
- char *e;
- char *p = state->buf;
- size_t l = size + state->buf_offset;
- debug(11, 3) ("storeLocateVaryRead: %s %p seen_offset=%"
PRINTF_OFF_T " buf_offset=%d size=%d\n", state->vary_data, data,
state->seen_offset, (int) state->buf_offset, (int) size);
- if (size <= 0) {
- storeLocateVaryCallback(state);
- goto finish;
- }
- assert(size <= nr.node->len);
- /* size should never exceed what we asked for; just make sure first */
- assert(size + state->buf_offset <= state->buf_size);
- /* Copy in the data before we do anything else */
- if (size > 0)
- memcpy(state->buf + state->buf_offset, nr.node->data + nr.offset, size);
-
- state->seen_offset = state->seen_offset + size;
- while ((e = memchr(p, '\n', l)) != NULL) {
- int l2;
- char *p2;
- if (strmatchbeg(p, "Key: ", l) == 0) {
- /* key field */
- p2 = p + 5;
- l2 = e - p2;
- safe_free(state->current.key);
- state->current.etag = NULL; /* saved in data.etags[] */
- state->current.ignore = 0;
- state->current.encoding_ok = strIsNotNull(state->accept_encoding);
- state->current.key = xmalloc(l2 + 1);
- memcpy(state->current.key, p2, l2);
- state->current.key[l2] = '\0';
- debug(11, 3) ("storeLocateVaryRead: Key: %s\n", state->current.key);
- } else if (state->current.ignore) {
- /* Skip this entry */
- } else if (!state->current.key) {
- char *t1 = xstrndup(p, e - p);
- char *t2 = xstrndup(state->buf, size + state->buf_offset);
- debug(11, 1) ("storeLocateVaryRead: Unexpected data '%s' in '%s'",
t1, t2);
- safe_free(t2);
- safe_free(t1);
- } else if (strmatchbeg(p, "ETag: ", l) == 0) {
- /* etag field */
- char *etag;
- if (state->current.encoding_ok) {
- p2 = p + 6;
- l2 = e - p2;
- etag = xmalloc(l2 + 1);
- memcpy(etag, p2, l2);
- etag[l2] = '\0';
- state->current.etag = etag;
- arrayAppend(&state->data->etags, etag);
- debug(11, 3) ("storeLocateVaryRead: ETag: %s\n", etag);
- } else {
- state->current.ignore = 1;
- }
- } else if (strmatchbeg(p, "VaryData: ", l) == 0) {
- /* vary field */
- p2 = p + 10;
- l2 = e - p2;
- if (strmatch(p2, state->vary_data, l2) == 0) {
- /* A matching vary header found */
- safe_free(state->data->key);
- state->data->key = xstrdup(state->current.key);
- state->data->etag = state->current.etag;
- debug(11, 2) ("storeLocateVaryRead: MATCH! %s %s\n", state->current.key,
state->current.etag);
- }
- } else if (strmatchbeg(p, "Accept-Encoding: ", l) == 0) {
- p2 = p + 17;
- l2 = e - p2;
- /*
- * This used to use strncmpnull(). It returned 0 on both string
equality -and-
- * both strings being null. Hm! What does this mean if
state->accept_encoding String is NULL?
- * Could p2 ever be NULL? No; it'll be pointing to -something-.
- */
-#if 0
- if (strncmpnull(state->accept_encoding, p2, l2) == 0 &&
state->accept_encoding[l2] == '\0') {
-#endif
- if (strNCmpNull(&state->accept_encoding, p2, l2) == 0 &&
strLen2(state->accept_encoding) == l2) {
- state->current.encoding_ok = 1;
- }
- }
- e += 1;
- l -= e - p;
- p = e;
- if (l == 0)
- break;
- assert(l > 0);
- assert(p < (state->buf + state->buf_offset + size));
- }
- state->buf_offset = l;
- if (l)
- memmove(state->buf, p, l);
- if (state->buf_offset == state->buf_size) {
- /* Oops.. the buffer size is not sufficient. Grow */
- if (state->buf_size < 65536) {
- debug(11, 2) ("storeLocateVaryRead: Increasing entry buffer size
to %d\n", (int) state->buf_size * 2);
- state->buf = memReallocBuf(state->buf, state->buf_size * 2,
&state->buf_size);
- } else {
- /* This does not look good. Bail out. This should match the size <= 0
case above */
- debug(11, 1) ("storeLocateVaryRead: Buffer very large and still can't
fit the data.. bailing out\n");
- storeLocateVaryCallback(state);
- goto finish;
- }
- }
- debug(11, 3) ("storeLocateVaryRead: %p seen_offset=%" PRINTF_OFF_T "
buf_offset=%d\n", data, state->seen_offset, (int) state->buf_offset);
- storeClientRef(state->sc, state->e,
- state->seen_offset,
- state->seen_offset,
- state->buf_size - state->buf_offset,
- storeLocateVaryRead,
- state);
- finish:
- stmemNodeUnref(&nr);
-}
-
-void
-storeLocateVary(StoreEntry * e, int offset, const char *vary_data, String
accept_encoding, STLVCB * callback, void *cbdata)
-{
- LocateVaryState *state;
- debug(11, 2) ("storeLocateVary: %s\n", vary_data);
- CBDATA_INIT_TYPE(LocateVaryState);
- if (!VaryData_pool)
- VaryData_pool = memPoolCreate("VaryData", sizeof(VaryData));
- state = cbdataAlloc(LocateVaryState);
- state->vary_data = xstrdup(vary_data);
- if (strIsNotNull(accept_encoding))
- state->accept_encoding = stringDup(&accept_encoding);
- state->data = memPoolAlloc(VaryData_pool);
- state->e = e;
- storeLockObject(state->e);
- state->callback_data = cbdata;
- cbdataLock(cbdata);
- state->callback = callback;
- state->buf = memAllocBuf(4096, &state->buf_size);
- state->sc = storeClientRegister(state->e, state);
- state->seen_offset = offset;
- if (!strLen2(e->mem_obj->reply->content_type) ||
strCmp(e->mem_obj->reply->content_type, "x-squid-internal/vary") != 0) {
- /* This is not our Vary marker object. Bail out. */
- debug(33, 1) ("storeLocateVary: Not our vary marker object, %s
= '%s', '%s'/'%.*s'\n",
- storeKeyText(e->hash.key), e->mem_obj->url, vary_data,
- strLen2(accept_encoding) ? strLen2(accept_encoding) : 1,
- strBuf2(accept_encoding) ? strBuf2(accept_encoding) : "-");
- storeLocateVaryCallback(state);
- return;
- }
- storeClientRef(state->sc, state->e,
- state->seen_offset,
- state->seen_offset,
- state->buf_size,
- storeLocateVaryRead,
- state);
-}
void
storeSetPublicKey(StoreEntry * e)
--
You received this message because you are subscribed to the Google Groups
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/lusca-commit?hl=en.