| 228 | } |
| 229 | |
| 230 | static int |
| 231 | read_resp_hdr(TSCont contp, TSEvent event, void *edata) |
| 232 | { |
| 233 | TSHttpTxn txnp = static_cast<TSHttpTxn>(edata); |
| 234 | PluginInfo *info = static_cast<PluginInfo *>(TSContDataGet(contp)); |
| 235 | |
| 236 | // This function does the following things: |
| 237 | // 1. Parse the object size from Content-Length |
| 238 | // 2. Cache the object size |
| 239 | // 3. If the object will be sliced in subsequent requests, turn off the cache to avoid taking up space, and head-of-line blocking. |
| 240 | |
| 241 | int urllen = 0; |
| 242 | char *urlstr = TSHttpTxnEffectiveUrlStringGet(txnp, &urllen); |
| 243 | if (urlstr != nullptr) { |
| 244 | TxnHdrMgr response; |
| 245 | TxnHdrMgr::HeaderGetFunc func = event == TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE ? TSHttpTxnCachedRespGet : TSHttpTxnServerRespGet; |
| 246 | response.populateFrom(txnp, func); |
| 247 | HttpHeader const resp_header(response.m_buffer, response.m_lochdr); |
| 248 | char constr[1024]; |
| 249 | int conlen = sizeof constr; |
| 250 | bool const hasContentLength(resp_header.valueForKey(TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH, constr, &conlen)); |
| 251 | if (hasContentLength) { |
| 252 | uint64_t content_length; |
| 253 | |
| 254 | [[maybe_unused]] auto [ptr, ec] = std::from_chars(constr, constr + conlen, content_length); |
| 255 | if (ec == std::errc()) { |
| 256 | if (content_length >= info->config.m_min_size_to_slice) { |
| 257 | // Remember that this object is big |
| 258 | info->config.sizeCacheAdd({urlstr, static_cast<size_t>(urllen)}, content_length); |
| 259 | // This object will be sliced in future requests. Don't cache it for now. |
| 260 | TSHttpTxnServerRespNoStoreSet(txnp, 1); |
| 261 | TSStatIntIncrement(info->config.stat_FN, 1); |
| 262 | } else { |
| 263 | TSStatIntIncrement(info->config.stat_TN, 1); |
| 264 | } |
| 265 | } else { |
| 266 | ERROR_LOG("Could not parse content-length: %.*s", conlen, constr); |
| 267 | TSStatIntIncrement(info->config.stat_bad_cl, 1); |
| 268 | } |
| 269 | } else { |
| 270 | DEBUG_LOG("Could not get a content length for updating object size"); |
| 271 | TSStatIntIncrement(info->config.stat_no_cl, 1); |
| 272 | } |
| 273 | TSfree(urlstr); |
| 274 | } else { |
| 275 | ERROR_LOG("Could not get URL for obj size."); |
| 276 | TSStatIntIncrement(info->config.stat_no_url, 1); |
| 277 | } |
| 278 | |
| 279 | // Reenable and continue with the state machine. |
| 280 | TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE); |
| 281 | return 0; |
| 282 | } |
| 283 | |
| 284 | int |
| 285 | global_read_request_hook(TSCont // contp |
nothing calls this directly
no test coverage detected