Line data Source code
1 : #include "source/common/formatter/substitution_format_utility.h" 2 : 3 : #include "envoy/api/os_sys_calls.h" 4 : 5 : #include "source/common/api/os_sys_calls_impl.h" 6 : #include "source/common/http/utility.h" 7 : #include "source/common/protobuf/utility.h" 8 : #include "source/common/stream_info/utility.h" 9 : 10 : namespace Envoy { 11 : namespace Formatter { 12 : 13 : static const std::string DefaultUnspecifiedValueString = "-"; 14 : 15 : void CommandSyntaxChecker::verifySyntax(CommandSyntaxFlags flags, const std::string& command, 16 : const std::string& subcommand, 17 3991 : const absl::optional<size_t>& length) { 18 3991 : if ((flags == COMMAND_ONLY) && ((subcommand.length() != 0) || length.has_value())) { 19 0 : throwEnvoyExceptionOrPanic(fmt::format("{} does not take any parameters or length", command)); 20 0 : } 21 : 22 3991 : if ((flags & PARAMS_REQUIRED).any() && (subcommand.length() == 0)) { 23 4 : throwEnvoyExceptionOrPanic(fmt::format("{} requires parameters", command)); 24 4 : } 25 : 26 3987 : if ((flags & LENGTH_ALLOWED).none() && length.has_value()) { 27 0 : throwEnvoyExceptionOrPanic(fmt::format("{} does not allow length to be specified.", command)); 28 0 : } 29 3987 : } 30 : 31 : const absl::optional<std::reference_wrapper<const std::string>> 32 613 : SubstitutionFormatUtils::protocolToString(const absl::optional<Http::Protocol>& protocol) { 33 613 : if (protocol) { 34 612 : return Http::Utility::getProtocolString(protocol.value()); 35 612 : } 36 1 : return absl::nullopt; 37 613 : } 38 : 39 : const std::string& 40 0 : SubstitutionFormatUtils::protocolToStringOrDefault(const absl::optional<Http::Protocol>& protocol) { 41 0 : if (protocol) { 42 0 : return Http::Utility::getProtocolString(protocol.value()); 43 0 : } 44 0 : return DefaultUnspecifiedValueString; 45 0 : } 46 : 47 0 : const absl::optional<std::string> SubstitutionFormatUtils::getHostname() { 48 0 : #ifdef HOST_NAME_MAX 49 0 : const size_t len = HOST_NAME_MAX; 50 : #else 51 : // This is notably the case in OSX. 52 : const size_t len = 255; 53 : #endif 54 0 : char name[len]; 55 0 : Api::OsSysCalls& os_sys_calls = Api::OsSysCallsSingleton::get(); 56 0 : const Api::SysCallIntResult result = os_sys_calls.gethostname(name, len); 57 : 58 0 : absl::optional<std::string> hostname; 59 0 : if (result.return_value_ == 0) { 60 0 : hostname = name; 61 0 : } 62 : 63 0 : return hostname; 64 0 : } 65 : 66 0 : const std::string SubstitutionFormatUtils::getHostnameOrDefault() { 67 0 : absl::optional<std::string> hostname = getHostname(); 68 0 : if (hostname.has_value()) { 69 0 : return hostname.value(); 70 0 : } 71 0 : return DefaultUnspecifiedValueString; 72 0 : } 73 : 74 36 : const ProtobufWkt::Value& SubstitutionFormatUtils::unspecifiedValue() { 75 36 : return ValueUtil::nullValue(); 76 36 : } 77 : 78 2217 : void SubstitutionFormatUtils::truncate(std::string& str, absl::optional<size_t> max_length) { 79 2217 : if (!max_length) { 80 2217 : return; 81 2217 : } 82 : 83 0 : if (str.length() > max_length.value()) { 84 0 : str.resize(max_length.value()); 85 0 : } 86 0 : } 87 : 88 : void SubstitutionFormatUtils::parseSubcommandHeaders(const std::string& subcommand, 89 : std::string& main_header, 90 1639 : std::string& alternative_header) { 91 : // subs is used only to check if there are more than 2 headers separated by '?'. 92 1639 : std::vector<std::string> subs; 93 1639 : alternative_header = ""; 94 1639 : parseSubcommand(subcommand, '?', main_header, alternative_header, subs); 95 1639 : if (!subs.empty()) { 96 0 : throwEnvoyExceptionOrPanic( 97 : // Header format rules support only one alternative header. 98 : // docs/root/configuration/observability/access_log/access_log.rst#format-rules 99 0 : absl::StrCat("More than 1 alternative header specified in token: ", subcommand)); 100 0 : } 101 : 102 : // The main and alternative header should not contain invalid characters {NUL, LR, CF}. 103 1639 : if (!Envoy::Http::validHeaderString(main_header) || 104 1639 : !Envoy::Http::validHeaderString(alternative_header)) { 105 4 : throwEnvoyExceptionOrPanic( 106 4 : "Invalid header configuration. Format string contains null or newline."); 107 4 : } 108 1639 : } 109 : 110 : } // namespace Formatter 111 : } // namespace Envoy