Skip to content

Commit fbdf022

Browse files
sfeltner-godaddySolidWallOfCode
authored andcommitted
TS-3977: Add cache-key-genid to experimental plugins.
This closes #309.
1 parent 1d1cb8f commit fbdf022

File tree

5 files changed

+218
-3
lines changed

5 files changed

+218
-3
lines changed

NOTICE

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This product includes software developed at
99
- Comcast
1010
- LinkedIn
1111
- Mike Pall
12+
- GoDaddy
1213

1314
~~~
1415

@@ -44,8 +45,8 @@ Copyright (C) 2012 Oregon Health & Science University
4445

4546
~~~
4647

47-
healthcheck Plugin developed by GoDaddy.
48-
Copyright (C) 2012 GoDaddy.
48+
cache-key-genid Plugin developed by GoDaddy
49+
Copyright (C) 2013 GoDaddy Operating Company, LLC
4950

5051
~~~
5152

@@ -84,7 +85,7 @@ Copyright (C) 2016 Yahoo! Inc. All rights reserved.
8485
~~~
8586

8687
healthchecks: Plugin for ATS healthchecks.
87-
Copyright (C) 2012 Go Daddy Operating Company, LLC
88+
Copyright (C) 2012 GoDaddy Operating Company, LLC
8889

8990
~~~
9091

