Repository: trafficserver Updated Branches: refs/heads/master 387bb9a5b -> 92bdda991
TS-2636: Enhance ATS custom logging to support WIPE_FIELD_VALUE filter action Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/92bdda99 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/92bdda99 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/92bdda99 Branch: refs/heads/master Commit: 92bdda99113cea13a6a70e08f5dd611dcae2ac8b Parents: 387bb9a Author: Sudheer Vinukonda <[email protected]> Authored: Thu May 8 09:52:18 2014 -0700 Committer: Bryan Call <[email protected]> Committed: Thu May 8 09:52:18 2014 -0700 ---------------------------------------------------------------------- proxy/logging/Log.cc | 18 +++-- proxy/logging/LogAccess.h | 7 ++ proxy/logging/LogAccessHttp.cc | 63 +++++++++++++++++ proxy/logging/LogAccessHttp.h | 7 ++ proxy/logging/LogField.cc | 23 ++++-- proxy/logging/LogField.h | 15 ++-- proxy/logging/LogFilter.cc | 135 +++++++++++++++++++++++++++++++++++- proxy/logging/LogFilter.h | 131 ++++++++++++++++++++++++++++++++++ proxy/logging/LogObject.cc | 4 ++ 9 files changed, 383 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/Log.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc index 8107cb1..11f8311 100644 --- a/proxy/logging/Log.cc +++ b/proxy/logging/Log.cc @@ -444,35 +444,40 @@ Log::init_fields() field = NEW(new LogField("client_req_url", "cqu", LogField::STRING, &LogAccess::marshal_client_req_url, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_url)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cqu", field); field = NEW(new LogField("client_req_url_canonical", "cquc", LogField::STRING, &LogAccess::marshal_client_req_url_canon, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_url_canon)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cquc", field); field = NEW(new LogField("client_req_unmapped_url_canonical", "cquuc", LogField::STRING, &LogAccess::marshal_client_req_unmapped_url_canon, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_unmapped_url_canon)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cquuc", field); field = NEW(new LogField("client_req_unmapped_url_path", "cquup", LogField::STRING, &LogAccess::marshal_client_req_unmapped_url_path, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_unmapped_url_path)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cquup", field); field = NEW(new LogField("client_req_unmapped_url_host", "cquuh", LogField::STRING, &LogAccess::marshal_client_req_unmapped_url_host, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_unmapped_url_host)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cquuh", field); @@ -486,7 +491,8 @@ Log::init_fields() field = NEW(new LogField("client_req_url_path", "cqup", LogField::STRING, &LogAccess::marshal_client_req_url_path, - (LogField::UnmarshalFunc)&LogAccess::unmarshal_str)); + (LogField::UnmarshalFunc)&LogAccess::unmarshal_str, + &LogAccess::set_client_req_url_path)); global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "cqup", field); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogAccess.h ---------------------------------------------------------------------- diff --git a/proxy/logging/LogAccess.h b/proxy/logging/LogAccess.h index 35291aa..940145d 100644 --- a/proxy/logging/LogAccess.h +++ b/proxy/logging/LogAccess.h @@ -228,6 +228,13 @@ public: inkcoreapi virtual int marshal_cache_resp_http_version(char *); // INT + inkcoreapi virtual void set_client_req_url(char *, int) {}; // STR + inkcoreapi virtual void set_client_req_url_canon(char *, int) {}; // STR + inkcoreapi virtual void set_client_req_unmapped_url_canon(char *, int) {}; // STR + inkcoreapi virtual void set_client_req_unmapped_url_path(char *, int) {}; // STR + inkcoreapi virtual void set_client_req_unmapped_url_host(char *, int) {}; // STR + inkcoreapi virtual void set_client_req_url_path(char *, int) {}; // STR + // // congestion control -- client_retry_after_time // http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogAccessHttp.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogAccessHttp.cc b/proxy/logging/LogAccessHttp.cc index 5ad308b..d8250ab 100644 --- a/proxy/logging/LogAccessHttp.cc +++ b/proxy/logging/LogAccessHttp.cc @@ -128,6 +128,69 @@ LogAccessHttp::init() } /*------------------------------------------------------------------------- + The set routines ... + + These routines are used by the WIPE_FIELD_VALUE filter to replace the original req url + strings with the WIPED req strings. + -------------------------------------------------------------------------*/ + +void +LogAccessHttp::set_client_req_url(char *buf, int len) +{ + if (buf) { + m_client_req_url_len = len; + ink_strlcpy(m_client_req_url_str, buf, m_client_req_url_len + 1); + } +} + +void +LogAccessHttp::set_client_req_url_canon(char *buf, int len) +{ + if (buf) { + m_client_req_url_canon_len = len; + ink_strlcpy(m_client_req_url_canon_str, buf, m_client_req_url_canon_len + 1); + } +} + +void +LogAccessHttp::set_client_req_unmapped_url_canon(char *buf, int len) +{ + if (buf) { + m_client_req_unmapped_url_canon_len = len; + ink_strlcpy(m_client_req_unmapped_url_canon_str, buf, m_client_req_unmapped_url_canon_len + 1); + } +} + +void +LogAccessHttp::set_client_req_unmapped_url_path(char *buf, int len) +{ + if (buf) { + m_client_req_unmapped_url_path_len = len; + ink_strlcpy(m_client_req_unmapped_url_path_str, buf, m_client_req_unmapped_url_path_len + 1); + } +} + +void +LogAccessHttp::set_client_req_unmapped_url_host(char *buf, int len) +{ + if (buf) { + m_client_req_unmapped_url_host_len = len; + ink_strlcpy(m_client_req_unmapped_url_host_str, buf, m_client_req_unmapped_url_host_len + 1); + } +} + +void +LogAccessHttp::set_client_req_url_path(char *buf, int len) +{ + //?? use m_client_req_unmapped_url_path_str for now..may need to enhance later.. + if (buf) { + m_client_req_url_path_len = len; + ink_strlcpy(m_client_req_unmapped_url_path_str, buf, m_client_req_url_path_len + 1); + } +} + + +/*------------------------------------------------------------------------- The marshalling routines ... We know that m_http_sm is a valid pointer (we assert so in the ctor), but http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogAccessHttp.h ---------------------------------------------------------------------- diff --git a/proxy/logging/LogAccessHttp.h b/proxy/logging/LogAccessHttp.h index 9235441..e487326 100644 --- a/proxy/logging/LogAccessHttp.h +++ b/proxy/logging/LogAccessHttp.h @@ -135,6 +135,13 @@ public: virtual int marshal_http_header_field(LogField::Container container, char *field, char *buf); virtual int marshal_http_header_field_escapify(LogField::Container container, char *field, char *buf); + virtual void set_client_req_url(char *, int); // STR + virtual void set_client_req_url_canon(char *, int); // STR + virtual void set_client_req_unmapped_url_canon(char *, int); // STR + virtual void set_client_req_unmapped_url_path(char *, int); // STR + virtual void set_client_req_unmapped_url_host(char *, int); // STR + virtual void set_client_req_url_path(char *, int); // STR + private: HttpSM * m_http_sm; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogField.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogField.cc b/proxy/logging/LogField.cc index 6bab383..add7b17 100644 --- a/proxy/logging/LogField.cc +++ b/proxy/logging/LogField.cc @@ -142,10 +142,10 @@ LogSlice::toStrOffset(int strlen, int *offset) -------------------------------------------------------------------------*/ // Generic field ctor -LogField::LogField(const char *name, const char *symbol, Type type, MarshalFunc marshal, UnmarshalFunc unmarshal) +LogField::LogField(const char *name, const char *symbol, Type type, MarshalFunc marshal, UnmarshalFunc unmarshal, SetFunc _setfunc) : m_name(ats_strdup(name)), m_symbol(ats_strdup(symbol)), m_type(type), m_container(NO_CONTAINER), m_marshal_func(marshal), m_unmarshal_func(unmarshal), m_unmarshal_func_map(NULL), m_agg_op(NO_AGGREGATE), m_agg_cnt(0), m_agg_val(0), - m_time_field(false), m_alias_map(0) + m_time_field(false), m_alias_map(0), m_set_func(_setfunc) { ink_assert(m_name != NULL); ink_assert(m_symbol != NULL); @@ -159,10 +159,10 @@ LogField::LogField(const char *name, const char *symbol, Type type, MarshalFunc } LogField::LogField(const char *name, const char *symbol, Type type, - MarshalFunc marshal, UnmarshalFuncWithMap unmarshal, Ptr<LogFieldAliasMap> map) + MarshalFunc marshal, UnmarshalFuncWithMap unmarshal, Ptr<LogFieldAliasMap> map, SetFunc _setfunc) : m_name(ats_strdup(name)), m_symbol(ats_strdup(symbol)), m_type(type), m_container(NO_CONTAINER), m_marshal_func(marshal), m_unmarshal_func(NULL), m_unmarshal_func_map(unmarshal), m_agg_op(NO_AGGREGATE), m_agg_cnt(0), m_agg_val(0), - m_time_field(false), m_alias_map(map) + m_time_field(false), m_alias_map(map), m_set_func(_setfunc) { ink_assert(m_name != NULL); ink_assert(m_symbol != NULL); @@ -177,10 +177,10 @@ LogField::LogField(const char *name, const char *symbol, Type type, } // Container field ctor -LogField::LogField(const char *field, Container container) +LogField::LogField(const char *field, Container container, SetFunc _setfunc) : m_name(ats_strdup(field)), m_symbol(ats_strdup(container_names[container])), m_type(LogField::STRING), m_container(container), m_marshal_func(NULL), m_unmarshal_func(NULL), m_unmarshal_func_map(NULL), - m_agg_op(NO_AGGREGATE), m_agg_cnt(0), m_agg_val(0), m_time_field(false), m_alias_map(0) + m_agg_op(NO_AGGREGATE), m_agg_cnt(0), m_agg_val(0), m_time_field(false), m_alias_map(0), m_set_func(_setfunc) { ink_assert(m_name != NULL); ink_assert(m_symbol != NULL); @@ -223,7 +223,7 @@ LogField::LogField(const char *field, Container container) LogField::LogField(const LogField &rhs) : m_name(ats_strdup(rhs.m_name)), m_symbol(ats_strdup(rhs.m_symbol)), m_type(rhs.m_type), m_container(rhs.m_container), m_marshal_func(rhs.m_marshal_func), m_unmarshal_func(rhs.m_unmarshal_func), m_unmarshal_func_map(rhs.m_unmarshal_func_map), - m_agg_op(rhs.m_agg_op), m_agg_cnt(0), m_agg_val(0), m_time_field(rhs.m_time_field), m_alias_map(rhs.m_alias_map) + m_agg_op(rhs.m_agg_op), m_agg_cnt(0), m_agg_val(0), m_time_field(rhs.m_time_field), m_alias_map(rhs.m_alias_map), m_set_func(rhs.m_set_func) { ink_assert(m_name != NULL); ink_assert(m_symbol != NULL); @@ -282,6 +282,15 @@ LogField::marshal_len(LogAccess *lad) } } +void +LogField::updateField(LogAccess *lad, char *buf, int len) +{ + if (m_container == NO_CONTAINER) { + return (lad->*m_set_func) (buf, len); + } + // else...// future enhancement +} + /*------------------------------------------------------------------------- LogField::marshal http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogField.h ---------------------------------------------------------------------- diff --git a/proxy/logging/LogField.h b/proxy/logging/LogField.h index 1847daa..b1b0c64 100644 --- a/proxy/logging/LogField.h +++ b/proxy/logging/LogField.h @@ -78,6 +78,7 @@ public: typedef int (*UnmarshalFunc) (char **buf, char *dest, int len); typedef int (*UnmarshalFuncWithSlice) (char **buf, char *dest, int len, LogSlice *slice); typedef int (*UnmarshalFuncWithMap) (char **buf, char *dest, int len, Ptr<LogFieldAliasMap> map); + typedef void (LogAccess::*SetFunc) (char *buf, int len); enum Type @@ -119,14 +120,14 @@ public: N_AGGREGATES }; - LogField(const char *name, const char *symbol, Type type, MarshalFunc marshal, UnmarshalFunc unmarshal); + LogField(const char *name, const char *symbol, Type type, MarshalFunc marshal, UnmarshalFunc unmarshal, SetFunc _setFunc=NULL); - LogField(const char *name, const char *symbol, Type type, - MarshalFunc marshal, UnmarshalFuncWithMap unmarshal, Ptr<LogFieldAliasMap> map); + LogField(const char *name, const char *symbol, Type type, + MarshalFunc marshal, UnmarshalFuncWithMap unmarshal, Ptr<LogFieldAliasMap> map, SetFunc _setFunc=NULL); - LogField(const char *field, Container container); - LogField(const LogField & rhs); - ~LogField(); + LogField(const char *field, Container container, SetFunc _setFunc=NULL); + LogField(const LogField & rhs); + ~LogField(); unsigned marshal_len(LogAccess * lad); unsigned marshal(LogAccess * lad, char *buf); @@ -134,6 +135,7 @@ public: unsigned unmarshal(char **buf, char *dest, int len); void display(FILE * fd = stdout); bool operator==(LogField & rhs); + void updateField(LogAccess * lad, char* val, int len); char *name() { @@ -179,6 +181,7 @@ private: int64_t m_agg_val; bool m_time_field; Ptr<LogFieldAliasMap> m_alias_map; // map sINT <--> string + SetFunc m_set_func; public: LINK(LogField, link); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogFilter.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogFilter.cc b/proxy/logging/LogFilter.cc index aada40a..f0360a8 100644 --- a/proxy/logging/LogFilter.cc +++ b/proxy/logging/LogFilter.cc @@ -44,7 +44,7 @@ #include "SimpleTokenizer.h" const char *LogFilter::OPERATOR_NAME[] = { "MATCH", "CASE_INSENSITIVE_MATCH","CONTAIN", "CASE_INSENSITIVE_CONTAIN" }; -const char *LogFilter::ACTION_NAME[] = { "REJECT", "ACCEPT" }; +const char *LogFilter::ACTION_NAME[] = { "REJECT", "ACCEPT", "WIPE_FIELD_VALUE" }; /*------------------------------------------------------------------------- LogFilter::LogFilter @@ -182,6 +182,85 @@ LogFilterString::operator==(LogFilterString & rhs) } /*------------------------------------------------------------------------- + LogFilterString::wipe_this_entry + + For strings, we need to marshal the given string into a buffer so that we + can compare it with the filter value. Most strings are snall, so we'll + only allocate space dynamically if the marshal_len is very large (eg, + URL). + + The m_substr field tells us whether we can match based on substrings, or + whether we should compare the entire string. + -------------------------------------------------------------------------*/ + +bool +LogFilterString::wipe_this_entry(LogAccess * lad) +{ + if (m_num_values == 0 || m_field == NULL || lad == NULL || m_action != WIPE_FIELD_VALUE) { + return false; + } + + static const unsigned BUFSIZE = 1024; + char small_buf[BUFSIZE]; + char small_buf_upper[BUFSIZE]; + char *big_buf = NULL; + char *big_buf_upper = NULL; + char *buf = small_buf; + char *buf_upper = small_buf_upper; + size_t marsh_len = m_field->marshal_len(lad); // includes null termination + + if (marsh_len > BUFSIZE) { + big_buf = (char *)ats_malloc((unsigned int) marsh_len); + buf = big_buf; + } + + m_field->marshal(lad, buf); + + bool cond_satisfied = false; + switch (m_operator) { + case MATCH: + // marsh_len is an upper bound on the length of the marshalled string + // because marsh_len counts padding and the eos. So for a MATCH + // operator, we use the DATA_LENGTH_LARGER length condition rather + // than DATA_LENGTH_EQUAL, which we would use if we had the actual + // length of the string. It is probably not worth computing the + // actual length, so we just use the fact that a MATCH is not possible + // when marsh_len <= (length of the filter string) + // + cond_satisfied = _checkConditionAndWipe(&strcmp, &buf, marsh_len, m_value, DATA_LENGTH_LARGER); + break; + case CASE_INSENSITIVE_MATCH: + cond_satisfied = _checkConditionAndWipe(&strcasecmp, &buf, marsh_len, m_value, DATA_LENGTH_LARGER); + break; + case CONTAIN: + cond_satisfied = _checkConditionAndWipe(&_isSubstring, &buf, marsh_len, m_value, DATA_LENGTH_LARGER); + break; + case CASE_INSENSITIVE_CONTAIN: + { + if (big_buf) { + big_buf_upper = (char *)ats_malloc((unsigned int) marsh_len); + buf_upper = big_buf_upper; + } + for (size_t i = 0; i < marsh_len; i++) { + buf_upper[i] = ParseRules::ink_toupper(buf[i]); + } + cond_satisfied = _checkConditionAndWipe(&_isSubstring, &buf_upper, marsh_len, m_value_uppercase, DATA_LENGTH_LARGER); + strcpy(buf, buf_upper); + break; + } + default: + ink_assert(!"INVALID FILTER OPERATOR"); + } + + ats_free(big_buf); + ats_free(big_buf_upper); + + m_field->updateField(lad, buf, strlen(buf)); + return cond_satisfied; +} + + +/*------------------------------------------------------------------------- LogFilterString::toss_this_entry For strings, we need to marshal the given string into a buffer so that we @@ -438,6 +517,44 @@ bool LogFilterInt::operator==(LogFilterInt & rhs) } /*------------------------------------------------------------------------- + LogFilterInt::wipe_this_entry + -------------------------------------------------------------------------*/ + +bool +LogFilterInt::wipe_this_entry(LogAccess * lad) +{ + if (m_num_values == 0 || m_field == NULL || lad == NULL || m_action != WIPE_FIELD_VALUE) { + return false; + } + + bool cond_satisfied = false; + int64_t value; + + m_field->marshal(lad, (char *) &value); + // This used to do an ntohl() on value, but that breaks various filters. + // Long term we should move IPs to their own log type. + + // we don't use m_operator because we consider all operators to be + // equivalent to "MATCH" for an integer field + // + + // most common case is single value, speed it up a little bit by unrolling + // + if (m_num_values == 1) { + cond_satisfied = (value == *m_value); + } else { + for (size_t i = 0; i < m_num_values; ++i) { + if (value == m_value[i]) { + cond_satisfied = true; + break; + } + } + } + + return cond_satisfied; +} + +/*------------------------------------------------------------------------- LogFilterInt::toss_this_entry -------------------------------------------------------------------------*/ @@ -620,6 +737,22 @@ LogFilterList::add(LogFilter * filter, bool copy) /*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ +bool +LogFilterList::wipe_this_entry(LogAccess * lad) +{ + bool wipeFlag = false; + for (LogFilter * f = first(); f; f = next(f)) { + if (f->wipe_this_entry(lad)) { + wipeFlag = true; + } + } + return wipeFlag; +} + + +/*------------------------------------------------------------------------- + -------------------------------------------------------------------------*/ + bool LogFilterList::toss_this_entry(LogAccess * lad) { if (m_does_conjunction) { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogFilter.h ---------------------------------------------------------------------- diff --git a/proxy/logging/LogFilter.h b/proxy/logging/LogFilter.h index a99e1d1..d754e0e 100644 --- a/proxy/logging/LogFilter.h +++ b/proxy/logging/LogFilter.h @@ -52,6 +52,7 @@ public: { REJECT = 0, ACCEPT, + WIPE_FIELD_VALUE, N_ACTIONS }; static const char *ACTION_NAME[]; @@ -78,6 +79,7 @@ public: size_t get_num_values() const { return m_num_values; }; virtual bool toss_this_entry(LogAccess * lad) = 0; + virtual bool wipe_this_entry(LogAccess * lad) = 0; virtual void display(FILE * fd = stdout) = 0; virtual void display_as_XML(FILE * fd = stdout) = 0; @@ -116,6 +118,7 @@ public: bool operator==(LogFilterString & rhs); bool toss_this_entry(LogAccess * lad); + bool wipe_this_entry(LogAccess * lad); void display(FILE * fd = stdout); void display_as_XML(FILE * fd = stdout); @@ -150,6 +153,9 @@ private: inline bool _checkCondition(OperatorFunction f, const char *field_value, size_t field_value_length, char **val, LengthCondition lc); + inline bool _checkConditionAndWipe(OperatorFunction f, char **field_value, size_t field_value_length, char **val, + LengthCondition lc); + // -- member functions that are not allowed -- LogFilterString(); LogFilterString & operator=(LogFilterString & rhs); @@ -171,6 +177,7 @@ public: bool operator==(LogFilterInt & rhs); bool toss_this_entry(LogAccess * lad); + bool wipe_this_entry(LogAccess * lad); void display(FILE * fd = stdout); void display_as_XML(FILE * fd = stdout); @@ -200,6 +207,7 @@ public: void add(LogFilter * filter, bool copy = true); bool toss_this_entry(LogAccess * lad); + bool wipe_this_entry(LogAccess * lad); LogFilter *find_by_name(char *name); void clear(); @@ -300,4 +308,127 @@ LogFilterString::_checkCondition(OperatorFunction f, return retVal; } +/*--------------------------------------------------------------------------- + wipeField : Given a dest buffer, wipe the first occurance of the value of the + field in the buffer. + +--------------------------------------------------------------------------*/ +static void +wipeField(char** dest, char* field) +{ + + char* buf_dest = *dest; + + if (buf_dest) { + + char* query_param = strstr(buf_dest, "?"); + + if (!query_param) return; + + char* p1 = strstr(query_param, field); + + if (p1) { + char tmp_text[strlen(buf_dest) + 10]; + char *temp_text = tmp_text; + memcpy(temp_text, buf_dest, (p1 - buf_dest)); + temp_text += (p1 - buf_dest); + char* p2 = strstr(p1, "="); + if (p2) { + p2++; + memcpy(temp_text, p1, (p2 - p1)); + temp_text += (p2 - p1); + char* p3 = strstr(p2, "&"); + if (p3) { + for (int i=0; i<(p3 - p2); i++) + temp_text[i] = 'X'; + temp_text += (p3 - p2); + memcpy(temp_text, p3, ((buf_dest+strlen(buf_dest)) - p3)); + } else { + for (int i=0; i<((buf_dest+strlen(buf_dest)) - p2); i++) + temp_text[i] = 'X'; + } + } else { + return; + } + + tmp_text[strlen(buf_dest)] = '\0'; + strcpy(*dest, tmp_text); + } + } +} + +/*------------------------------------------------------------------------- + _checkConditionAndWipe + + check all values for a matching condition and perform wipe action + + the arguments to the function are: + + - a function f of type OperatorFunction that determines if the + condition is true for a single filter value. Note that this function + must return 0 if the condition is true. + - the value of the field from the log record + - the length of this field + - the array of filter values to compare to note that we pass this as an + argument because it can be either m_value or m_value_uppercase + - a LengthCondition argument that determines if the length of the field value + must be equal or larger to the length of the filter value (this is to + compare strings only if really needed + ------------------------------------------------------------------------*/ + +inline bool +LogFilterString::_checkConditionAndWipe(OperatorFunction f, char **field_value, size_t field_value_length, + char **val, LengthCondition lc) +{ + bool retVal = false; + + if (m_action != WIPE_FIELD_VALUE) return false; + + // make single value case a little bit faster by taking it out of loop + // + if (m_num_values == 1) { + switch (lc) { + case DATA_LENGTH_EQUAL: + retVal = (field_value_length == *m_length ? ((*f) (*field_value, *val) == 0 ? true : false) : false); + if (retVal) { + wipeField(field_value, *val); + } + break; + case DATA_LENGTH_LARGER: + retVal = (field_value_length > *m_length ? ((*f) (*field_value, *val) == 0 ? true : false) : false); + if (retVal) { + wipeField(field_value, *val); + } + break; + default: + ink_assert(!"LogFilterString::checkCondition " "unknown LengthCondition"); + } + } else { + size_t i; + switch (lc) { + case DATA_LENGTH_EQUAL: + for (i = 0; i < m_num_values; ++i) { + // condition is satisfied if f returns zero + if (field_value_length == m_length[i] && (*f) (*field_value, val[i]) == 0) { + retVal = true; + wipeField(field_value, val[i]); + } + } + break; + case DATA_LENGTH_LARGER: + for (i = 0; i < m_num_values; ++i) { + // condition is satisfied if f returns zero + if (field_value_length > m_length[i] && (*f) (*field_value, val[i]) == 0) { + retVal = true; + wipeField(field_value, val[i]); + } + } + break; + default: + ink_assert(!"LogFilterString::checkConditionAndWipe " "unknown LengthConditionAndWipe"); + } + } + return retVal; +} + #endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92bdda99/proxy/logging/LogObject.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogObject.cc b/proxy/logging/LogObject.cc index 52ace03..4dbc511 100644 --- a/proxy/logging/LogObject.cc +++ b/proxy/logging/LogObject.cc @@ -566,6 +566,10 @@ LogObject::log(LogAccess * lad, const char *text_entry) return Log::SKIP; } + if (lad && m_filter_list.wipe_this_entry(lad)) { + Debug("log", "entry wiped, ..."); + } + if (lad && m_format->is_aggregate()) { // marshal the field data into the temp space provided by the // LogFormat object for aggregate formats
