Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
33 changes: 22 additions & 11 deletions plugins/header_rewrite/README
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ perform various header "rewrite" rules (operations) on a request or
response. Currently, only one operation is supported, since we had to get
this rolling asap.

Note that currently only static string "values" are supported. We'll add
advanced features to allow for expansions in a future release.

Using the plugin
----------------

Expand All @@ -28,14 +25,15 @@ during the origin response header parsing, using READ_RESPONSE_HDR_HOOK.

Operators
---------
The following operators are available:
The following operators are available:

rm-header header-name [flags]
add-header header <value> [flags]
set-status <status-code> [flags]
set-status-reason <value> [flags]
set-config config <value> [flags]
no-op [flags]
counter counter-name [flags]

The following operator(s) currently only works when instantiating the
plugin as a remap plugin:
Expand All @@ -60,6 +58,18 @@ Operator flags
[L] Last rule, do not continue


Variable expansion
------------------
Currntly only limited variable expansion is supported in add-header. Supported
substitutions include:
%<proto> Protocol
%<port> Port
%<chi> Client IP
%<cqhl> Client request length
%<cqhm> Client HTTP method
%<cquup> Client unmapped URI


Conditions
----------
The conditions are used as qualifiers: The operators specified will
Expand All @@ -71,8 +81,8 @@ only be evaluated if the condition(s) are met.
cond %{TRUE} [flags]
cond %{FALSE} [flags]
cond %{HEADER:header-name} operand [flags]
cond %{COOKIE:cookie-name} operand [flags]
cond %{CLIENT-HEADER:header-name} operand [flags]
cond %{METHOD} operand [flags]
cond %{PROTOCOL} operand [flags]
cond %{PORT} operand [flags]
cond %{HOST} operand [flags]
Expand Down Expand Up @@ -103,7 +113,7 @@ configuration, but being the default it is also optional.

Condition flags
---------------
[NC] Not ase sensitive condition (when applicable)
[NC] Not case sensitive condition (when applicable)
[AND] AND with next condition (default)
[OR] OR with next condition
[NOT] Invert this condition
Expand Down Expand Up @@ -133,11 +143,12 @@ Examples
--------

cond %{HEADER:X-Y-Foobar}
cond %{METHOD} =GET [OR]
cond %{METHOD} =POST
cond %{COOKIE:X-DC} =DC1
add-header X-Y-Fiefum %{HEADER:X-Y-Foobar}
add-header X-Forwarded-For %<chi>
rm-header X-Y-Foobar
rm-header Set-Cookie
counter plugin.header_rewrite.x-y-foobar-dc1

cond %{HEADER:X-Y-Foobar} "Some string" [AND,NC]

Expand All @@ -164,13 +175,13 @@ Version 1.6.9 (10,17,11,cdoshi)
- Support for PATH condition

Version 1.6.8 (10/17/11,cdoshi)
- Replace the INKHttpHdrStatusSet with INKHttptxnSetHttpRetStatus
- Replace the INKHttpHdrStatusSet with INKHttptxnSetHttpRetStatus

Version 1.6.7 (07/21/11, bcall)
- [bug 4699620] - Removed some extra printf()'s

Version 1.6.6 (cdoshi)
- when Host adder is added setHostChange will be called
- when Host adder is added setHostChange will be called

Version 1.6.5 (cdoshi)
- fix QSA for set-destination
Expand All @@ -185,7 +196,7 @@ Version 1.6.2 (cdoshi)
- Support for regex matcher

Version 1.6.1 (09/15/10, leif)
- [bug 3985913]
- [bug 3985913]