configure.ac

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,19 @@ AC_CHECK_LIB([mysqlclient],[mysql_info],[AC_SUBST([LIB_MYSQLCLIENT],["-lmysqlcli
14541454
AC_SUBST(has_mysql)
14551455
AM_CONDITIONAL([HAS_MYSQL], [ test "x${has_mysql}" = "x1" ])
14561456

1457+
AC_CHECK_HEADERS([kclangc.h], [
1458+
AC_CHECK_LIB([kyotocabinet], [kcdbopen], [
1459+
AC_SUBST([LIB_KYOTOCABINET], ["-lkyotocabinet"])
1460+
has_kyotocabinet=1
1461+
], [
1462+
has_kyotocabinet=0
1463+
])
1464+
],
1465+
[has_kyotocabinet=0]
1466+
)
1467+
AC_SUBST(has_kyotocabinet)
1468+
AM_CONDITIONAL([HAS_KYOTOCABINET], [ test "x${has_kyotocabinet}" = "x1" ])
1469+
14571470
# -----------------------------------------------------------------------------
14581471
# 5. CHECK FOR HEADER FILES
14591472

@@ -1930,6 +1943,7 @@ AC_CONFIG_FILES([
19301943
plugins/experimental/background_fetch/Makefile
19311944
plugins/experimental/balancer/Makefile
19321945
plugins/experimental/buffer_upload/Makefile
1946+
plugins/experimental/cache_key_genid/Makefile
19331947
plugins/experimental/cache_promote/Makefile
19341948
plugins/experimental/cache_range_requests/Makefile
19351949
plugins/experimental/cachekey/Makefile

plugins/experimental/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ endif
6161
if BUILD_LUAJIT
6262
SUBDIRS += ts_lua
6363
endif
64+
65+
if HAS_KYOTOCABINET
66+
SUBDIRS += cache_key_genid
67+
endif
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
include $(top_srcdir)/build/plugins.mk
18+
19+
pkglib_LTLIBRARIES = cache_key_genid.la
20+
cache_key_genid_la_SOURCES = cache_key_genid.c
21+
cache_key_genid_la_LDFLAGS = $(TS_PLUGIN_LDFLAGS) $(LIB_KYOTOCABINET)
22+
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
/* cache-key-genid.c - Plugin to modify the URL used as a cache key for
16+
* requests, without modifying the URL used for actually fetching data from
17+
* the origin server.
18+
*/
19+
20+
#include <ts/ts.h>
21+
#include <stdio.h>
22+
#include <string.h>
23+
#include "kclangc.h"
24+
25+
#define PLUGIN_NAME "cache-key-genid"
26+
27+
static char genid_kyoto_db[PATH_MAX + 1];
28+
29+
// Find the host in url and set host to it
30+
static void
31+
get_genid_host(char **host, char *url)
32+
{
33+
char *pt1;
34+
char *pt2;
35+
size_t host_len;
36+
unsigned num = 1;
37+
38+
pt1 = strstr(url, "//");
39+
40+
if (pt1) {
41+
pt1 = pt1 + 2;
42+
pt2 = strstr(pt1, "/");
43+
}
44+
45+
if (pt1 && pt2 && pt2 > pt1) {
46+
host_len = pt2 - pt1;
47+
*host = calloc(num, host_len + 1);
48+
strncpy(*host, pt1, host_len);
49+
}
50+
}
51+
52+
/* get_genid
53+
* Looks up the host's genid in the host->genid database
54+
*/
55+
static int
56+
get_genid(char *host)
57+
{
58+
KCDB *db;
59+
char *vbuf;
60+
size_t vsiz;
61+
int answer = 0;
62+
int host_size;
63+
64+
/* create the database object */
65+
db = kcdbnew();
66+
67+
/* open the database */
68+
if (!kcdbopen(db, genid_kyoto_db, KCOREADER | KCONOLOCK)) {
69+
TSDebug(PLUGIN_NAME, "could not open the genid database %s", genid_kyoto_db);
70+
TSError("[%s] could not open the genid database %s: %s", PLUGIN_NAME, genid_kyoto_db, strerror(errno));
71+
return 0;
72+
}
73+
74+
vbuf = kcdbget(db, host, strlen(host), &vsiz);
75+
76+
if (vbuf) {
77+
TSDebug(PLUGIN_NAME, "kcdbget(%s) = %s", host, vbuf);
78+
answer = (int)strtol(vbuf, NULL, 10);
79+
kcfree(vbuf);
80+
} else {
81+
host_size = strlen(host);
82+
TSDebug(PLUGIN_NAME, "kcdbget(%s) - no record found, len(%d)", host, host_size);
83+
answer = 0;
84+
}
85+
86+
kcdbclose(db);
87+
return answer;
88+
}
89+
90+
/* handle_hook
91+
* Fires on TS_EVENT_HTTP_READ_REQUEST_HDR events, gets the effectiveUrl
92+
* finds the host, gets the generation ID, gen_id, for the host
93+
* and runs TSCacheUrlSet to change the cache key for the read
94+
*/
95+
static int
96+
handle_hook(TSCont *contp, TSEvent event, void *edata)
97+
{
98+
TSHttpTxn txnp = (TSHttpTxn)edata;
99+
char *url = NULL, *host = NULL;
100+
int url_length;
101+
int gen_id;
102+
int ok = 1;
103+
104+
switch (event) {
105+
case TS_EVENT_HTTP_READ_REQUEST_HDR:
106+
TSDebug(PLUGIN_NAME, "handling TS_EVENT_HTTP_READ_REQUEST_HDR");
107+
108+
if (ok) {
109+
url = TSHttpTxnEffectiveUrlStringGet(txnp, &url_length);
110+
if (!url) {
111+
TSError("[%s] could not retrieve request url", PLUGIN_NAME);
112+
ok = 0;
113+
}
114+
}
115+
116+
if (ok) {
117+
get_genid_host(&host, url);
118+
if (!host) {
119+
TSError("[%s] could not retrieve request host", PLUGIN_NAME);
120+
ok = 0;
121+
}
122+
}
123+
124+
if (ok) {
125+
TSDebug(PLUGIN_NAME, "From url (%s) discovered host (%s)", url, host);
126+
if ((gen_id = get_genid(host)) != 0) {
127+
if (TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_CACHE_GENERATION, gen_id) != TS_SUCCESS) {
128+
TSDebug(PLUGIN_NAME, "Error, unable to modify cache url");
129+
TSError("[%s] Unable to set cache generation for %s to %d", PLUGIN_NAME, url, gen_id);
130+
ok = 0;
131+
}
132+
}
133+
}
134+
135+
/* Clean up */
136+
if (url)
137+
TSfree(url);
138+
if (host)
139+
TSfree(host);
140+
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
141+
break;
142+
143+
default:
144+
TSAssert(!"Unexpected event");
145+
ok = 0;
146+
break;
147+
}
148+
149+
return ok;
150+
}
151+
152+
void
153+
TSPluginInit(int argc, const char *argv[])
154+
{
155+
TSPluginRegistrationInfo info;
156+
157+
info.plugin_name = (char *)PLUGIN_NAME;
158+
info.vendor_name = (char *)"Apache Software Foundation";
159+
info.support_email = (char *)"dev@trafficserver.apache.org";
160+
161+
if (argc > 1) {
162+
TSstrlcpy(genid_kyoto_db, argv[1], sizeof(genid_kyoto_db));
163+
} else {
164+
TSError("[%s] plugin registration failed. check argv[1] for db path", PLUGIN_NAME);
165+
return;
166+
}
167+
168+
if (TSPluginRegister(&info) != TS_SUCCESS) {
169+
TSError("[%s] plugin registration failed. check version.", PLUGIN_NAME);
170+
return;
171+
}
172+
173+
TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, TSContCreate((TSEventFunc)handle_hook, NULL));
174+
}

0 commit comments

Comments
 (0)