diff --git a/include/proxy/PreTransactionLogData.h b/include/proxy/PreTransactionLogData.h index 9d65e667616..0ec03c646bb 100644 --- a/include/proxy/PreTransactionLogData.h +++ b/include/proxy/PreTransactionLogData.h @@ -24,7 +24,9 @@ #pragma once -#include "proxy/logging/TransactionLogData.h" +#include "proxy/Milestones.h" +#include "proxy/hdrs/HTTP.h" +#include "tscore/ink_inet.h" #include @@ -36,160 +38,21 @@ * copied request and session metadata needed to emit a best-effort * transaction log entry for those failures. * - * Unlike TransactionLogData (which reads from a live HttpSM), this class - * owns its milestones, addresses, and strings because the originating - * stream is about to be destroyed. + * This class owns its milestones, addresses, and strings because the + * originating stream is about to be destroyed. */ -class PreTransactionLogData : public TransactionLogData +class PreTransactionLogData { public: PreTransactionLogData() = default; - ~PreTransactionLogData() override + ~PreTransactionLogData() { if (owned_client_request.valid()) { owned_client_request.destroy(); } } - // ===== Milestones ===== - - TransactionMilestones const * - get_milestones() const override - { - return &owned_milestones; - } - - // ===== Headers ===== - - HTTPHdr * - get_client_request() const override - { - if (owned_client_request.valid()) { - return const_cast(&owned_client_request); - } - return nullptr; - } - - // ===== Client request URL / path ===== - - const char * - get_client_req_url_str() const override - { - return owned_url.empty() ? nullptr : owned_url.c_str(); - } - int - get_client_req_url_len() const override - { - return static_cast(owned_url.size()); - } - const char * - get_client_req_url_path_str() const override - { - return owned_path.empty() ? nullptr : owned_path.c_str(); - } - int - get_client_req_url_path_len() const override - { - return static_cast(owned_path.size()); - } - - // ===== Client addressing ===== - - sockaddr const * - get_client_addr() const override - { - return &owned_client_addr.sa; - } - sockaddr const * - get_client_src_addr() const override - { - return &owned_client_src_addr.sa; - } - sockaddr const * - get_client_dst_addr() const override - { - return &owned_client_dst_addr.sa; - } - uint16_t - get_client_port() const override - { - return m_client_port; - } - - // ===== Squid codes ===== - - SquidLogCode - get_log_code() const override - { - return m_log_code; - } - SquidHitMissCode - get_hit_miss_code() const override - { - return m_hit_miss_code; - } - SquidHierarchyCode - get_hier_code() const override - { - return m_hier_code; - } - - // ===== Transaction identifiers ===== - - int64_t - get_connection_id() const override - { - return m_connection_id; - } - int - get_transaction_id() const override - { - return m_transaction_id; - } - - // ===== Protocol info ===== - - const char * - get_client_protocol() const override - { - return owned_client_protocol_str.empty() ? nullptr : owned_client_protocol_str.c_str(); - } - - // ===== Connection flags ===== - - bool - get_client_connection_is_ssl() const override - { - return m_client_connection_is_ssl; - } - - // ===== Server transaction count ===== - - int64_t - get_server_transact_count() const override - { - return m_server_transact_count; - } - - // ===== Fallback fields for pre-transaction logging ===== - - std::string_view - get_method() const override - { - return owned_method; - } - std::string_view - get_scheme() const override - { - return owned_scheme; - } - std::string_view - get_client_protocol_str() const override - { - return owned_client_protocol_str; - } - // ===== Owned backing storage (public for ProxyTransaction to populate). ===== HTTPHdr owned_client_request; diff --git a/include/proxy/http/CompletedTransactionLogData.h b/include/proxy/http/CompletedTransactionLogData.h deleted file mode 100644 index 3e1a25aa7b7..00000000000 --- a/include/proxy/http/CompletedTransactionLogData.h +++ /dev/null @@ -1,208 +0,0 @@ -/** @file - - CompletedTransactionLogData populates TransactionLogData from a live HttpSM. - - @section license License - - 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. - */ - -#pragma once - -#include "proxy/logging/TransactionLogData.h" - -class HttpSM; - -/** Provide TransactionLogData from a live HttpSM via virtual getters. - * - * Each getter reads directly from m_http_sm on demand, avoiding the need to - * copy all fields upfront. The HttpSM must outlive this object. - */ -class CompletedTransactionLogData : public TransactionLogData -{ -public: - /** Construct from a live HttpSM. - * - * @param[in] sm The HttpSM for the completing transaction. - */ - explicit CompletedTransactionLogData(HttpSM *sm); - - void *http_sm_for_plugins() const override; - - // ===== Milestones ===== - TransactionMilestones const *get_milestones() const override; - - // ===== Headers ===== - HTTPHdr *get_client_request() const override; - HTTPHdr *get_proxy_response() const override; - HTTPHdr *get_proxy_request() const override; - HTTPHdr *get_server_response() const override; - HTTPHdr *get_cache_response() const override; - - // ===== Client request URL / path ===== - const char *get_client_req_url_str() const override; - int get_client_req_url_len() const override; - const char *get_client_req_url_path_str() const override; - int get_client_req_url_path_len() const override; - - // ===== Proxy response content-type / reason ===== - char *get_proxy_resp_content_type_str() const override; - int get_proxy_resp_content_type_len() const override; - char *get_proxy_resp_reason_phrase_str() const override; - int get_proxy_resp_reason_phrase_len() const override; - - // ===== Unmapped URL ===== - char *get_unmapped_url_str() const override; - int get_unmapped_url_len() const override; - - // ===== Cache lookup URL ===== - char *get_cache_lookup_url_str() const override; - int get_cache_lookup_url_len() const override; - - // ===== Client addressing ===== - sockaddr const *get_client_addr() const override; - sockaddr const *get_client_src_addr() const override; - sockaddr const *get_client_dst_addr() const override; - sockaddr const *get_verified_client_addr() const override; - uint16_t get_client_port() const override; - - // ===== Server addressing ===== - sockaddr const *get_server_src_addr() const override; - sockaddr const *get_server_dst_addr() const override; - sockaddr const *get_server_info_dst_addr() const override; - const char *get_server_name() const override; - - // ===== Squid codes ===== - SquidLogCode get_log_code() const override; - SquidSubcode get_subcode() const override; - SquidHitMissCode get_hit_miss_code() const override; - SquidHierarchyCode get_hier_code() const override; - - // ===== Byte counters ===== - int64_t get_client_request_body_bytes() const override; - int64_t get_client_response_hdr_bytes() const override; - int64_t get_client_response_body_bytes() const override; - int64_t get_server_request_body_bytes() const override; - int64_t get_server_response_body_bytes() const override; - int64_t get_cache_response_body_bytes() const override; - int64_t get_cache_response_hdr_bytes() const override; - - // ===== Transaction identifiers ===== - int64_t get_sm_id() const override; - int64_t get_connection_id() const override; - int get_transaction_id() const override; - int get_transaction_priority_weight() const override; - int get_transaction_priority_dependence() const override; - - // ===== Plugin info ===== - int64_t get_plugin_id() const override; - const char *get_plugin_tag() const override; - - // ===== Protocol info ===== - const char *get_client_protocol() const override; - const char *get_server_protocol() const override; - const char *get_client_sec_protocol() const override; - const char *get_client_cipher_suite() const override; - const char *get_client_curve() const override; - const char *get_client_security_group() const override; - int get_client_alpn_id() const override; - - // ===== SNI ===== - const char *get_sni_server_name() const override; - - // ===== Connection flags ===== - bool get_client_tcp_reused() const override; - bool get_client_connection_is_ssl() const override; - bool get_client_ssl_reused() const override; - int get_client_ssl_resumption_type() const override; - bool get_is_internal() const override; - bool get_server_connection_is_ssl() const override; - bool get_server_ssl_reused() const override; - int get_server_connection_provided_cert() const override; - int get_client_provided_cert() const override; - - // ===== Server transaction count ===== - int64_t get_server_transact_count() const override; - - // ===== Finish status ===== - int get_client_finish_status_code() const override; - int get_proxy_finish_status_code() const override; - - // ===== Error codes ===== - const char *get_client_rx_error_code() const override; - const char *get_client_tx_error_code() const override; - - // ===== MPTCP ===== - std::optional get_mptcp_state() const override; - - // ===== Misc transaction state ===== - in_port_t get_incoming_port() const override; - int get_orig_scheme() const override; - int64_t get_congestion_control_crat() const override; - - // ===== Cache state ===== - int get_cache_write_code() const override; - int get_cache_transform_write_code() const override; - int get_cache_open_read_tries() const override; - int get_cache_open_write_tries() const override; - int get_max_cache_open_write_retries() const override; - - // ===== Retry attempts ===== - int64_t get_simple_retry_attempts() const override; - int64_t get_unavailable_retry_attempts() const override; - int64_t get_retry_attempts_saved() const override; - - // ===== Status plugin entry name ===== - std::string_view get_http_return_code_setter_name() const override; - - // ===== Proxy Protocol ===== - int get_pp_version() const override; - sockaddr const *get_pp_src_addr() const override; - sockaddr const *get_pp_dst_addr() const override; - std::string_view get_pp_authority() const override; - std::string_view get_pp_tls_cipher() const override; - std::string_view get_pp_tls_version() const override; - - // ===== Server response Transfer-Encoding ===== - std::string_view get_server_response_transfer_encoding() const override; - -private: - HttpSM *m_http_sm; - - // Cached values for fields that require computation or string formatting. - mutable char m_client_rx_error_code[10] = {'-', '\0'}; - mutable char m_client_tx_error_code[10] = {'-', '\0'}; - mutable bool m_error_codes_formatted = false; - - // Cached URL string pointers (computed on first access). - mutable const char *m_client_req_url_str = nullptr; - mutable int m_client_req_url_len = 0; - mutable const char *m_client_req_url_path_str = nullptr; - mutable int m_client_req_url_path_len = 0; - mutable bool m_url_cached = false; - - // Cached content-type pointers (computed on first access). - mutable char *m_proxy_resp_content_type_str = nullptr; - mutable int m_proxy_resp_content_type_len = 0; - mutable char *m_proxy_resp_reason_phrase_str = nullptr; - mutable int m_proxy_resp_reason_phrase_len = 0; - mutable bool m_content_type_cached = false; - - void cache_url_strings() const; - void cache_content_type() const; - void format_error_codes() const; -}; diff --git a/include/proxy/logging/Log.h b/include/proxy/logging/Log.h index 09ce7ab2f73..0064c9dd8e0 100644 --- a/include/proxy/logging/Log.h +++ b/include/proxy/logging/Log.h @@ -43,7 +43,7 @@ @section example Example usage of the API @code - // Populate a LogData (e.g. TransactionLogData or PreTransactionLogData), then: + // Populate a TransactionLogData, then: LogAccess entry(data); int ret = Log::access(&entry); @endcode diff --git a/include/proxy/logging/LogAccess.h b/include/proxy/logging/LogAccess.h index 7fdc82851c9..facfd5f836c 100644 --- a/include/proxy/logging/LogAccess.h +++ b/include/proxy/logging/LogAccess.h @@ -123,8 +123,8 @@ class LogAccess * The caller retains ownership of @a data, which must outlive the * synchronous Log::access() call that marshals this entry. * - * @param[in] data Populated TransactionLogData (CompletedTransactionLogData - * or PreTransactionLogData). + * @param[in] data Populated TransactionLogData for a completed or + * pre-transaction entry. */ explicit LogAccess(TransactionLogData &data); diff --git a/include/proxy/logging/TransactionLogData.h b/include/proxy/logging/TransactionLogData.h index 55ae45150ec..b2942024ca3 100644 --- a/include/proxy/logging/TransactionLogData.h +++ b/include/proxy/logging/TransactionLogData.h @@ -1,6 +1,6 @@ /** @file - Base class providing the data interface for access log entries. + Concrete data accessor for access log entries. @section license License @@ -30,578 +30,194 @@ #include #include -class HTTPHdr; +class HttpSM; +class PreTransactionLogData; -/** Abstract base for the data backing a single access log entry. +/** Provide access-log data from either a completed HttpSM or pre-transaction storage. * - * Subclasses provide data from the appropriate source via virtual getters: - * - CompletedTransactionLogData reads from HttpSM (defined in the http - * module) for transactions that completed normally. - * - PreTransactionLogData returns owned storage (defined in the proxy - * module), for requests that never create an HttpSM. - * - * LogAccess reads only from this interface, so the logging module has no - * compile-time dependency on the http module. + * The common completed-transaction path reads directly from @c HttpSM. The + * rare pre-transaction path reads from @c PreTransactionLogData, which owns + * copied request/session state for malformed requests rejected before HttpSM + * creation. */ class TransactionLogData { public: - virtual ~TransactionLogData() = default; - - /** Return the HttpSM pointer for plugin custom marshal functions. - * - * Only TransactionLogData provides a non-null value. Pre-transaction - * entries have no HttpSM, so plugins receive nullptr. - * - * @return An opaque pointer to the HttpSM, or nullptr. - */ - virtual void * - http_sm_for_plugins() const - { - return nullptr; - } + explicit TransactionLogData(HttpSM *sm); + explicit TransactionLogData(PreTransactionLogData const &pre_data); - // ===== Milestones ===== + void *http_sm_for_plugins() const; - virtual TransactionMilestones const * - get_milestones() const - { - return nullptr; - } + // ===== Milestones ===== + TransactionMilestones const *get_milestones() const; // ===== Headers ===== - - virtual HTTPHdr * - get_client_request() const - { - return nullptr; - } - virtual HTTPHdr * - get_proxy_response() const - { - return nullptr; - } - virtual HTTPHdr * - get_proxy_request() const - { - return nullptr; - } - virtual HTTPHdr * - get_server_response() const - { - return nullptr; - } - virtual HTTPHdr * - get_cache_response() const - { - return nullptr; - } + HTTPHdr *get_client_request() const; + HTTPHdr *get_proxy_response() const; + HTTPHdr *get_proxy_request() const; + HTTPHdr *get_server_response() const; + HTTPHdr *get_cache_response() const; // ===== Client request URL / path ===== - - virtual const char * - get_client_req_url_str() const - { - return nullptr; - } - virtual int - get_client_req_url_len() const - { - return 0; - } - virtual const char * - get_client_req_url_path_str() const - { - return nullptr; - } - virtual int - get_client_req_url_path_len() const - { - return 0; - } + const char *get_client_req_url_str() const; + int get_client_req_url_len() const; + const char *get_client_req_url_path_str() const; + int get_client_req_url_path_len() const; // ===== Proxy response content-type / reason ===== - - virtual char * - get_proxy_resp_content_type_str() const - { - return nullptr; - } - virtual int - get_proxy_resp_content_type_len() const - { - return 0; - } - virtual char * - get_proxy_resp_reason_phrase_str() const - { - return nullptr; - } - virtual int - get_proxy_resp_reason_phrase_len() const - { - return 0; - } + char *get_proxy_resp_content_type_str() const; + int get_proxy_resp_content_type_len() const; + char *get_proxy_resp_reason_phrase_str() const; + int get_proxy_resp_reason_phrase_len() const; // ===== Unmapped URL ===== - - virtual char * - get_unmapped_url_str() const - { - return nullptr; - } - virtual int - get_unmapped_url_len() const - { - return 0; - } + char *get_unmapped_url_str() const; + int get_unmapped_url_len() const; // ===== Cache lookup URL ===== - - virtual char * - get_cache_lookup_url_str() const - { - return nullptr; - } - virtual int - get_cache_lookup_url_len() const - { - return 0; - } + char *get_cache_lookup_url_str() const; + int get_cache_lookup_url_len() const; // ===== Client addressing ===== - - virtual sockaddr const * - get_client_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_client_src_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_client_dst_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_verified_client_addr() const - { - return nullptr; - } - virtual uint16_t - get_client_port() const - { - return 0; - } + sockaddr const *get_client_addr() const; + sockaddr const *get_client_src_addr() const; + sockaddr const *get_client_dst_addr() const; + sockaddr const *get_verified_client_addr() const; + uint16_t get_client_port() const; // ===== Server addressing ===== - - virtual sockaddr const * - get_server_src_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_server_dst_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_server_info_dst_addr() const - { - return nullptr; - } - virtual const char * - get_server_name() const - { - return nullptr; - } + sockaddr const *get_server_src_addr() const; + sockaddr const *get_server_dst_addr() const; + sockaddr const *get_server_info_dst_addr() const; + const char *get_server_name() const; // ===== Squid codes ===== - - virtual SquidLogCode - get_log_code() const - { - return SquidLogCode::EMPTY; - } - virtual SquidSubcode - get_subcode() const - { - return SquidSubcode::EMPTY; - } - virtual SquidHitMissCode - get_hit_miss_code() const - { - return SQUID_MISS_NONE; - } - virtual SquidHierarchyCode - get_hier_code() const - { - return SquidHierarchyCode::NONE; - } + SquidLogCode get_log_code() const; + SquidSubcode get_subcode() const; + SquidHitMissCode get_hit_miss_code() const; + SquidHierarchyCode get_hier_code() const; // ===== Byte counters ===== - - virtual int64_t - get_client_request_body_bytes() const - { - return 0; - } - virtual int64_t - get_client_response_hdr_bytes() const - { - return 0; - } - virtual int64_t - get_client_response_body_bytes() const - { - return 0; - } - virtual int64_t - get_server_request_body_bytes() const - { - return 0; - } - virtual int64_t - get_server_response_body_bytes() const - { - return 0; - } - virtual int64_t - get_cache_response_body_bytes() const - { - return 0; - } - virtual int64_t - get_cache_response_hdr_bytes() const - { - return 0; - } + int64_t get_client_request_body_bytes() const; + int64_t get_client_response_hdr_bytes() const; + int64_t get_client_response_body_bytes() const; + int64_t get_server_request_body_bytes() const; + int64_t get_server_response_body_bytes() const; + int64_t get_cache_response_body_bytes() const; + int64_t get_cache_response_hdr_bytes() const; // ===== Transaction identifiers ===== - - virtual int64_t - get_sm_id() const - { - return 0; - } - virtual int64_t - get_connection_id() const - { - return 0; - } - virtual int - get_transaction_id() const - { - return 0; - } - virtual int - get_transaction_priority_weight() const - { - return 0; - } - virtual int - get_transaction_priority_dependence() const - { - return 0; - } + int64_t get_sm_id() const; + int64_t get_connection_id() const; + int get_transaction_id() const; + int get_transaction_priority_weight() const; + int get_transaction_priority_dependence() const; // ===== Plugin info ===== - - virtual int64_t - get_plugin_id() const - { - return 0; - } - virtual const char * - get_plugin_tag() const - { - return nullptr; - } + int64_t get_plugin_id() const; + const char *get_plugin_tag() const; // ===== Protocol info ===== - - virtual const char * - get_client_protocol() const - { - return nullptr; - } - virtual const char * - get_server_protocol() const - { - return nullptr; - } - virtual const char * - get_client_sec_protocol() const - { - return nullptr; - } - virtual const char * - get_client_cipher_suite() const - { - return nullptr; - } - virtual const char * - get_client_curve() const - { - return nullptr; - } - virtual const char * - get_client_security_group() const - { - return nullptr; - } - virtual int - get_client_alpn_id() const - { - return -1; - } + const char *get_client_protocol() const; + const char *get_server_protocol() const; + const char *get_client_sec_protocol() const; + const char *get_client_cipher_suite() const; + const char *get_client_curve() const; + const char *get_client_security_group() const; + int get_client_alpn_id() const; // ===== SNI ===== - - virtual const char * - get_sni_server_name() const - { - return nullptr; - } + const char *get_sni_server_name() const; // ===== Connection flags ===== - - virtual bool - get_client_tcp_reused() const - { - return false; - } - virtual bool - get_client_connection_is_ssl() const - { - return false; - } - virtual bool - get_client_ssl_reused() const - { - return false; - } - /** Get the client TLS session resumption type (full handshake, session ID, or session ticket). - - @return The HttpUserAgent client SSL resumption type integer. - */ - virtual int - get_client_ssl_resumption_type() const - { - return 0; - } - virtual bool - get_is_internal() const - { - return false; - } - virtual bool - get_server_connection_is_ssl() const - { - return false; - } - virtual bool - get_server_ssl_reused() const - { - return false; - } - virtual int - get_server_connection_provided_cert() const - { - return 0; - } - virtual int - get_client_provided_cert() const - { - return 0; - } + bool get_client_tcp_reused() const; + bool get_client_connection_is_ssl() const; + bool get_client_ssl_reused() const; + int get_client_ssl_resumption_type() const; + bool get_is_internal() const; + bool get_server_connection_is_ssl() const; + bool get_server_ssl_reused() const; + int get_server_connection_provided_cert() const; + int get_client_provided_cert() const; // ===== Server transaction count ===== - - virtual int64_t - get_server_transact_count() const - { - return 0; - } + int64_t get_server_transact_count() const; // ===== Finish status ===== - - virtual int - get_client_finish_status_code() const - { - return 0; - } - virtual int - get_proxy_finish_status_code() const - { - return 0; - } + int get_client_finish_status_code() const; + int get_proxy_finish_status_code() const; // ===== Error codes ===== - - virtual const char * - get_client_rx_error_code() const - { - return "-"; - } - virtual const char * - get_client_tx_error_code() const - { - return "-"; - } + const char *get_client_rx_error_code() const; + const char *get_client_tx_error_code() const; // ===== MPTCP ===== - - virtual std::optional - get_mptcp_state() const - { - return std::nullopt; - } + std::optional get_mptcp_state() const; // ===== Misc transaction state ===== - - virtual in_port_t - get_incoming_port() const - { - return 0; - } - virtual int - get_orig_scheme() const - { - return -1; - } - virtual int64_t - get_congestion_control_crat() const - { - return 0; - } + in_port_t get_incoming_port() const; + int get_orig_scheme() const; + int64_t get_congestion_control_crat() const; // ===== Cache state ===== - - virtual int - get_cache_write_code() const - { - return 0; - } - virtual int - get_cache_transform_write_code() const - { - return 0; - } - virtual int - get_cache_open_read_tries() const - { - return 0; - } - virtual int - get_cache_open_write_tries() const - { - return 0; - } - virtual int - get_max_cache_open_write_retries() const - { - return -1; - } + int get_cache_write_code() const; + int get_cache_transform_write_code() const; + int get_cache_open_read_tries() const; + int get_cache_open_write_tries() const; + int get_max_cache_open_write_retries() const; // ===== Retry attempts ===== - - virtual int64_t - get_simple_retry_attempts() const - { - return 0; - } - virtual int64_t - get_unavailable_retry_attempts() const - { - return 0; - } - virtual int64_t - get_retry_attempts_saved() const - { - return 0; - } + int64_t get_simple_retry_attempts() const; + int64_t get_unavailable_retry_attempts() const; + int64_t get_retry_attempts_saved() const; // ===== Status plugin entry name ===== - - virtual std::string_view - get_http_return_code_setter_name() const - { - return {}; - } + std::string_view get_http_return_code_setter_name() const; // ===== Proxy Protocol ===== - - virtual int - get_pp_version() const - { - return 0; - } - virtual sockaddr const * - get_pp_src_addr() const - { - return nullptr; - } - virtual sockaddr const * - get_pp_dst_addr() const - { - return nullptr; - } - virtual std::string_view - get_pp_authority() const - { - return {}; - } - virtual std::string_view - get_pp_tls_cipher() const - { - return {}; - } - virtual std::string_view - get_pp_tls_version() const - { - return {}; - } - virtual std::string_view - get_pp_tls_group() const - { - return {}; - } + int get_pp_version() const; + sockaddr const *get_pp_src_addr() const; + sockaddr const *get_pp_dst_addr() const; + std::string_view get_pp_authority() const; + std::string_view get_pp_tls_cipher() const; + std::string_view get_pp_tls_version() const; + std::string_view get_pp_tls_group() const; // ===== Server response Transfer-Encoding ===== - - virtual std::string_view - get_server_response_transfer_encoding() const - { - return {}; - } + std::string_view get_server_response_transfer_encoding() const; // ===== Fallback fields for pre-transaction logging ===== + std::string_view get_method() const; + std::string_view get_scheme() const; + std::string_view get_client_protocol_str() const; - virtual std::string_view - get_method() const - { - return {}; - } - virtual std::string_view - get_scheme() const - { - return {}; - } - virtual std::string_view - get_client_protocol_str() const - { - return {}; - } - - // noncopyable TransactionLogData(const TransactionLogData &) = delete; TransactionLogData &operator=(const TransactionLogData &) = delete; -protected: - TransactionLogData() = default; +private: + HttpSM *m_http_sm = nullptr; + PreTransactionLogData const *m_pre_data = nullptr; + + // Cached values for fields that require computation or string formatting. + mutable char m_client_rx_error_code[10] = {'-', '\0'}; + mutable char m_client_tx_error_code[10] = {'-', '\0'}; + mutable bool m_error_codes_formatted = false; + + // Cached URL string pointers (computed on first access). + mutable const char *m_client_req_url_str = nullptr; + mutable int m_client_req_url_len = 0; + mutable const char *m_client_req_url_path_str = nullptr; + mutable int m_client_req_url_path_len = 0; + mutable bool m_url_cached = false; + + // Cached content-type pointers (computed on first access). + mutable char *m_proxy_resp_content_type_str = nullptr; + mutable int m_proxy_resp_content_type_len = 0; + mutable char *m_proxy_resp_reason_phrase_str = nullptr; + mutable int m_proxy_resp_reason_phrase_len = 0; + mutable bool m_content_type_cached = false; + + void cache_url_strings() const; + void cache_content_type() const; + void format_error_codes() const; }; diff --git a/src/proxy/ProxyTransaction.cc b/src/proxy/ProxyTransaction.cc index ee02429722f..c2a5a4584e7 100644 --- a/src/proxy/ProxyTransaction.cc +++ b/src/proxy/ProxyTransaction.cc @@ -25,6 +25,7 @@ #include "proxy/Plugin.h" #include "proxy/PreTransactionLogData.h" #include "proxy/logging/LogAccess.h" +#include "proxy/logging/TransactionLogData.h" #include "proxy/logging/Log.h" namespace @@ -411,6 +412,7 @@ ProxyTransaction::log_pre_transaction_access(HTTPHdr const *request, const char data.owned_milestones[TS_MILESTONE_UA_READ_HEADER_DONE] = now; data.owned_milestones[TS_MILESTONE_SM_FINISH] = now; - LogAccess access(data); + TransactionLogData log_data(data); + LogAccess access(log_data); Log::access(&access); } diff --git a/src/proxy/http/CMakeLists.txt b/src/proxy/http/CMakeLists.txt index 94a3130803a..55cf7ebd36e 100644 --- a/src/proxy/http/CMakeLists.txt +++ b/src/proxy/http/CMakeLists.txt @@ -27,7 +27,6 @@ add_library( HttpDebugNames.cc HttpProxyServerMain.cc HttpSM.cc - CompletedTransactionLogData.cc Http1ServerSession.cc HttpSessionManager.cc HttpTransact.cc diff --git a/src/proxy/http/CompletedTransactionLogData.cc b/src/proxy/http/CompletedTransactionLogData.cc deleted file mode 100644 index 4c8f4188192..00000000000 --- a/src/proxy/http/CompletedTransactionLogData.cc +++ /dev/null @@ -1,832 +0,0 @@ -/** @file - - CompletedTransactionLogData implementation: read TransactionLogData from a - live HttpSM. - - @section license License - - 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. - */ - -#include "proxy/http/CompletedTransactionLogData.h" -#include "proxy/http/HttpSM.h" -#include "proxy/logging/LogAccess.h" -#include "proxy/hdrs/MIME.h" -#include "../private/SSLProxySession.h" - -namespace -{ -/** Map HttpTransact::CacheWriteStatus_t to LogCacheWriteCodeType. */ -int -convert_cache_write_code(HttpTransact::CacheWriteStatus_t t) -{ - switch (t) { - case HttpTransact::CacheWriteStatus_t::NO_WRITE: - return LOG_CACHE_WRITE_NONE; - case HttpTransact::CacheWriteStatus_t::LOCK_MISS: - return LOG_CACHE_WRITE_LOCK_MISSED; - case HttpTransact::CacheWriteStatus_t::IN_PROGRESS: - return LOG_CACHE_WRITE_LOCK_ABORTED; - case HttpTransact::CacheWriteStatus_t::ERROR: - return LOG_CACHE_WRITE_ERROR; - case HttpTransact::CacheWriteStatus_t::COMPLETE: - return LOG_CACHE_WRITE_COMPLETE; - default: - ink_assert(!"bad cache write code"); - return LOG_CACHE_WRITE_NONE; - } -} - -int -compute_client_finish_status(HttpSM *sm) -{ - HttpTransact::AbortState_t cl_abort_state = sm->t_state.client_info.abort; - if (cl_abort_state == HttpTransact::ABORTED) { - if (sm->t_state.client_info.state == HttpTransact::ACTIVE_TIMEOUT || - sm->t_state.client_info.state == HttpTransact::INACTIVE_TIMEOUT) { - return LOG_FINISH_TIMEOUT; - } - return LOG_FINISH_INTR; - } - return LOG_FINISH_FIN; -} - -int -compute_proxy_finish_status(HttpSM *sm) -{ - if (sm->t_state.current.server) { - switch (sm->t_state.current.server->state) { - case HttpTransact::ACTIVE_TIMEOUT: - case HttpTransact::INACTIVE_TIMEOUT: - return LOG_FINISH_TIMEOUT; - case HttpTransact::CONNECTION_ERROR: - return LOG_FINISH_INTR; - default: - if (sm->t_state.current.server->abort == HttpTransact::ABORTED) { - return LOG_FINISH_INTR; - } - break; - } - } - return LOG_FINISH_FIN; -} -} // end anonymous namespace - -CompletedTransactionLogData::CompletedTransactionLogData(HttpSM *sm) : m_http_sm(sm) -{ - ink_assert(sm != nullptr); -} - -void * -CompletedTransactionLogData::http_sm_for_plugins() const -{ - return m_http_sm; -} - -// ===== Milestones ===== - -TransactionMilestones const * -CompletedTransactionLogData::get_milestones() const -{ - return &m_http_sm->milestones; -} - -// ===== Headers ===== - -HTTPHdr * -CompletedTransactionLogData::get_client_request() const -{ - HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; - if (hdr->client_request.valid()) { - return &hdr->client_request; - } - return nullptr; -} - -HTTPHdr * -CompletedTransactionLogData::get_proxy_response() const -{ - HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; - if (hdr->client_response.valid()) { - return &hdr->client_response; - } - return nullptr; -} - -HTTPHdr * -CompletedTransactionLogData::get_proxy_request() const -{ - HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; - if (hdr->server_request.valid()) { - return &hdr->server_request; - } - return nullptr; -} - -HTTPHdr * -CompletedTransactionLogData::get_server_response() const -{ - HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; - if (hdr->server_response.valid()) { - return &hdr->server_response; - } - return nullptr; -} - -HTTPHdr * -CompletedTransactionLogData::get_cache_response() const -{ - HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; - if (hdr->cache_response.valid()) { - return &hdr->cache_response; - } - return nullptr; -} - -// ===== Client request URL / path ===== - -void -CompletedTransactionLogData::cache_url_strings() const -{ - if (m_url_cached) { - return; - } - m_url_cached = true; - - HTTPHdr *client_request = get_client_request(); - if (client_request) { - m_client_req_url_str = client_request->url_string_get_ref(&m_client_req_url_len); - auto path_sv = client_request->path_get(); - m_client_req_url_path_str = path_sv.data(); - m_client_req_url_path_len = static_cast(path_sv.length()); - } -} - -const char * -CompletedTransactionLogData::get_client_req_url_str() const -{ - cache_url_strings(); - return m_client_req_url_str; -} - -int -CompletedTransactionLogData::get_client_req_url_len() const -{ - cache_url_strings(); - return m_client_req_url_len; -} - -const char * -CompletedTransactionLogData::get_client_req_url_path_str() const -{ - cache_url_strings(); - return m_client_req_url_path_str; -} - -int -CompletedTransactionLogData::get_client_req_url_path_len() const -{ - cache_url_strings(); - return m_client_req_url_path_len; -} - -// ===== Proxy response content-type / reason ===== - -void -CompletedTransactionLogData::cache_content_type() const -{ - if (m_content_type_cached) { - return; - } - m_content_type_cached = true; - - HTTPHdr *proxy_response = get_proxy_response(); - if (proxy_response) { - MIMEField *field = proxy_response->field_find(static_cast(MIME_FIELD_CONTENT_TYPE)); - if (field) { - auto ct = field->value_get(); - m_proxy_resp_content_type_str = const_cast(ct.data()); - m_proxy_resp_content_type_len = ct.length(); - } else { - constexpr std::string_view hidden_ct{"@Content-Type"}; - field = proxy_response->field_find(hidden_ct); - if (field) { - auto ct = field->value_get(); - m_proxy_resp_content_type_str = const_cast(ct.data()); - m_proxy_resp_content_type_len = ct.length(); - } - } - auto reason = proxy_response->reason_get(); - m_proxy_resp_reason_phrase_str = const_cast(reason.data()); - m_proxy_resp_reason_phrase_len = static_cast(reason.length()); - } -} - -char * -CompletedTransactionLogData::get_proxy_resp_content_type_str() const -{ - cache_content_type(); - return m_proxy_resp_content_type_str; -} - -int -CompletedTransactionLogData::get_proxy_resp_content_type_len() const -{ - cache_content_type(); - return m_proxy_resp_content_type_len; -} - -char * -CompletedTransactionLogData::get_proxy_resp_reason_phrase_str() const -{ - cache_content_type(); - return m_proxy_resp_reason_phrase_str; -} - -int -CompletedTransactionLogData::get_proxy_resp_reason_phrase_len() const -{ - cache_content_type(); - return m_proxy_resp_reason_phrase_len; -} - -// ===== Unmapped URL ===== - -char * -CompletedTransactionLogData::get_unmapped_url_str() const -{ - if (m_http_sm->t_state.unmapped_url.valid()) { - int len = 0; - return m_http_sm->t_state.unmapped_url.string_get_ref(&len); - } - return nullptr; -} - -int -CompletedTransactionLogData::get_unmapped_url_len() const -{ - if (m_http_sm->t_state.unmapped_url.valid()) { - int len = 0; - m_http_sm->t_state.unmapped_url.string_get_ref(&len); - return len; - } - return 0; -} - -// ===== Cache lookup URL ===== - -char * -CompletedTransactionLogData::get_cache_lookup_url_str() const -{ - if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) { - int len = 0; - return m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len); - } - return nullptr; -} - -int -CompletedTransactionLogData::get_cache_lookup_url_len() const -{ - if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) { - int len = 0; - m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len); - return len; - } - return 0; -} - -// ===== Client addressing ===== - -sockaddr const * -CompletedTransactionLogData::get_client_addr() const -{ - return &m_http_sm->t_state.effective_client_addr.sa; -} - -sockaddr const * -CompletedTransactionLogData::get_client_src_addr() const -{ - return &m_http_sm->t_state.client_info.src_addr.sa; -} - -sockaddr const * -CompletedTransactionLogData::get_client_dst_addr() const -{ - return &m_http_sm->t_state.client_info.dst_addr.sa; -} - -sockaddr const * -CompletedTransactionLogData::get_verified_client_addr() const -{ - if (auto txn = m_http_sm->get_ua_txn(); txn) { - sockaddr const *vaddr = txn->get_verified_client_addr(); - if (vaddr && ats_is_ip(vaddr)) { - return vaddr; - } - } - return nullptr; -} - -uint16_t -CompletedTransactionLogData::get_client_port() const -{ - if (auto txn = m_http_sm->get_ua_txn(); txn) { - return txn->get_client_port(); - } - return 0; -} - -// ===== Server addressing ===== - -sockaddr const * -CompletedTransactionLogData::get_server_src_addr() const -{ - if (m_http_sm->t_state.current.server) { - return &m_http_sm->t_state.current.server->src_addr.sa; - } - return nullptr; -} - -sockaddr const * -CompletedTransactionLogData::get_server_dst_addr() const -{ - if (m_http_sm->t_state.current.server) { - return &m_http_sm->t_state.current.server->dst_addr.sa; - } - return nullptr; -} - -sockaddr const * -CompletedTransactionLogData::get_server_info_dst_addr() const -{ - return &m_http_sm->t_state.server_info.dst_addr.sa; -} - -const char * -CompletedTransactionLogData::get_server_name() const -{ - if (m_http_sm->t_state.current.server) { - return m_http_sm->t_state.current.server->name; - } - return nullptr; -} - -// ===== Squid codes ===== - -SquidLogCode -CompletedTransactionLogData::get_log_code() const -{ - return m_http_sm->t_state.squid_codes.log_code; -} - -SquidSubcode -CompletedTransactionLogData::get_subcode() const -{ - return m_http_sm->t_state.squid_codes.subcode; -} - -SquidHitMissCode -CompletedTransactionLogData::get_hit_miss_code() const -{ - return m_http_sm->t_state.squid_codes.hit_miss_code; -} - -SquidHierarchyCode -CompletedTransactionLogData::get_hier_code() const -{ - return m_http_sm->t_state.squid_codes.hier_code; -} - -// ===== Byte counters ===== - -int64_t -CompletedTransactionLogData::get_client_request_body_bytes() const -{ - return m_http_sm->client_request_body_bytes; -} - -int64_t -CompletedTransactionLogData::get_client_response_hdr_bytes() const -{ - return m_http_sm->client_response_hdr_bytes; -} - -int64_t -CompletedTransactionLogData::get_client_response_body_bytes() const -{ - return m_http_sm->client_response_body_bytes; -} - -int64_t -CompletedTransactionLogData::get_server_request_body_bytes() const -{ - return m_http_sm->server_request_body_bytes; -} - -int64_t -CompletedTransactionLogData::get_server_response_body_bytes() const -{ - return m_http_sm->server_response_body_bytes; -} - -int64_t -CompletedTransactionLogData::get_cache_response_body_bytes() const -{ - return m_http_sm->cache_response_body_bytes; -} - -int64_t -CompletedTransactionLogData::get_cache_response_hdr_bytes() const -{ - return m_http_sm->cache_response_hdr_bytes; -} - -// ===== Transaction identifiers ===== - -int64_t -CompletedTransactionLogData::get_sm_id() const -{ - return m_http_sm->sm_id; -} - -int64_t -CompletedTransactionLogData::get_connection_id() const -{ - return m_http_sm->client_connection_id(); -} - -int -CompletedTransactionLogData::get_transaction_id() const -{ - return m_http_sm->client_transaction_id(); -} - -int -CompletedTransactionLogData::get_transaction_priority_weight() const -{ - return m_http_sm->client_transaction_priority_weight(); -} - -int -CompletedTransactionLogData::get_transaction_priority_dependence() const -{ - return m_http_sm->client_transaction_priority_dependence(); -} - -// ===== Plugin info ===== - -int64_t -CompletedTransactionLogData::get_plugin_id() const -{ - return m_http_sm->plugin_id; -} - -const char * -CompletedTransactionLogData::get_plugin_tag() const -{ - return m_http_sm->plugin_tag; -} - -// ===== Protocol info ===== - -const char * -CompletedTransactionLogData::get_client_protocol() const -{ - return m_http_sm->get_user_agent().get_client_protocol(); -} - -const char * -CompletedTransactionLogData::get_server_protocol() const -{ - return m_http_sm->server_protocol; -} - -const char * -CompletedTransactionLogData::get_client_sec_protocol() const -{ - return m_http_sm->get_user_agent().get_client_sec_protocol(); -} - -const char * -CompletedTransactionLogData::get_client_cipher_suite() const -{ - return m_http_sm->get_user_agent().get_client_cipher_suite(); -} - -const char * -CompletedTransactionLogData::get_client_curve() const -{ - return m_http_sm->get_user_agent().get_client_curve(); -} - -const char * -CompletedTransactionLogData::get_client_security_group() const -{ - return m_http_sm->get_user_agent().get_client_security_group(); -} - -int -CompletedTransactionLogData::get_client_alpn_id() const -{ - return m_http_sm->get_user_agent().get_client_alpn_id(); -} - -// ===== SNI ===== - -const char * -CompletedTransactionLogData::get_sni_server_name() const -{ - if (auto txn = m_http_sm->get_ua_txn(); txn) { - if (auto ssn = txn->get_proxy_ssn(); ssn) { - if (auto ssl = ssn->ssl(); ssl) { - return ssl->client_sni_server_name(); - } - } - } - return nullptr; -} - -// ===== Connection flags ===== - -bool -CompletedTransactionLogData::get_client_tcp_reused() const -{ - return m_http_sm->get_user_agent().get_client_tcp_reused(); -} - -bool -CompletedTransactionLogData::get_client_connection_is_ssl() const -{ - return m_http_sm->get_user_agent().get_client_connection_is_ssl(); -} - -bool -CompletedTransactionLogData::get_client_ssl_reused() const -{ - return m_http_sm->get_user_agent().get_client_ssl_reused(); -} - -int -CompletedTransactionLogData::get_client_ssl_resumption_type() const -{ - return m_http_sm->get_user_agent().get_client_ssl_resumption_type(); -} - -bool -CompletedTransactionLogData::get_is_internal() const -{ - return m_http_sm->is_internal; -} - -bool -CompletedTransactionLogData::get_server_connection_is_ssl() const -{ - return m_http_sm->server_connection_is_ssl; -} - -bool -CompletedTransactionLogData::get_server_ssl_reused() const -{ - return m_http_sm->server_ssl_reused; -} - -int -CompletedTransactionLogData::get_server_connection_provided_cert() const -{ - return m_http_sm->server_connection_provided_cert; -} - -int -CompletedTransactionLogData::get_client_provided_cert() const -{ - if (auto txn = m_http_sm->get_ua_txn(); txn) { - if (auto ssn = txn->get_proxy_ssn(); ssn) { - if (auto ssl = ssn->ssl(); ssl) { - return ssl->client_provided_certificate(); - } - } - } - return 0; -} - -// ===== Server transaction count ===== - -int64_t -CompletedTransactionLogData::get_server_transact_count() const -{ - return m_http_sm->server_transact_count; -} - -// ===== Finish status ===== - -int -CompletedTransactionLogData::get_client_finish_status_code() const -{ - return compute_client_finish_status(m_http_sm); -} - -int -CompletedTransactionLogData::get_proxy_finish_status_code() const -{ - return compute_proxy_finish_status(m_http_sm); -} - -// ===== Error codes ===== - -void -CompletedTransactionLogData::format_error_codes() const -{ - if (m_error_codes_formatted) { - return; - } - m_error_codes_formatted = true; - m_http_sm->t_state.client_info.rx_error_code.str(m_client_rx_error_code, sizeof(m_client_rx_error_code)); - m_http_sm->t_state.client_info.tx_error_code.str(m_client_tx_error_code, sizeof(m_client_tx_error_code)); -} - -const char * -CompletedTransactionLogData::get_client_rx_error_code() const -{ - format_error_codes(); - return m_client_rx_error_code; -} - -const char * -CompletedTransactionLogData::get_client_tx_error_code() const -{ - format_error_codes(); - return m_client_tx_error_code; -} - -// ===== MPTCP ===== - -std::optional -CompletedTransactionLogData::get_mptcp_state() const -{ - return m_http_sm->mptcp_state; -} - -// ===== Misc transaction state ===== - -in_port_t -CompletedTransactionLogData::get_incoming_port() const -{ - return m_http_sm->t_state.request_data.incoming_port; -} - -int -CompletedTransactionLogData::get_orig_scheme() const -{ - return m_http_sm->t_state.orig_scheme; -} - -int64_t -CompletedTransactionLogData::get_congestion_control_crat() const -{ - return m_http_sm->t_state.congestion_control_crat; -} - -// ===== Cache state ===== - -int -CompletedTransactionLogData::get_cache_write_code() const -{ - return convert_cache_write_code(m_http_sm->t_state.cache_info.write_status); -} - -int -CompletedTransactionLogData::get_cache_transform_write_code() const -{ - return convert_cache_write_code(m_http_sm->t_state.cache_info.transform_write_status); -} - -int -CompletedTransactionLogData::get_cache_open_read_tries() const -{ - return m_http_sm->get_cache_sm().get_open_read_tries(); -} - -int -CompletedTransactionLogData::get_cache_open_write_tries() const -{ - return m_http_sm->get_cache_sm().get_open_write_tries(); -} - -int -CompletedTransactionLogData::get_max_cache_open_write_retries() const -{ - return m_http_sm->t_state.txn_conf->max_cache_open_write_retries; -} - -// ===== Retry attempts ===== - -int64_t -CompletedTransactionLogData::get_simple_retry_attempts() const -{ - return m_http_sm->t_state.current.simple_retry_attempts; -} - -int64_t -CompletedTransactionLogData::get_unavailable_retry_attempts() const -{ - return m_http_sm->t_state.current.unavailable_server_retry_attempts; -} - -int64_t -CompletedTransactionLogData::get_retry_attempts_saved() const -{ - return m_http_sm->t_state.current.retry_attempts.saved(); -} - -// ===== Status plugin entry name ===== - -std::string_view -CompletedTransactionLogData::get_http_return_code_setter_name() const -{ - return m_http_sm->t_state.http_return_code_setter_name; -} - -// ===== Proxy Protocol ===== - -int -CompletedTransactionLogData::get_pp_version() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - return static_cast(m_http_sm->t_state.pp_info.version); - } - return 0; -} - -sockaddr const * -CompletedTransactionLogData::get_pp_src_addr() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - return &m_http_sm->t_state.pp_info.src_addr.sa; - } - return nullptr; -} - -sockaddr const * -CompletedTransactionLogData::get_pp_dst_addr() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - return &m_http_sm->t_state.pp_info.dst_addr.sa; - } - return nullptr; -} - -std::string_view -CompletedTransactionLogData::get_pp_authority() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - if (auto authority_opt = m_http_sm->t_state.pp_info.get_tlv(PP2_TYPE_AUTHORITY); authority_opt) { - return *authority_opt; - } - } - return {}; -} - -std::string_view -CompletedTransactionLogData::get_pp_tls_cipher() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - if (auto cipher = m_http_sm->t_state.pp_info.get_tlv_ssl_cipher(); cipher) { - return *cipher; - } - } - return {}; -} - -std::string_view -CompletedTransactionLogData::get_pp_tls_version() const -{ - if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { - if (auto version = m_http_sm->t_state.pp_info.get_tlv_ssl_version(); version) { - return *version; - } - } - return {}; -} - -// ===== Server response Transfer-Encoding ===== - -std::string_view -CompletedTransactionLogData::get_server_response_transfer_encoding() const -{ - return m_http_sm->t_state.hdr_info.server_response_transfer_encoding; -} diff --git a/src/proxy/http/HttpBodyFactory.cc b/src/proxy/http/HttpBodyFactory.cc index 05849b781e3..cdaaac582d8 100644 --- a/src/proxy/http/HttpBodyFactory.cc +++ b/src/proxy/http/HttpBodyFactory.cc @@ -40,7 +40,7 @@ #include "proxy/hdrs/URL.h" #include "proxy/logging/Log.h" #include "proxy/logging/LogAccess.h" -#include "proxy/http/CompletedTransactionLogData.h" +#include "proxy/logging/TransactionLogData.h" #include "proxy/hdrs/HttpCompat.h" #include "tscore/Layout.h" @@ -1158,8 +1158,8 @@ HttpBodyTemplate::build_instantiated_buffer(HttpTransact::State *context, int64_ Dbg(dbg_ctl_body_factory_instantiation, " before instantiation: [%s]", template_buffer); - CompletedTransactionLogData log_data(context->state_machine); - LogAccess la(log_data); + TransactionLogData log_data(context->state_machine); + LogAccess la(log_data); buffer = resolve_logfield_string(&la, template_buffer); diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc index 2bc3654a515..481dcf60752 100644 --- a/src/proxy/http/HttpSM.cc +++ b/src/proxy/http/HttpSM.cc @@ -45,7 +45,7 @@ #include "proxy/http/PreWarmConfig.h" #include "proxy/logging/Log.h" #include "proxy/logging/LogAccess.h" -#include "proxy/http/CompletedTransactionLogData.h" +#include "proxy/logging/TransactionLogData.h" #include "proxy/PluginVC.h" #include "proxy/ReverseProxy.h" #include "proxy/http/remap/RemapProcessor.h" @@ -7714,8 +7714,8 @@ HttpSM::kill_this() ////////////// SMDbg(dbg_ctl_http_seq, "Logging transaction"); if (Log::transaction_logging_enabled() && t_state.api_info.logging_enabled) { - CompletedTransactionLogData log_data(this); - LogAccess accessor(log_data); + TransactionLogData log_data(this); + LogAccess accessor(log_data); int ret = Log::access(&accessor); @@ -8443,8 +8443,8 @@ HttpSM::do_redirect() if (redirect_url != nullptr || t_state.hdr_info.client_response.field_find(static_cast(MIME_FIELD_LOCATION))) { if (Log::transaction_logging_enabled() && t_state.api_info.logging_enabled) { - CompletedTransactionLogData log_data(this); - LogAccess accessor(log_data); + TransactionLogData log_data(this); + LogAccess accessor(log_data); if (redirect_url == nullptr) { if (t_state.squid_codes.log_code == SquidLogCode::TCP_HIT) { t_state.squid_codes.log_code = SquidLogCode::TCP_HIT_REDIRECT; diff --git a/src/proxy/logging/CMakeLists.txt b/src/proxy/logging/CMakeLists.txt index f9da235e073..24c8cccf76e 100644 --- a/src/proxy/logging/CMakeLists.txt +++ b/src/proxy/logging/CMakeLists.txt @@ -28,6 +28,7 @@ add_library( LogFormat.cc LogFieldFallback.cc LogObject.cc + TransactionLogData.cc LogUtils.cc RolledLogDeleter.cc YamlLogConfig.cc diff --git a/src/proxy/logging/TransactionLogData.cc b/src/proxy/logging/TransactionLogData.cc new file mode 100644 index 00000000000..1a6b0ff4de7 --- /dev/null +++ b/src/proxy/logging/TransactionLogData.cc @@ -0,0 +1,1119 @@ +/** @file + + TransactionLogData implementation. + + @section license License + + 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. + */ + +#include "proxy/logging/TransactionLogData.h" +#include "proxy/PreTransactionLogData.h" +#include "proxy/http/HttpSM.h" +#include "proxy/logging/LogAccess.h" +#include "proxy/hdrs/MIME.h" +#include "tscore/ink_defs.h" +#include "../private/SSLProxySession.h" + +namespace +{ +/** Map HttpTransact::CacheWriteStatus_t to LogCacheWriteCodeType. */ +int +convert_cache_write_code(HttpTransact::CacheWriteStatus_t t) +{ + switch (t) { + case HttpTransact::CacheWriteStatus_t::NO_WRITE: + return LOG_CACHE_WRITE_NONE; + case HttpTransact::CacheWriteStatus_t::LOCK_MISS: + return LOG_CACHE_WRITE_LOCK_MISSED; + case HttpTransact::CacheWriteStatus_t::IN_PROGRESS: + return LOG_CACHE_WRITE_LOCK_ABORTED; + case HttpTransact::CacheWriteStatus_t::ERROR: + return LOG_CACHE_WRITE_ERROR; + case HttpTransact::CacheWriteStatus_t::COMPLETE: + return LOG_CACHE_WRITE_COMPLETE; + default: + ink_assert(!"bad cache write code"); + return LOG_CACHE_WRITE_NONE; + } +} + +int +compute_client_finish_status(HttpSM *sm) +{ + HttpTransact::AbortState_t cl_abort_state = sm->t_state.client_info.abort; + if (cl_abort_state == HttpTransact::ABORTED) { + if (sm->t_state.client_info.state == HttpTransact::ACTIVE_TIMEOUT || + sm->t_state.client_info.state == HttpTransact::INACTIVE_TIMEOUT) { + return LOG_FINISH_TIMEOUT; + } + return LOG_FINISH_INTR; + } + return LOG_FINISH_FIN; +} + +int +compute_proxy_finish_status(HttpSM *sm) +{ + if (sm->t_state.current.server) { + switch (sm->t_state.current.server->state) { + case HttpTransact::ACTIVE_TIMEOUT: + case HttpTransact::INACTIVE_TIMEOUT: + return LOG_FINISH_TIMEOUT; + case HttpTransact::CONNECTION_ERROR: + return LOG_FINISH_INTR; + default: + if (sm->t_state.current.server->abort == HttpTransact::ABORTED) { + return LOG_FINISH_INTR; + } + break; + } + } + return LOG_FINISH_FIN; +} +} // end anonymous namespace + +TransactionLogData::TransactionLogData(HttpSM *sm) : m_http_sm(sm) +{ + ink_assert(sm != nullptr); +} + +TransactionLogData::TransactionLogData(PreTransactionLogData const &pre_data) : m_pre_data(&pre_data) {} + +void * +TransactionLogData::http_sm_for_plugins() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm; + } + return nullptr; +} + +// ===== Milestones ===== + +TransactionMilestones const * +TransactionLogData::get_milestones() const +{ + if (likely(m_http_sm != nullptr)) { + return &m_http_sm->milestones; + } + return &m_pre_data->owned_milestones; +} + +// ===== Headers ===== + +HTTPHdr * +TransactionLogData::get_client_request() const +{ + if (likely(m_http_sm != nullptr)) { + HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; + if (hdr->client_request.valid()) { + return &hdr->client_request; + } + return nullptr; + } + + if (m_pre_data->owned_client_request.valid()) { + return const_cast(&m_pre_data->owned_client_request); + } + return nullptr; +} + +HTTPHdr * +TransactionLogData::get_proxy_response() const +{ + if (likely(m_http_sm != nullptr)) { + HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; + if (hdr->client_response.valid()) { + return &hdr->client_response; + } + } + return nullptr; +} + +HTTPHdr * +TransactionLogData::get_proxy_request() const +{ + if (likely(m_http_sm != nullptr)) { + HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; + if (hdr->server_request.valid()) { + return &hdr->server_request; + } + } + return nullptr; +} + +HTTPHdr * +TransactionLogData::get_server_response() const +{ + if (likely(m_http_sm != nullptr)) { + HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; + if (hdr->server_response.valid()) { + return &hdr->server_response; + } + } + return nullptr; +} + +HTTPHdr * +TransactionLogData::get_cache_response() const +{ + if (likely(m_http_sm != nullptr)) { + HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info; + if (hdr->cache_response.valid()) { + return &hdr->cache_response; + } + } + return nullptr; +} + +// ===== Client request URL / path ===== + +void +TransactionLogData::cache_url_strings() const +{ + if (m_url_cached) { + return; + } + m_url_cached = true; + + HTTPHdr *client_request = get_client_request(); + if (client_request) { + m_client_req_url_str = client_request->url_string_get_ref(&m_client_req_url_len); + auto path_sv = client_request->path_get(); + m_client_req_url_path_str = path_sv.data(); + m_client_req_url_path_len = static_cast(path_sv.length()); + } +} + +const char * +TransactionLogData::get_client_req_url_str() const +{ + if (likely(m_http_sm != nullptr)) { + cache_url_strings(); + return m_client_req_url_str; + } + return m_pre_data->owned_url.empty() ? nullptr : m_pre_data->owned_url.c_str(); +} + +int +TransactionLogData::get_client_req_url_len() const +{ + if (likely(m_http_sm != nullptr)) { + cache_url_strings(); + return m_client_req_url_len; + } + return static_cast(m_pre_data->owned_url.size()); +} + +const char * +TransactionLogData::get_client_req_url_path_str() const +{ + if (likely(m_http_sm != nullptr)) { + cache_url_strings(); + return m_client_req_url_path_str; + } + return m_pre_data->owned_path.empty() ? nullptr : m_pre_data->owned_path.c_str(); +} + +int +TransactionLogData::get_client_req_url_path_len() const +{ + if (likely(m_http_sm != nullptr)) { + cache_url_strings(); + return m_client_req_url_path_len; + } + return static_cast(m_pre_data->owned_path.size()); +} + +// ===== Proxy response content-type / reason ===== + +void +TransactionLogData::cache_content_type() const +{ + if (m_content_type_cached) { + return; + } + m_content_type_cached = true; + + HTTPHdr *proxy_response = get_proxy_response(); + if (proxy_response) { + MIMEField *field = proxy_response->field_find(static_cast(MIME_FIELD_CONTENT_TYPE)); + if (field) { + auto ct = field->value_get(); + m_proxy_resp_content_type_str = const_cast(ct.data()); + m_proxy_resp_content_type_len = ct.length(); + } else { + constexpr std::string_view hidden_ct{"@Content-Type"}; + field = proxy_response->field_find(hidden_ct); + if (field) { + auto ct = field->value_get(); + m_proxy_resp_content_type_str = const_cast(ct.data()); + m_proxy_resp_content_type_len = ct.length(); + } + } + auto reason = proxy_response->reason_get(); + m_proxy_resp_reason_phrase_str = const_cast(reason.data()); + m_proxy_resp_reason_phrase_len = static_cast(reason.length()); + } +} + +char * +TransactionLogData::get_proxy_resp_content_type_str() const +{ + if (likely(m_http_sm != nullptr)) { + cache_content_type(); + return m_proxy_resp_content_type_str; + } + return nullptr; +} + +int +TransactionLogData::get_proxy_resp_content_type_len() const +{ + if (likely(m_http_sm != nullptr)) { + cache_content_type(); + return m_proxy_resp_content_type_len; + } + return 0; +} + +char * +TransactionLogData::get_proxy_resp_reason_phrase_str() const +{ + if (likely(m_http_sm != nullptr)) { + cache_content_type(); + return m_proxy_resp_reason_phrase_str; + } + return nullptr; +} + +int +TransactionLogData::get_proxy_resp_reason_phrase_len() const +{ + if (likely(m_http_sm != nullptr)) { + cache_content_type(); + return m_proxy_resp_reason_phrase_len; + } + return 0; +} + +// ===== Unmapped URL ===== + +char * +TransactionLogData::get_unmapped_url_str() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.unmapped_url.valid()) { + int len = 0; + return m_http_sm->t_state.unmapped_url.string_get_ref(&len); + } + } + return nullptr; +} + +int +TransactionLogData::get_unmapped_url_len() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.unmapped_url.valid()) { + int len = 0; + m_http_sm->t_state.unmapped_url.string_get_ref(&len); + return len; + } + } + return 0; +} + +// ===== Cache lookup URL ===== + +char * +TransactionLogData::get_cache_lookup_url_str() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) { + int len = 0; + return m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len); + } + } + return nullptr; +} + +int +TransactionLogData::get_cache_lookup_url_len() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) { + int len = 0; + m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len); + return len; + } + } + return 0; +} + +// ===== Client addressing ===== + +sockaddr const * +TransactionLogData::get_client_addr() const +{ + if (likely(m_http_sm != nullptr)) { + return &m_http_sm->t_state.effective_client_addr.sa; + } + return &m_pre_data->owned_client_addr.sa; +} + +sockaddr const * +TransactionLogData::get_client_src_addr() const +{ + if (likely(m_http_sm != nullptr)) { + return &m_http_sm->t_state.client_info.src_addr.sa; + } + return &m_pre_data->owned_client_src_addr.sa; +} + +sockaddr const * +TransactionLogData::get_client_dst_addr() const +{ + if (likely(m_http_sm != nullptr)) { + return &m_http_sm->t_state.client_info.dst_addr.sa; + } + return &m_pre_data->owned_client_dst_addr.sa; +} + +sockaddr const * +TransactionLogData::get_verified_client_addr() const +{ + if (likely(m_http_sm != nullptr)) { + if (auto txn = m_http_sm->get_ua_txn(); txn) { + sockaddr const *vaddr = txn->get_verified_client_addr(); + if (vaddr && ats_is_ip(vaddr)) { + return vaddr; + } + } + } + return nullptr; +} + +uint16_t +TransactionLogData::get_client_port() const +{ + if (likely(m_http_sm != nullptr)) { + if (auto txn = m_http_sm->get_ua_txn(); txn) { + return txn->get_client_port(); + } + return 0; + } + return m_pre_data->m_client_port; +} + +// ===== Server addressing ===== + +sockaddr const * +TransactionLogData::get_server_src_addr() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.current.server) { + return &m_http_sm->t_state.current.server->src_addr.sa; + } + } + return nullptr; +} + +sockaddr const * +TransactionLogData::get_server_dst_addr() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.current.server) { + return &m_http_sm->t_state.current.server->dst_addr.sa; + } + } + return nullptr; +} + +sockaddr const * +TransactionLogData::get_server_info_dst_addr() const +{ + if (likely(m_http_sm != nullptr)) { + return &m_http_sm->t_state.server_info.dst_addr.sa; + } + return nullptr; +} + +const char * +TransactionLogData::get_server_name() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.current.server) { + return m_http_sm->t_state.current.server->name; + } + } + return nullptr; +} + +// ===== Squid codes ===== + +SquidLogCode +TransactionLogData::get_log_code() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.squid_codes.log_code; + } + return m_pre_data->m_log_code; +} + +SquidSubcode +TransactionLogData::get_subcode() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.squid_codes.subcode; + } + return SquidSubcode::EMPTY; +} + +SquidHitMissCode +TransactionLogData::get_hit_miss_code() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.squid_codes.hit_miss_code; + } + return m_pre_data->m_hit_miss_code; +} + +SquidHierarchyCode +TransactionLogData::get_hier_code() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.squid_codes.hier_code; + } + return m_pre_data->m_hier_code; +} + +// ===== Byte counters ===== + +int64_t +TransactionLogData::get_client_request_body_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_request_body_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_client_response_hdr_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_response_hdr_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_client_response_body_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_response_body_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_server_request_body_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_request_body_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_server_response_body_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_response_body_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_cache_response_body_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->cache_response_body_bytes; + } + return 0; +} + +int64_t +TransactionLogData::get_cache_response_hdr_bytes() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->cache_response_hdr_bytes; + } + return 0; +} + +// ===== Transaction identifiers ===== + +int64_t +TransactionLogData::get_sm_id() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->sm_id; + } + return 0; +} + +int64_t +TransactionLogData::get_connection_id() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_connection_id(); + } + return m_pre_data->m_connection_id; +} + +int +TransactionLogData::get_transaction_id() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_transaction_id(); + } + return m_pre_data->m_transaction_id; +} + +int +TransactionLogData::get_transaction_priority_weight() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_transaction_priority_weight(); + } + return 0; +} + +int +TransactionLogData::get_transaction_priority_dependence() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->client_transaction_priority_dependence(); + } + return 0; +} + +// ===== Plugin info ===== + +int64_t +TransactionLogData::get_plugin_id() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->plugin_id; + } + return 0; +} + +const char * +TransactionLogData::get_plugin_tag() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->plugin_tag; + } + return nullptr; +} + +// ===== Protocol info ===== + +const char * +TransactionLogData::get_client_protocol() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_protocol(); + } + return m_pre_data->owned_client_protocol_str.empty() ? nullptr : m_pre_data->owned_client_protocol_str.c_str(); +} + +const char * +TransactionLogData::get_server_protocol() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_protocol; + } + return nullptr; +} + +const char * +TransactionLogData::get_client_sec_protocol() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_sec_protocol(); + } + return nullptr; +} + +const char * +TransactionLogData::get_client_cipher_suite() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_cipher_suite(); + } + return nullptr; +} + +const char * +TransactionLogData::get_client_curve() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_curve(); + } + return nullptr; +} + +const char * +TransactionLogData::get_client_security_group() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_security_group(); + } + return nullptr; +} + +int +TransactionLogData::get_client_alpn_id() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_alpn_id(); + } + return -1; +} + +// ===== SNI ===== + +const char * +TransactionLogData::get_sni_server_name() const +{ + if (likely(m_http_sm != nullptr)) { + if (auto txn = m_http_sm->get_ua_txn(); txn) { + if (auto ssn = txn->get_proxy_ssn(); ssn) { + if (auto ssl = ssn->ssl(); ssl) { + return ssl->client_sni_server_name(); + } + } + } + } + return nullptr; +} + +// ===== Connection flags ===== + +bool +TransactionLogData::get_client_tcp_reused() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_tcp_reused(); + } + return false; +} + +bool +TransactionLogData::get_client_connection_is_ssl() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_connection_is_ssl(); + } + return m_pre_data->m_client_connection_is_ssl; +} + +bool +TransactionLogData::get_client_ssl_reused() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_ssl_reused(); + } + return false; +} + +int +TransactionLogData::get_client_ssl_resumption_type() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_user_agent().get_client_ssl_resumption_type(); + } + return 0; +} + +bool +TransactionLogData::get_is_internal() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->is_internal; + } + return false; +} + +bool +TransactionLogData::get_server_connection_is_ssl() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_connection_is_ssl; + } + return false; +} + +bool +TransactionLogData::get_server_ssl_reused() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_ssl_reused; + } + return false; +} + +int +TransactionLogData::get_server_connection_provided_cert() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_connection_provided_cert; + } + return 0; +} + +int +TransactionLogData::get_client_provided_cert() const +{ + if (likely(m_http_sm != nullptr)) { + if (auto txn = m_http_sm->get_ua_txn(); txn) { + if (auto ssn = txn->get_proxy_ssn(); ssn) { + if (auto ssl = ssn->ssl(); ssl) { + return ssl->client_provided_certificate(); + } + } + } + } + return 0; +} + +// ===== Server transaction count ===== + +int64_t +TransactionLogData::get_server_transact_count() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->server_transact_count; + } + return m_pre_data->m_server_transact_count; +} + +// ===== Finish status ===== + +int +TransactionLogData::get_client_finish_status_code() const +{ + if (likely(m_http_sm != nullptr)) { + return compute_client_finish_status(m_http_sm); + } + return 0; +} + +int +TransactionLogData::get_proxy_finish_status_code() const +{ + if (likely(m_http_sm != nullptr)) { + return compute_proxy_finish_status(m_http_sm); + } + return 0; +} + +// ===== Error codes ===== + +void +TransactionLogData::format_error_codes() const +{ + if (m_error_codes_formatted) { + return; + } + m_error_codes_formatted = true; + ink_assert(m_http_sm != nullptr); + m_http_sm->t_state.client_info.rx_error_code.str(m_client_rx_error_code, sizeof(m_client_rx_error_code)); + m_http_sm->t_state.client_info.tx_error_code.str(m_client_tx_error_code, sizeof(m_client_tx_error_code)); +} + +const char * +TransactionLogData::get_client_rx_error_code() const +{ + if (likely(m_http_sm != nullptr)) { + format_error_codes(); + return m_client_rx_error_code; + } + return "-"; +} + +const char * +TransactionLogData::get_client_tx_error_code() const +{ + if (likely(m_http_sm != nullptr)) { + format_error_codes(); + return m_client_tx_error_code; + } + return "-"; +} + +// ===== MPTCP ===== + +std::optional +TransactionLogData::get_mptcp_state() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->mptcp_state; + } + return std::nullopt; +} + +// ===== Misc transaction state ===== + +in_port_t +TransactionLogData::get_incoming_port() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.request_data.incoming_port; + } + return 0; +} + +int +TransactionLogData::get_orig_scheme() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.orig_scheme; + } + return -1; +} + +int64_t +TransactionLogData::get_congestion_control_crat() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.congestion_control_crat; + } + return 0; +} + +// ===== Cache state ===== + +int +TransactionLogData::get_cache_write_code() const +{ + if (likely(m_http_sm != nullptr)) { + return convert_cache_write_code(m_http_sm->t_state.cache_info.write_status); + } + return 0; +} + +int +TransactionLogData::get_cache_transform_write_code() const +{ + if (likely(m_http_sm != nullptr)) { + return convert_cache_write_code(m_http_sm->t_state.cache_info.transform_write_status); + } + return 0; +} + +int +TransactionLogData::get_cache_open_read_tries() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_cache_sm().get_open_read_tries(); + } + return 0; +} + +int +TransactionLogData::get_cache_open_write_tries() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->get_cache_sm().get_open_write_tries(); + } + return 0; +} + +int +TransactionLogData::get_max_cache_open_write_retries() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.txn_conf->max_cache_open_write_retries; + } + return -1; +} + +// ===== Retry attempts ===== + +int64_t +TransactionLogData::get_simple_retry_attempts() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.current.simple_retry_attempts; + } + return 0; +} + +int64_t +TransactionLogData::get_unavailable_retry_attempts() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.current.unavailable_server_retry_attempts; + } + return 0; +} + +int64_t +TransactionLogData::get_retry_attempts_saved() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.current.retry_attempts.saved(); + } + return 0; +} + +// ===== Status plugin entry name ===== + +std::string_view +TransactionLogData::get_http_return_code_setter_name() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.http_return_code_setter_name; + } + return {}; +} + +// ===== Proxy Protocol ===== + +int +TransactionLogData::get_pp_version() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + return static_cast(m_http_sm->t_state.pp_info.version); + } + } + return 0; +} + +sockaddr const * +TransactionLogData::get_pp_src_addr() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + return &m_http_sm->t_state.pp_info.src_addr.sa; + } + } + return nullptr; +} + +sockaddr const * +TransactionLogData::get_pp_dst_addr() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + return &m_http_sm->t_state.pp_info.dst_addr.sa; + } + } + return nullptr; +} + +std::string_view +TransactionLogData::get_pp_authority() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + if (auto authority_opt = m_http_sm->t_state.pp_info.get_tlv(PP2_TYPE_AUTHORITY); authority_opt) { + return *authority_opt; + } + } + } + return {}; +} + +std::string_view +TransactionLogData::get_pp_tls_cipher() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + if (auto cipher = m_http_sm->t_state.pp_info.get_tlv_ssl_cipher(); cipher) { + return *cipher; + } + } + } + return {}; +} + +std::string_view +TransactionLogData::get_pp_tls_version() const +{ + if (likely(m_http_sm != nullptr)) { + if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) { + if (auto version = m_http_sm->t_state.pp_info.get_tlv_ssl_version(); version) { + return *version; + } + } + } + return {}; +} + +std::string_view +TransactionLogData::get_pp_tls_group() const +{ + return {}; +} + +// ===== Server response Transfer-Encoding ===== + +std::string_view +TransactionLogData::get_server_response_transfer_encoding() const +{ + if (likely(m_http_sm != nullptr)) { + return m_http_sm->t_state.hdr_info.server_response_transfer_encoding; + } + return {}; +} + +// ===== Fallback fields for pre-transaction logging ===== + +std::string_view +TransactionLogData::get_method() const +{ + if (likely(m_http_sm != nullptr)) { + return {}; + } + return m_pre_data->owned_method; +} + +std::string_view +TransactionLogData::get_scheme() const +{ + if (likely(m_http_sm != nullptr)) { + return {}; + } + return m_pre_data->owned_scheme; +} + +std::string_view +TransactionLogData::get_client_protocol_str() const +{ + if (likely(m_http_sm != nullptr)) { + return {}; + } + return m_pre_data->owned_client_protocol_str; +} diff --git a/src/proxy/logging/unit-tests/test_LogAccess.cc b/src/proxy/logging/unit-tests/test_LogAccess.cc index e567a2889c0..aee2bd67287 100644 --- a/src/proxy/logging/unit-tests/test_LogAccess.cc +++ b/src/proxy/logging/unit-tests/test_LogAccess.cc @@ -25,6 +25,7 @@ #include "proxy/PreTransactionLogData.h" #include "proxy/logging/LogAccess.h" +#include "proxy/logging/TransactionLogData.h" #include "tscore/ink_inet.h" #include @@ -167,7 +168,8 @@ TEST_CASE("LogAccess pre-transaction CONNECT fields", "[LogAccess]") { PreTransactionLogData data; populate_pre_transaction_data(data, "CONNECT", ""sv, "example.com:443", ""sv); - LogAccess access(data); + TransactionLogData log_data(data); + LogAccess access(log_data); access.init(); @@ -187,7 +189,8 @@ TEST_CASE("LogAccess malformed CONNECT without authority falls back to path", "[ { PreTransactionLogData data; populate_pre_transaction_data(data, "CONNECT", "https"sv, ""sv, "/"sv); - LogAccess access(data); + TransactionLogData log_data(data); + LogAccess access(log_data); access.init(); @@ -202,7 +205,8 @@ TEST_CASE("LogAccess pre-transaction client host port is null-safe", "[LogAccess { PreTransactionLogData data; populate_pre_transaction_data(data, "GET", "https"sv, "example.com", "/client-port"sv); - LogAccess access(data); + TransactionLogData log_data(data); + LogAccess access(log_data); access.init();