Skip to content

Commit 5cfaac0

Browse files
committed
Add cache key hash logging field and public API
Add 'ckh' log field that emits the base64-encoded cache key digest, and TSHttpTxnCacheKeyDigestGet() for plugin access to the raw hash bytes. Includes admin and API documentation. Co-Author: Craig Taylor
1 parent 83ec495 commit 5cfaac0

12 files changed

Lines changed: 196 additions & 6 deletions

File tree

doc/admin-guide/logging/formatting.en.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ Cache Details
151151
.. _crc:
152152
.. _crsc:
153153
.. _chm:
154+
.. _ckh:
154155
.. _cwr:
155156
.. _cwtr:
156157
.. _crra:
@@ -166,6 +167,10 @@ Field Source Description
166167
cluc Client Request Cache Lookup URL, also known as the :term:`cache key`,
167168
which is the canonicalized version of the client request
168169
URL.
170+
ckh Proxy Cache Cache Key Hash. The base64-encoded cryptographic hash of the
171+
effective cache key used for cache lookup and storage. This
172+
is the actual key used to index cache objects. Empty
173+
(``-``) when no cache lookup was performed.
169174
crc Proxy Cache Cache Result Code. The result of |TS| attempting to obtain
170175
the object from cache; :ref:`admin-logging-cache-results`.
171176
crsc Proxy Cache Cache Result Sub-Code. More specific code to complement the
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
.. Licensed to the Apache Software Foundation (ASF) under one or more
2+
contributor license agreements. See the NOTICE file distributed
3+
with this work for additional information regarding copyright
4+
ownership. The ASF licenses this file to you under the Apache
5+
License, Version 2.0 (the "License"); you may not use this file
6+
except in compliance with the License. You may obtain a copy of
7+
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
14+
implied. See the License for the specific language governing
15+
permissions and limitations under the License.
16+
17+
.. include:: ../../../common.defs
18+
19+
.. default-domain:: cpp
20+
21+
TSHttpTxnCacheKeyDigestGet
22+
**************************
23+
24+
Synopsis
25+
========
26+
27+
.. code-block:: cpp
28+
29+
#include <ts/ts.h>
30+
31+
.. function:: TSReturnCode TSHttpTxnCacheKeyDigestGet(TSHttpTxn txnp, char *buffer, int *length)
32+
33+
Description
34+
===========
35+
36+
Get the effective cache key digest (cryptographic hash) that was used for
37+
cache lookup or storage on this transaction. This is the raw hash bytes,
38+
not a hex or base64 encoding.
39+
40+
The digest size depends on the build configuration: 16 bytes for MD5
41+
(default) or 32 bytes for SHA-256 (FIPS mode). A 32-byte buffer is
42+
sufficient for either mode:
43+
44+
.. code-block:: c
45+
46+
char digest[32];
47+
int digest_len = sizeof(digest);
48+
if (TSHttpTxnCacheKeyDigestGet(txnp, digest, &digest_len) == TS_SUCCESS) {
49+
// digest_len contains the actual number of bytes written
50+
}
51+
52+
Pass :code:`nullptr` for *buffer* to query the digest size without
53+
copying.
54+
55+
Returns :enumerator:`TS_SUCCESS` if a cache key was computed for the
56+
transaction. Returns :enumerator:`TS_ERROR` if no cache lookup was
57+
performed, or if *buffer* is non-null and *\*length* is smaller than the
58+
digest size. In all cases *\*length* is set to the required digest size
59+
on return.
60+
61+
See Also
62+
========
63+
64+
:func:`TSHttpTxnCacheLookupUrlGet`

include/proxy/http/HttpCacheSM.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ class HttpCacheSM : public Continuation
129129
return cache_read_vc ? (cache_read_vc->is_compressed_in_ram()) : false;
130130
}
131131

132+
const HttpCacheKey &
133+
get_cache_key() const
134+
{
135+
return cache_key;
136+
}
137+
132138
void
133139
set_open_read_tries(int value)
134140
{

include/proxy/logging/LogAccess.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class LogAccess
254254
//
255255
int marshal_cache_write_code(char *); // INT
256256
int marshal_cache_write_transform_code(char *); // INT
257+
int marshal_cache_key_hash(char *); // STR
257258

258259
// other fields
259260
//

include/proxy/logging/TransactionLogData.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ class TransactionLogData
7575
int get_unmapped_url_len() const;
7676

7777
// ===== Cache lookup URL =====
78-
char *get_cache_lookup_url_str() const;
79-
int get_cache_lookup_url_len() const;
78+
char *get_cache_lookup_url_str() const;
79+
int get_cache_lookup_url_len() const;
80+
const ts::CryptoHash *get_cache_lookup_hash() const;
8081

8182
// ===== Client addressing =====
8283
sockaddr const *get_client_addr() const;

include/ts/ts.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2768,6 +2768,25 @@ TSReturnCode TSHttpTxnCachedRespModifiableGet(TSHttpTxn txnp, TSMBuffer *bufp, T
27682768
TSReturnCode TSHttpTxnCacheLookupStatusSet(TSHttpTxn txnp, int cachelookup);
27692769
TSReturnCode TSHttpTxnCacheLookupUrlGet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj);
27702770
TSReturnCode TSHttpTxnCacheLookupUrlSet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj);
2771+
2772+
/**
2773+
Gets the effective cache key digest (cryptographic hash) that was
2774+
used for cache lookup or storage on this transaction. The digest
2775+
is returned as raw bytes — 16 bytes for MD5 (default) or 32 bytes
2776+
for SHA-256 (FIPS mode). A buffer of at least 32 bytes is
2777+
recommended to accommodate either configuration.
2778+
2779+
@param txnp the transaction.
2780+
@param buffer caller-provided buffer to receive the raw hash bytes.
2781+
If @c nullptr, only @a length is set (size query).
2782+
@param length in: capacity of @a buffer in bytes.
2783+
out: actual digest size in bytes.
2784+
2785+
@return @c TS_SUCCESS if a cache key was computed for this
2786+
transaction, @c TS_ERROR if no cache lookup was performed or if
2787+
@a buffer is non-null and too small.
2788+
*/
2789+
TSReturnCode TSHttpTxnCacheKeyDigestGet(TSHttpTxn txnp, char *buffer, int *length);
27712790
TSReturnCode TSHttpTxnPrivateSessionSet(TSHttpTxn txnp, int private_session);
27722791
const char *TSHttpTxnCacheDiskPathGet(TSHttpTxn txnp, int *length);
27732792
int TSHttpTxnBackgroundFillStarted(TSHttpTxn txnp);