Version 1.6.0 (07/14/10, leif)
- Added support for the timeout-out operator.
Expand Down
10 changes: 5 additions & 5 deletions plugins/header_rewrite/condition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ parse_matcher_op(std::string& arg)
{
switch (arg[0]) {
case '=':
arg.erase(0,1);
arg.erase(0, 1);
return MATCH_EQUAL;
break;
case '<':
arg.erase(0,1);
arg.erase(0, 1);
return MATCH_LESS_THEN;
break;
case '>':
arg.erase(0,1);
arg.erase(0, 1);
return MATCH_GREATER_THEN;
break;
case '/':
arg.erase(0,1);
arg.erase(arg.length() -1 , arg.length());
arg.erase(0, 1);
arg.erase(arg.length() - 1, arg.length());
return MATCH_REGULAR_EXPRESSION;
break;
default:
Expand Down
2 changes: 1 addition & 1 deletion plugins/header_rewrite/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
limitations under the License.
*/
//////////////////////////////////////////////////////////////////////////////////////////////
//
//
// Implement the classes for the various types of hash keys we support.
//
#ifndef __CONDITION_H__
Expand Down
104 changes: 90 additions & 14 deletions plugins/header_rewrite/conditions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,24 @@ ConditionStatus::initialize(Parser& p)


void
ConditionStatus::initialize_hooks() {
ConditionStatus::initialize_hooks()
{
add_allowed_hook(TS_HTTP_READ_RESPONSE_HDR_HOOK);
add_allowed_hook(TS_HTTP_SEND_RESPONSE_HDR_HOOK);
}


bool
ConditionStatus::eval(const Resources& res) {
ConditionStatus::eval(const Resources& res)
{
TSDebug(PLUGIN_NAME, "Evaluating STATUS()"); // TODO: It'd be nice to get the args here ...
return static_cast<const Matchers<TSHttpStatus>*>(_matcher)->test(res.resp_status);
}


void
ConditionStatus::append_value(std::string& s, const Resources& res) {
ConditionStatus::append_value(std::string& s, const Resources& res)
{
s += boost::lexical_cast<std::string>(res.resp_status);
TSDebug(PLUGIN_NAME, "Appending STATUS(%d) to evaluation value -> %s", res.resp_status, s.c_str());
}
Expand All @@ -86,7 +89,8 @@ ConditionRandom::initialize(Parser& p)


bool
ConditionRandom::eval(const Resources& /* res ATS_UNUSED */) {
ConditionRandom::eval(const Resources& /* res ATS_UNUSED */)
{
TSDebug(PLUGIN_NAME, "Evaluating RANDOM(%d)", _max);
return static_cast<const Matchers<unsigned int>*>(_matcher)->test(rand_r(&_seed) % _max);
}
Expand Down Expand Up @@ -188,10 +192,10 @@ ConditionHeader::append_value(std::string& s, const Resources& res)
field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, _qualifier.c_str(), _qualifier.size());
TSDebug(PLUGIN_NAME, "Getting Header: %s, field_loc: %p", _qualifier.c_str(), field_loc);
if (field_loc != NULL) {
value = TSMimeHdrFieldValueStringGet(res.bufp, res.hdr_loc, field_loc, 0, &len);
value = TSMimeHdrFieldValueStringGet(bufp, res.hdr_loc, field_loc, 0, &len);
TSDebug(PLUGIN_NAME, "Appending HEADER(%s) to evaluation value -> %.*s", _qualifier.c_str(), len, value);
s.append(value, len);
TSHandleMLocRelease(res.bufp, res.hdr_loc, field_loc);
TSHandleMLocRelease(bufp, res.hdr_loc, field_loc);
}
}
}
Expand Down Expand Up @@ -220,13 +224,19 @@ ConditionPath::initialize(Parser& p)
_matcher = match;
}

void
ConditionPath::append_value(std::string& s, const Resources& res)
{
int path_len = 0;
const char *path = TSUrlPathGet(res._rri->requestBufp, res._rri->requestUrl, &path_len);
TSDebug(PLUGIN_NAME, "Appending PATH to evaluation value: %.*s", path_len, path);
s.append(path, path_len);
void ConditionPath::append_value(std::string& s, const Resources& res) {
TSMBuffer bufp;
TSMLoc url_loc;

if (TSHttpTxnPristineUrlGet(res.txnp, &bufp, &url_loc) == TS_SUCCESS) {
int path_length;
const char *path = TSUrlPathGet(bufp, url_loc, &path_length);

if (path && path_length)
s.append(path, path_length);

TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc);
}
}

bool
Expand Down Expand Up @@ -288,7 +298,8 @@ ConditionUrl::initialize(Parser& /* p ATS_UNUSED */)


void
ConditionUrl::set_qualifier(const std::string& q) {
ConditionUrl::set_qualifier(const std::string& q)
{
Condition::set_qualifier(q);

_url_qual = parse_url_qualifier(q);
Expand Down Expand Up @@ -374,3 +385,68 @@ ConditionDBM::eval(const Resources& res)

return static_cast<const Matchers<std::string>*>(_matcher)->test(s);
}


// ConditionCookie: request or response header
void ConditionCookie::initialize(Parser& p)
{
Condition::initialize(p);

Matchers<std::string>* match = new Matchers<std::string>(_cond_op);
match->set(p.get_arg());

_matcher = match;

require_resources(RSRC_CLIENT_REQUEST_HEADERS);
}

void ConditionCookie::append_value(std::string& s, const Resources& res)
{
TSMBuffer bufp = res.client_bufp;
TSMLoc hdr_loc = res.client_hdr_loc;
TSMLoc field_loc;
int error;
int cookies_len;
int cookie_value_len;
const char *cookies;
const char *cookie_value;
const char * const cookie_name = _qualifier.c_str();
const int cookie_name_len = _qualifier.length();

// Sanity
if (bufp == NULL || hdr_loc == NULL)
return;

// Find Cookie
field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, TS_MIME_FIELD_COOKIE, TS_MIME_LEN_COOKIE);
if (field_loc == NULL)
return;

// Get all cookies
// NB! Cookie field does not support commas, so we use index == 0
cookies = TSMimeHdrFieldValueStringGet(bufp, hdr_loc, field_loc, 0, &cookies_len);
if (cookies == NULL || cookies_len <= 0)
goto out_release_field;

// Find particular cookie's value
error = get_cookie_value(cookies, cookies_len, cookie_name, cookie_name_len, &cookie_value, &cookie_value_len);
if (error == TS_ERROR)
goto out_release_field;

TSDebug(PLUGIN_NAME, "Appending COOKIE(%s) to evaluation value -> %.*s", cookie_name, cookie_value_len, cookie_value);
s.append(cookie_value, cookie_value_len);

// Unwind
out_release_field:
TSHandleMLocRelease(bufp, hdr_loc, field_loc);
}

bool ConditionCookie::eval(const Resources& res)
{
std::string s;

append_value(s, res);
bool rval = static_cast<const Matchers<std::string>*>(_matcher)->test(s);
TSDebug(PLUGIN_NAME, "Evaluating COOKIE(%s): %s: rval: %d", _qualifier.c_str(), s.c_str(), rval);
return rval;
}
Loading