Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1502170
  • 博文数量: 228
  • 博客积分: 1698
  • 博客等级: 上尉
  • 技术积分: 3241
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-24 21:49
个人简介

Linux

文章分类

全部博文(228)

文章存档

2017年(1)

2016年(43)

2015年(102)

2014年(44)

2013年(5)

2012年(30)

2011年(3)

分类: LINUX

2015-07-02 11:35:10

来源:https://blog.zymlinux.net/index.php/archives/367

以修改age头为例讲解http头修改

    说起ats的http header的修改,其实已经有很多插件了,包括增加的,删除的,修改的都可以,但是像age这样value值不固定的http header的修改的还是没有详细介绍。本文就通过对replace-header插件代码的修改,将age换成x-age来介绍下这类插件的写法,希望通过本文和之前的插件,大家可以对整个ats的http header的操作就不应再有什么困难了。

下面将按照对replace header插件代码的修改顺序来介绍age头的修改,在这里对用户的访问流程做如下约定
age

  • 0方向:表示从用户到ats
  • 1方向:表示从ats到源站
  • 2方向:表示从源站到ats
  • 3方向:表示从ats到用户
  • 首先是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方向,有如下几处:

  • 1、replace_header_plugin()的case
  • //  87   case TS_EVENT_HTTP_READ_RESPONSE_HDR:
    87   case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
    

  • 2、replace_header()的response header
  • //  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一下子就生效了,可以看看效果哦。
    1



    阅读(1782) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~