Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 51 additions & 13 deletions include/proxy/http/HttpConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "swoc/swoc_ip.h"
#include "swoc/BufferWriter.h"

#include "tscore/MgmtDefs.h"
#include "tscore/ink_platform.h"
#include "tscore/ink_inet.h"
#include "tscore/ink_resolver.h"
Expand All @@ -61,6 +62,27 @@ using ts::Metrics;
static const unsigned HTTP_STATUS_NUMBER = 600;
using HttpStatusBitset = std::bitset<HTTP_STATUS_NUMBER>;

class HttpStatusCodeList
{
public:
static const MgmtConverter Conv;

HttpStatusCodeList(const char *value, size_t length);
~HttpStatusCodeList();

bool
contains(int code) const
{
return _data.test(code);
}

private:
char *_conf_value = nullptr;

// TODO: change container to std::unordered_set or something
HttpStatusBitset _data;
};

struct HttpStatsBlock {
// Need two stats for these for counts and times
Metrics::Counter::AtomicType *background_fill_bytes_aborted;
Expand Down Expand Up @@ -393,6 +415,20 @@ OptionBitSet optStrToBitset(std::string_view optConfigStr, swoc::FixedBufferWrit

} // namespace HttpForwarded

// TODO: make a template
class HttpForwardedConf
{
public:
HttpForwardedConf(std::string_view value, swoc::FixedBufferWriter &error);
~HttpForwardedConf();

const HttpForwarded::OptionBitSet &data();

private:
char *_conf_value = nullptr;
HttpForwarded::OptionBitSet _data;
};

namespace RedirectEnabled
{
enum class AddressClass {
Expand Down Expand Up @@ -437,8 +473,6 @@ static std::map<std::string, Action> action_map = {
// and State (txn) structure. It allows for certain configs
// to be overridable per transaction more easily.
struct OverridableHttpConfigParams {
OverridableHttpConfigParams() : insert_forwarded(HttpForwarded::OptionBitSet()) {}

// A simple rules here:
// * Place all MgmtByte configs before all other configs
MgmtByte maintain_pristine_host_hdr = 1;
Expand Down Expand Up @@ -492,8 +526,8 @@ struct OverridableHttpConfigParams {
///////////////
// Forwarded //
///////////////
HttpForwarded::OptionBitSet insert_forwarded;
MgmtInt proxy_protocol_out = -1;
HttpForwardedConf *insert_forwarded = nullptr;
MgmtInt proxy_protocol_out = -1;

//////////////////////
// Version Hell //
Expand Down Expand Up @@ -645,7 +679,7 @@ struct OverridableHttpConfigParams {
MgmtByte enable_parent_timeout_markdowns = 0;
MgmtByte disable_parent_markdowns = 0;

ts_seconds down_server_timeout{300};
TSMgmtSeconds down_server_timeout{300};

// open read failure retries.
MgmtInt max_cache_open_read_retries = -1;
Expand Down Expand Up @@ -697,7 +731,13 @@ struct OverridableHttpConfigParams {
char *ssl_client_alpn_protocols = nullptr;

// Host Resolution order
HostResData host_res_data;
HostResData *host_res_data;

// bitset to hold the status codes that will BE cached with negative caching enabled
HttpStatusCodeList *negative_caching_list;

// bitset to hold the status codes that will used by nagative revalidating enabled
HttpStatusCodeList *negative_revalidating_list;
};

/////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -795,12 +835,6 @@ struct HttpConfigParams : public ConfigInfo {

ConnectionTracker::GlobalConfig global_connection_tracker_config;

// bitset to hold the status codes that will BE cached with negative caching enabled
HttpStatusBitset negative_caching_list;

// bitset to hold the status codes that will used by nagative revalidating enabled
HttpStatusBitset negative_revalidating_list;

// All the overridable configurations goes into this class member, but they
// are not copied over until needed ("lazy").
OverridableHttpConfigParams oride;
Expand Down Expand Up @@ -878,8 +912,12 @@ inline HttpConfigParams::~HttpConfigParams()
ats_free(redirect_actions_string);
ats_free(oride.ssl_client_sni_policy);
ats_free(oride.ssl_client_alpn_protocols);
ats_free(oride.host_res_data.conf_value);

delete connect_ports;
delete redirect_actions_map;

delete oride.host_res_data;
delete oride.insert_forwarded;
delete oride.negative_caching_list;
delete oride.negative_revalidating_list;
}
22 changes: 22 additions & 0 deletions include/ts/apidefs.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@

#include <cstdint>
#include <netinet/in.h>
#include <string_view>
#include <sys/types.h>
#include <sys/socket.h>
#include <variant>

/** Apply printf format string compile-time argument checking to a function.
*
Expand Down Expand Up @@ -732,6 +734,7 @@ enum TSRecordDataType {
TS_RECORDDATATYPE_COUNTER,
TS_RECORDDATATYPE_STAT_CONST,
TS_RECORDDATATYPE_STAT_FX,
TS_RECORDDATATYPE_VARIANT,
TS_RECORDDATATYPE_MAX,
};

Expand Down Expand Up @@ -777,6 +780,7 @@ enum TSOverridableConfigKey {
TS_CONFIG_HTTP_CHUNKING_ENABLED,
TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED,
TS_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME,
TS_CONFIG_HTTP_NEGATIVE_CACHING_LIST,
TS_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE,
TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN,
TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT,
Expand Down Expand Up @@ -840,6 +844,7 @@ enum TSOverridableConfigKey {
TS_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE,
TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED,
TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME,
TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIST,
TS_CONFIG_SSL_HSTS_MAX_AGE,
TS_CONFIG_SSL_HSTS_INCLUDE_SUBDOMAINS,
TS_CONFIG_HTTP_CACHE_OPEN_READ_RETRY_TIME,
Expand Down Expand Up @@ -985,6 +990,23 @@ using TSMgmtInt = int64_t;
using TSMgmtCounter = int64_t;
using TSMgmtFloat = float;
using TSMgmtString = char *;
using TSMgmtSeconds = std::chrono::seconds;

class HttpStatusCodeList;
struct HostResData;
class HttpForwardedConf;

// clang-format off
using TSConfigValue = std::variant<
TSMgmtInt,
TSMgmtFloat,
TSMgmtSeconds,
std::string_view,
HttpStatusCodeList *,
HostResData *,
HttpForwardedConf *,
TSOutboundConnectionMatchType>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, this variant captures all types in the OverridableHttpConfigParams. However, as @zwoop pointed out, every time we add a new type here, ABI compatibility is broken 🤔

// clang-format on

/// The source of a management value.
enum TSMgmtSource {
Expand Down
3 changes: 3 additions & 0 deletions include/ts/ts.h
Original file line number Diff line number Diff line change
Expand Up @@ -2583,6 +2583,9 @@ TSReturnCode TSHttpTxnConfigStringGet(TSHttpTxn txnp, TSOverridableConfigKey con

TSReturnCode TSHttpTxnConfigFind(const char *name, int length, TSOverridableConfigKey *conf, TSRecordDataType *type);

TSReturnCode TSHttpTxnConfigParse(TSConfigValue &dst, TSOverridableConfigKey key, const char *value, size_t length);
TSReturnCode TSHttpTxnConfigSet(TSHttpTxn txnp, TSOverridableConfigKey key, const TSConfigValue &src);

/**
This is a generalization of the old TSHttpTxnFollowRedirect(), but gives finer
control over the behavior. Instead of using the Location: header for the new
Expand Down
2 changes: 2 additions & 0 deletions include/tscore/ink_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ extern void ats_force_order_by_family(sa_family_t family, HostResPreferenceOrder

// Domain resolution priority for origin.
struct HostResData {
~HostResData() { ats_free(conf_value); }

HostResPreferenceOrder order;
// keep the configuration value to satisfy the API(TSHttpTxnConfigStringSet)
char *conf_value{nullptr};
Expand Down
25 changes: 25 additions & 0 deletions plugins/conf_remap/conf_remap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
limitations under the License.
*/

#include "ts/apidefs.h"
#include "ts/ts.h"
#include "ts/remap.h"
#include "tscore/ink_defs.h"
Expand Down Expand Up @@ -46,6 +47,7 @@ struct RemapConfigs {
TSRecordDataType _type;
TSRecordData _data;
int _data_len; // Used when data is a string
TSConfigValue _value;
};

RemapConfigs() { memset(_items, 0, sizeof(_items)); };
Expand Down Expand Up @@ -106,6 +108,15 @@ RemapConfigs::parse_inline(const char *arg)
case TS_RECORDDATATYPE_INT:
_items[_current]._data.rec_int = strtoll(value.c_str(), nullptr, 10);
break;
case TS_RECORDDATATYPE_VARIANT: {
TSReturnCode res = TSHttpTxnConfigParse(_items[_current]._value, name, value.c_str(), value.length());
if (res == TS_ERROR) {
TSError("[%s] key %s: failed to parse value", PLUGIN_NAME, key.c_str());
return false;
}
// also store the value in string
[[fallthrough]];
}
case TS_RECORDDATATYPE_STRING:
if (strcmp(value.c_str(), "NULL") == 0) {
_items[_current]._data.rec_string = nullptr;
Expand Down Expand Up @@ -185,6 +196,16 @@ scalar_node_handler(const TSYAMLRecCfgFieldData *cfg, void *data)
case TS_RECORDDATATYPE_INT:
item->_data.rec_int = value.as<int64_t>();
break;
case TS_RECORDDATATYPE_VARIANT: {
std::string str = value.as<std::string>();
TSReturnCode res = TSHttpTxnConfigParse(item->_value, name, TSstrdup(str.c_str()), str.size());
if (res == TS_ERROR) {
TSError("[%s] field %s: failed to parse value", PLUGIN_NAME, cfg->field_name);
return TS_ERROR;
}
// also store the value in string
[[fallthrough]];
}
case TS_RECORDDATATYPE_STRING: {
std::string str = value.as<std::string>();
if (value.IsNull() || str == "NULL") {
Expand Down Expand Up @@ -350,6 +371,10 @@ TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo * /* rri ATS_UNUSED */
TSHttpTxnConfigFloatSet(txnp, conf->_items[ix]._name, conf->_items[ix]._data.rec_int);
Dbg(dbg_ctl, "Setting config id %d to %f", conf->_items[ix]._name, conf->_items[ix]._data.rec_float);
break;
case TS_RECORDDATATYPE_VARIANT:
TSHttpTxnConfigSet(txnp, conf->_items[ix]._name, conf->_items[ix]._value);
Dbg(dbg_ctl, "Setting config id %d to %s", conf->_items[ix]._name, conf->_items[ix]._data.rec_string);
break;
default:
break; // Error ?
}
Expand Down
Loading