以修改age头为例讲解http头修改
说起ats的http header的修改,其实已经有很多插件了,包括增加的,删除的,修改的都可以,但是像age这样value值不固定的http header的修改的还是没有详细介绍。本文就通过对replace-header插件代码的修改,将age换成x-age来介绍下这类插件的写法,希望通过本文和之前的插件,大家可以对整个ats的http header的操作就不应再有什么困难了。
下面将按照对replace header插件代码的修改顺序来介绍age头的修改,在这里对用户的访问流程做如下约定
首先是TSPluginInit()函数,在这里面我们只需要修改一行代码就可以了,至于上面的版本信息什么的,都不是重点,看个人意愿了,需要修改的是下面这行代码:
// 140 TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, TSContCreate(replace_header_plugin, NULL));
140 TSHttpHookAdd(TS_HTTP_SEND_RESPONSE_HDR_HOOK, TSContCreate(replace_header_plugin, NULL));
从上面的修改可以看到,是把TS_HTTP_READ_RESPONSE_HDR_HOOK替换为了TS_HTTP_SEND_RESPONSE_HDR_HOOK,这两个区别,还是从上面那张图说起,这个READ和SEND是对应上面的2方向和3方向的(同理0方向和1方向上的分别为READ_REQUEST和SEND_REQUEST),我们修改age头后希望在用户端能够看到,所以就用了SEND,表示3方向的,用户端可以看到,这样子也不会破坏ats的缓存内容。
因此相应的,整个插件里面都需要修改成3方向,有如下几处:
// 87 case TS_EVENT_HTTP_READ_RESPONSE_HDR:
87 case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
// 49 if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
// 50 TSError("couldn't retrieve server response header.\n");
// 51 goto done;
// 52 }
49 if (TSHttpTxnClientRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
50 TSError("couldn't retrieve server response header.\n");
51 goto done;
52 }
经过了以上两个地方的修改,基础的工作就算是做完了,现在就是要真正的去修改age这个http header了,先贴代码,然后详细解释
// 54 field_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
54 field_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, TS_MIME_FIELD_AGE, TS_MIME_LEN_AGE);
55 if (field_loc == TS_NULL_MLOC) {
56 /* field was not found */
57
58 /* create a new field in the header */
59 TSMimeHdrFieldCreate(resp_bufp, resp_loc, &field_loc); /* Probably should check for errors. */
60 /* set its name */
// 61 TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
61 TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, "x-age", 5);
62 /* set its value */
// 63 TSMimeHdrFieldValueAppend(resp_bufp, resp_loc, field_loc, -1, "none", 4);
62 /*add default value*/
63 TSMimeHdrFieldValueIntInsert(resp_bufp, resp_loc, field_loc, -1, 0);
64 /* insert it into the header */
65 TSMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc);
66 TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
67 TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
68 } else {
// 69 /* clear the field */
// 70 TSMimeHdrFieldValuesClear(resp_bufp, resp_loc, field_loc);
// 71 /* set the value to "none" */
// 72 TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, "none", 4);
/* Just need to replace its name*/
TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, "x-age", 5);
73 TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
74 TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
75 }
-
好了,根据上面修改的代码详细介绍下修改的内容,第一个地方是54行,这里是TSMimeHdrFieldFind()函数,就是找到这个http header,所以这里就要改成AGE,把两个ACCEPT_RANGE都要改成AGE,这样就是找到AGE这个头域。
-
然后就是处理了,在这里有两种情况:一种是找到了,有age这个http header;另一种是没找到。首先处理的是没有找到的情况,没有找到的话我们需要添加该头域,并添加一个初始化值,于是我们修改了61行和63行,其中第61行是添加http header的名称x-age,因为该http header不是标准的,因此没有变量,在这里我们没有去破坏定义,添加这个变量,而是直接写。我们需要修改最后两个参数,第一个是名字,即x-age,后面一个参数是长度,x-age总共5个字符,因此长度是5。名字已经添加了,然后就是值了,在这里要注意,x-age变量是一个int类型的,因此需要使用TSMimeHdrFieldValueIntInsert()函数,添加一个Int类型的值,在这里默认设置成0。
然后是找到的情况,如果找到了就很简单了只需要将age修改成x-age就可以了,其他的都不需要做任何操作,因此可以把69~72行的操作都不需要了,仅仅需要重新set一下age的name为x-age就可以了,这里也不要忘了x-age的长度是5。
-
好了,到这里代码的修改就算完成了,然后就是测试我们的修改是否正确了,编译安装该插件
-
make & make install
然后是在plugin.config中添加该插件,名字看自己取了,我这里没有修改名字,因此还是叫replace-header.so,添加完毕之后traffic_line -x一下子就生效了,可以看看效果哦。