| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| /** |
| * @file cachekey.h |
| * @brief Cache key manipulation (header file). |
| */ |
| |
| #pragma once |
| |
| #include "ts/ts.h" |
| #include "ts/remap.h" |
| #include "common.h" |
| #include "configs.h" |
| |
| /** |
| * @brief Cache key manipulation class. |
| * |
| * Initialize the cache key from the request URI. |
| * |
| * The cache key is to be a valid URI. Key structure documented in doc/cachekey.en.rst#cache-key-structure |
| * @note scheme, #fragment, user:password@ from URI authority component are currently ignored. |
| * The query parameters, headers and cookies are handled similarly in general, |
| * but there are some differences in the handling of the query and the rest of the elements: |
| * - headers and cookies are never included in the cache key by default, query is. |
| * - query manipulation is different (stripping off, sorting, exclusion of query parameters, etc). |
| * That is why seemed like a good idea to add headers, cookies, UA-captures, UA-classes |
| * to the "hier-part" and keep only the query parameters in the "query part" (RFC 3986). |
| * |
| * @todo Consider avoiding the ATS API multiple-lookups while handling headers and cookies. |
| * Currently ts/ts.h states that iterating through the headers one by one is not efficient |
| * but being able to iterate through all the headers once and figure out what to append to |
| * the cache key seems be more time efficient. |
| */ |
| class CacheKey |
| { |
| public: |
| CacheKey(TSHttpTxn txn, String separator, CacheKeyUriType urlType, CacheKeyKeyType targetUrlType, |
| TSRemapRequestInfo *rri = nullptr); |
| ~CacheKey(); |
| |
| void append(unsigned number); |
| void append(const String &); |
| void append(const String &s, bool useSeparator); |
| void append(const char *s); |
| void append(const char *n, unsigned s); |
| void appendPrefix(const String &prefix, Pattern &prefixCapture, Pattern &prefixCaptureUri, bool canonicalPrefix); |
| void appendPath(Pattern &pathCapture, Pattern &pathCaptureUri); |
| void appendHeaders(const ConfigHeaders &config); |
| void appendQuery(const ConfigQuery &config); |
| void appendCookies(const ConfigCookies &config); |
| void appendUaCaptures(Pattern &config); |
| bool appendUaClass(Classifier &classifier); |
| bool finalize() const; |
| |
| // noncopyable |
| CacheKey(const CacheKey &) = delete; // disallow |
| CacheKey &operator=(const CacheKey &) = delete; // disallow |
| |
| private: |
| CacheKey(); // disallow |
| |
| template <class T> |
| void processHeader(const String &name_s, const ConfigHeaders &config, T &dst, |
| void (*fun)(const ConfigHeaders &config, const String &name_s, const String &value_s, T &captures)); |
| |
| /* Information from the request */ |
| TSHttpTxn _txn; /**< @brief transaction handle */ |
| TSMBuffer _buf; /**< @brief marshal buffer */ |
| TSMLoc _url; /**< @brief URI handle */ |
| TSMLoc _hdrs; /**< @brief headers handle */ |
| bool _valid = false; /**< @brief shows if the constructor discovered the input correctly */ |
| bool _remap = false; /**< @brief shows if the input URI was from remap info */ |
| |
| String _key; /**< @brief cache key */ |
| String _separator; /**< @brief a separator used to separate the cache key elements extracted from the URI */ |
| CacheKeyUriType _uriType = REMAP; /**< @brief the URI type used as a cachekey base: pristine, remap, etc. */ |
| CacheKeyKeyType _keyType = CACHE_KEY; /**< @brief the target URI type: cache key, parent selection, etc. */ |
| }; |