2626 * requests.
2727 */
2828
29- #include < cstdio>
30- #include < cstring>
3129#include " ts/ts.h"
3230#include " ts/remap.h"
3331
32+ #include < cstdio>
33+ #include < cstring>
34+ #include < getopt.h>
35+
3436#define PLUGIN_NAME " cache_range_requests"
3537#define DEBUG_LOG (fmt, ...) TSDebug(PLUGIN_NAME, " [%s:%d] %s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
3638#define ERROR_LOG (fmt, ...) TSError(" [%s:%d] %s(): " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
@@ -41,7 +43,8 @@ typedef enum parent_select_mode {
4143} parent_select_mode_t ;
4244
4345struct pluginconfig {
44- parent_select_mode_t ps_mode;
46+ parent_select_mode_t ps_mode{PS_DEFAULT};
47+ bool modify_cache_key{true };
4548};
4649
4750struct txndata {
@@ -56,7 +59,7 @@ static void handle_server_read_response(TSHttpTxn, struct txndata *);
5659static int remove_header (TSMBuffer, TSMLoc, const char *, int );
5760static bool set_header (TSMBuffer, TSMLoc, const char *, int , const char *, int );
5861static int transaction_handler (TSCont, TSEvent, void *);
59- static struct pluginconfig *create_pluginconfig (int argc, const char *argv[]);
62+ static struct pluginconfig *create_pluginconfig (int argc, char *const argv[]);
6063static void delete_pluginconfig (struct pluginconfig *);
6164
6265// pluginconfig struct (global plugin only)
@@ -68,26 +71,50 @@ static struct pluginconfig *gPluginConfig = nullptr;
6871 * Walk plugin argument list and updates config
6972 */
7073static struct pluginconfig *
71- create_pluginconfig (int argc, const char *argv[])
74+ create_pluginconfig (int argc, char *const argv[])
7275{
73- struct pluginconfig *pc = nullptr ;
74-
75- pc = (struct pluginconfig *)TSmalloc (sizeof (struct pluginconfig ));
76+ struct pluginconfig *pc = new pluginconfig;
7677
7778 if (nullptr == pc) {
7879 ERROR_LOG (" Can't allocate pluginconfig" );
7980 return nullptr ;
8081 }
8182
82- // Plugin uses default ATS selection (hash of URL path)
83- pc->ps_mode = PS_DEFAULT;
83+ static const struct option longopts[] = {
84+ {const_cast <char *>(" ps-cachekey" ), no_argument, nullptr , ' p' },
85+ {const_cast <char *>(" no-modify-cachekey" ), no_argument, nullptr , ' n' },
86+ {nullptr , 0 , nullptr , 0 },
87+ };
8488
85- // Walk through param list.
86- for (int c = 0 ; c < argc; c++) {
87- if (strcmp (" ps_mode:cache_key_url" , argv[c]) == 0 ) {
88- pc->ps_mode = PS_CACHEKEY_URL;
89+ // getopt assumes args start at '1'
90+ ++argc;
91+ --argv;
92+
93+ for (;;) {
94+ int const opt = getopt_long (argc, argv, " " , longopts, nullptr );
95+ if (-1 == opt) {
8996 break ;
9097 }
98+
99+ switch (opt) {
100+ case ' p' : {
101+ DEBUG_LOG (" Plugin modifies parent selection key" );
102+ pc->ps_mode = PS_CACHEKEY_URL;
103+ } break ;
104+ case ' n' : {
105+ DEBUG_LOG (" Plugin doesn't modify cache key" );
106+ pc->modify_cache_key = false ;
107+ } break ;
108+ default : {
109+ DEBUG_LOG (" Unknown option: '%c'" , opt);
110+ } break ;
111+ }
112+ }
113+
114+ // Backwards compatibility
115+ if (optind < argc && 0 == strcmp (" ps_mode:cache_key_url" , argv[optind])) {
116+ DEBUG_LOG (" Plugin modifies parent selection key (deprecated)" );
117+ pc->ps_mode = PS_CACHEKEY_URL;
91118 }
92119
93120 return pc;
@@ -101,7 +128,7 @@ delete_pluginconfig(struct pluginconfig *pc)
101128{
102129 if (nullptr != pc) {
103130 DEBUG_LOG (" Delete struct pluginconfig" );
104- TSfree (pc) ;
131+ delete pc ;
105132 pc = nullptr ;
106133 }
107134}
@@ -165,23 +192,29 @@ range_header_check(TSHttpTxn txnp, struct pluginconfig *pc)
165192 TSfree (req_url);
166193 }
167194
168- // set the cache key.
169- if (TS_SUCCESS != TSCacheUrlSet (txnp, cache_key_url, cache_key_url_length)) {
170- DEBUG_LOG (" failed to change the cache url to %s." , cache_key_url);
171- }
195+ if (nullptr != pc) {
196+ // set the cache key if configured to.
197+ if (pc->modify_cache_key && TS_SUCCESS != TSCacheUrlSet (txnp, cache_key_url, cache_key_url_length)) {
198+ ERROR_LOG (" failed to change the cache url to %s." , cache_key_url);
199+ ERROR_LOG (" Disabling cache for this transaction to avoid cache poisoning." );
200+ TSHttpTxnServerRespNoStoreSet (txnp, 1 );
201+ TSHttpTxnRespCacheableSet (txnp, 0 );
202+ TSHttpTxnReqCacheableSet (txnp, 0 );
203+ }
172204
173- // Optionally set the parent_selection_url to the cache_key url or path
174- if (nullptr != pc && PS_DEFAULT != pc->ps_mode ) {
175- TSMLoc ps_loc = nullptr ;
176-
177- if (PS_CACHEKEY_URL == pc->ps_mode ) {
178- const char *start = cache_key_url;
179- const char *end = cache_key_url + cache_key_url_length;
180- if (TS_SUCCESS == TSUrlCreate (hdr_bufp, &ps_loc) &&
181- TS_PARSE_DONE == TSUrlParse (hdr_bufp, ps_loc, &start, end) && // This should always succeed.
182- TS_SUCCESS == TSHttpTxnParentSelectionUrlSet (txnp, hdr_bufp, ps_loc)) {
183- DEBUG_LOG (" Set Parent Selection URL to cache_key_url: %s" , cache_key_url);
184- TSHandleMLocRelease (hdr_bufp, TS_NULL_MLOC, ps_loc);
205+ // Optionally set the parent_selection_url to the cache_key url or path
206+ if (PS_DEFAULT != pc->ps_mode ) {
207+ TSMLoc ps_loc = nullptr ;
208+
209+ if (PS_CACHEKEY_URL == pc->ps_mode ) {
210+ const char *start = cache_key_url;
211+ const char *end = cache_key_url + cache_key_url_length;
212+ if (TS_SUCCESS == TSUrlCreate (hdr_bufp, &ps_loc) &&
213+ TS_PARSE_DONE == TSUrlParse (hdr_bufp, ps_loc, &start, end) && // This should always succeed.
214+ TS_SUCCESS == TSHttpTxnParentSelectionUrlSet (txnp, hdr_bufp, ps_loc)) {
215+ DEBUG_LOG (" Set Parent Selection URL to cache_key_url: %s" , cache_key_url);
216+ TSHandleMLocRelease (hdr_bufp, TS_NULL_MLOC, ps_loc);
217+ }
185218 }
186219 }
187220 }
@@ -411,11 +444,10 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /*errbuf */, int /*
411444 }
412445
413446 // Skip over the Remap params
414- const char **plugin_argv = const_cast <const char **>(argv + 2 );
415- argc -= 2 ;
447+ char *const *plugin_argv = const_cast <char *const *>(argv);
416448
417449 // Parse the argument list.
418- *ih = (struct pluginconfig *)create_pluginconfig (argc, plugin_argv);
450+ *ih = (struct pluginconfig *)create_pluginconfig (argc - 2 , plugin_argv + 2 );
419451
420452 if (*ih == nullptr ) {
421453 ERROR_LOG (" Can't create pluginconfig" );
@@ -472,9 +504,8 @@ TSPluginInit(int argc, const char *argv[])
472504 if (nullptr == gPluginConfig ) {
473505 if (argc > 1 ) {
474506 // Skip ahead of first param (name of traffic server plugin shared object)
475- const char **plugin_argv = const_cast <const char **>(argv + 1 );
476- argc -= 1 ;
477- gPluginConfig = create_pluginconfig (argc, plugin_argv);
507+ char *const *plugin_argv = const_cast <char *const *>(argv);
508+ gPluginConfig = create_pluginconfig (argc - 1 , plugin_argv + 1 );
478509 }
479510 }
480511
0 commit comments