src/api/InkAPI.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4477,6 +4477,35 @@ TSHttpTxnCacheLookupUrlSet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj)
44774477
return TS_SUCCESS;
44784478
}
44794479

4480+
TSReturnCode
4481+
TSHttpTxnCacheKeyDigestGet(TSHttpTxn txnp, char *buffer, int *length)
4482+
{
4483+
sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
4484+
sdk_assert(length != nullptr);
4485+
4486+
HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
4487+
const CryptoHash &hash = sm->get_cache_sm().get_cache_key().hash;
4488+
constexpr int size = CRYPTO_HASH_SIZE;
4489+
4490+
if (hash.is_zero()) {
4491+
return TS_ERROR;
4492+
}
4493+
4494+
if (buffer == nullptr) {
4495+
*length = size;
4496+
return TS_SUCCESS;
4497+
}
4498+
4499+
if (*length < size) {
4500+
*length = size;
4501+
return TS_ERROR;
4502+
}
4503+
4504+
memcpy(buffer, hash.u8, size);
4505+
*length = size;
4506+
return TS_SUCCESS;
4507+
}
4508+
44804509
/**
44814510
* timeout is in msec
44824511
* overrides as proxy.config.http.transaction_active_timeout_out

src/proxy/logging/Log.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,10 @@ Log::init_fields()
505505
global_field_list.add(field, false);
506506
field_symbol_hash.emplace("cluc", field);
507507

508+
field = new LogField("cache_key_hash", "ckh", LogField::STRING, &LogAccess::marshal_cache_key_hash, &LogAccess::unmarshal_str);
509+
global_field_list.add(field, false);
510+
field_symbol_hash.emplace("ckh", field);
511+
508512
field = new LogField("client_sni_server_name", "cssn", LogField::STRING, &LogAccess::marshal_client_sni_server_name,
509513
&LogAccess::unmarshal_str);
510514
global_field_list.add(field, false);

src/proxy/logging/LogAccess.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "swoc/BufferWriter.h"
3636
#include "tscore/Encoding.h"
3737
#include "tscore/ink_inet.h"
38+
#include "tscore/ink_base64.h"
3839

3940
char INVALID_STR[] = "!INVALID_STR!";
4041

@@ -3030,6 +3031,35 @@ LogAccess::marshal_cache_write_transform_code(char *buf)
30303031
return INK_MIN_ALIGN;
30313032
}
30323033

3034+
/*-------------------------------------------------------------------------
3035+
-------------------------------------------------------------------------*/
3036+
3037+
int
3038+
LogAccess::marshal_cache_key_hash(char *buf)
3039+
{
3040+
const ts::CryptoHash *hash = m_data->get_cache_lookup_hash();
3041+
3042+
if (!hash || hash->is_zero()) {
3043+
if (buf) {
3044+
marshal_str(buf, "-", padded_length(2));
3045+
}
3046+
return padded_length(2);
3047+
}
3048+
3049+
constexpr size_t b64_bufsize = ats_base64_encode_dstlen(CRYPTO_HASH_SIZE);
3050+
char b64_str[b64_bufsize];
3051+
size_t b64_len = 0;
3052+
3053+
ats_base64_encode(reinterpret_cast<const char *>(hash->u8), CRYPTO_HASH_SIZE, b64_str, b64_bufsize, &b64_len);
3054+
3055+
int len = padded_length(b64_len + 1);
3056+
3057+
if (buf) {
3058+
marshal_str(buf, b64_str, len);
3059+
}
3060+
return len;
3061+
}
3062+
30333063
/*-------------------------------------------------------------------------
30343064
-------------------------------------------------------------------------*/
30353065

src/proxy/logging/TransactionLogData.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,16 @@ TransactionLogData::get_cache_lookup_url_len() const
366366
return 0;
367367
}
368368

369+
const ts::CryptoHash *
370+
TransactionLogData::get_cache_lookup_hash() const
371+
{
372+
if (likely(m_http_sm != nullptr)) {
373+
return &(m_http_sm->get_cache_sm().get_cache_key().hash);
374+
}
375+
376+
return nullptr;
377+
}
378+
369379
// ===== Client addressing =====
370380

371381
sockaddr const *

0 commit comments

Comments
 (0)