You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zy...@apache.org on 2013/02/17 03:50:00 UTC

git commit: TS-1710: esi plugin enhancement such as support forward proxy

Updated Branches:
  refs/heads/master 31a52688e -> 3f82a9be5


TS-1710: esi plugin enhancement such as support forward proxy

  * bug fixed: do NOT support keep-alive for async requests,
    ignore header Proxy-Connection
  * save header for fetch event when http status is not 200
  * getRequestStatus judge http status
  * node type change from uint32_t to enum for changing from "if ...
    else if" to "switch"
  * esi:include tag allows empty url

Signed-off-by: Yu Qing <zh...@taobao.com>
Signed-off-by: Zhao Yongming <mi...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/3f82a9be
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/3f82a9be
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/3f82a9be

Branch: refs/heads/master
Commit: 3f82a9be544372f280541bd67e9434155e74449b
Parents: 31a5268
Author: Yu Qing <zh...@taobao.com>
Authored: Sat Feb 16 13:54:42 2013 +0800
Committer: Zhao Yongming <mi...@gmail.com>
Committed: Sun Feb 17 10:29:18 2013 +0800

----------------------------------------------------------------------
 CHANGES                                            |    3 +
 .../esi/fetcher/HttpDataFetcherImpl.cc             |   28 ++-
 .../experimental/esi/fetcher/HttpDataFetcherImpl.h |    8 +-
 plugins/experimental/esi/lib/DocNode.cc            |   15 -
 plugins/experimental/esi/lib/DocNode.h             |   38 ++--
 plugins/experimental/esi/lib/EsiParser.cc          |   85 +++---
 plugins/experimental/esi/lib/EsiParser.h           |    4 +-
 plugins/experimental/esi/lib/EsiProcessor.cc       |  228 ++++++++-------
 plugins/experimental/esi/lib/EsiProcessor.h        |    6 +-
 plugins/experimental/esi/lib/FailureInfo.cc        |    2 +-
 plugins/experimental/esi/plugin.cc                 |   18 +-
 plugins/experimental/esi/test/sampleProb.cc        |    2 +-
 12 files changed, 241 insertions(+), 196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index bbd1100..01c2928 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 3.3.1
 
+  *) [TS-1710] esi plugin enhancement such as support forward proxy
+   Author: Yu Qing <zh...@taobao.com>
+
   *) [TS-1707] fix FreeBSD store blocks calculation
    Thanks to Ben Aitchison <ben at meh dot net dot nz>
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.cc b/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.cc
index ab70a2b..a76633a 100644
--- a/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.cc
+++ b/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.cc
@@ -22,8 +22,8 @@
  */
 
 #include "HttpDataFetcherImpl.h"
-#include "Utils.h"
-#include "gzip.h"
+#include "lib/Utils.h"
+#include "lib/gzip.h"
 
 #include <arpa/inet.h>
 
@@ -112,7 +112,8 @@ HttpDataFetcherImpl::_isFetchEvent(TSEvent event, int &base_event_id) const {
   base_event_id = _getBaseEventId(event);
   if ((base_event_id < 0) || (base_event_id >= static_cast<int>(_page_entry_lookup.size()))) {
     TSDebug(_debug_tag, "[%s] Event id %d not within fetch event id range [%d, %ld)",
-             __FUNCTION__, event, FETCH_EVENT_ID_BASE, static_cast<long int>(FETCH_EVENT_ID_BASE + (_page_entry_lookup.size() * 3)));
+             __FUNCTION__, event, FETCH_EVENT_ID_BASE,
+             static_cast<long int>(FETCH_EVENT_ID_BASE + (_page_entry_lookup.size() * 3)));
     return false;
   }
   return true;
@@ -158,9 +159,9 @@ HttpDataFetcherImpl::handleFetchEvent(TSEvent event, void *edata) {
   TSHttpParserClear(_http_parser);
   
   if (TSHttpHdrParseResp(_http_parser, req_data.bufp, req_data.hdr_loc, &startptr, endptr) == TS_PARSE_DONE) {
-    TSHttpStatus resp_status = TSHttpHdrStatusGet(req_data.bufp, req_data.hdr_loc);
-    if (resp_status == TS_HTTP_STATUS_OK) {
-      valid_data_received = true;
+    req_data.resp_status = TSHttpHdrStatusGet(req_data.bufp, req_data.hdr_loc);
+    valid_data_received = true;
+    if (req_data.resp_status == TS_HTTP_STATUS_OK) {
       req_data.body_len = endptr - startptr;
       req_data.body = startptr;
       TSDebug(_debug_tag,
@@ -191,8 +192,8 @@ HttpDataFetcherImpl::handleFetchEvent(TSEvent event, void *edata) {
 
     } else {
       TSDebug(_debug_tag, "[%s] Received non-OK status %d for request [%s]",
-               __FUNCTION__, resp_status, req_str.data());
-    } 
+               __FUNCTION__, req_data.resp_status, req_str.data());
+    }
   } else {
     TSDebug(_debug_tag, "[%s] Could not parse response for request [%s]",
              __FUNCTION__, req_str.data());
@@ -289,12 +290,15 @@ HttpDataFetcherImpl::getRequestStatus(const string &url) const {
     TSError("Status being requested for unregistered URL [%s]", url.data());
     return STATUS_ERROR;
   }
+
   if (!(iter->second).complete) {
     return STATUS_DATA_PENDING;
   }
-  if ((iter->second).response.empty()) {
+
+  if ((iter->second).resp_status != TS_HTTP_STATUS_OK) {
     return STATUS_ERROR;
   }
+
   return STATUS_DATA_AVAILABLE;
 }
 
@@ -318,6 +322,12 @@ HttpDataFetcherImpl::useHeader(const HttpHeader &header) {
       return;
   }
 
+  // should not support keep-alive for async requests
+  if (Utils::areEqual(header.name, header.name_len,
+              TS_MIME_FIELD_PROXY_CONNECTION, TS_MIME_LEN_PROXY_CONNECTION)) {
+      return;
+  }
+
   _headers_str.append(header.name, header.name_len);
   _headers_str.append(": ");
   _headers_str.append(header.value, header.value_len);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.h
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.h b/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.h
index 467006f..8864d74 100644
--- a/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.h
+++ b/plugins/experimental/esi/fetcher/HttpDataFetcherImpl.h
@@ -29,8 +29,8 @@
 #include <vector>
 
 #include "ts/ts.h"
-#include "StringHash.h"
-#include "HttpHeader.h"
+#include "lib/StringHash.h"
+#include "lib/HttpHeader.h"
 #include "HttpDataFetcher.h"
 
 class HttpDataFetcherImpl : public HttpDataFetcher
@@ -99,11 +99,13 @@ private:
     std::string raw_response;
     const char *body;
     int body_len;
+    TSHttpStatus resp_status;
     CallbackObjectList callback_objects;
     bool complete;
     TSMBuffer bufp;
     TSMLoc hdr_loc;
-    RequestData() : body(0), body_len(0), complete(false), bufp(0), hdr_loc(0) { };
+
+    RequestData() : body(0), body_len(0), resp_status(TS_HTTP_STATUS_NONE), complete(false), bufp(0), hdr_loc(0) { }
   };
 
   typedef __gnu_cxx::hash_map<std::string, RequestData, EsiLib::StringHasher> UrlToContentMap;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/DocNode.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/DocNode.cc b/plugins/experimental/esi/lib/DocNode.cc
index 1d2e83c..01b0a53 100644
--- a/plugins/experimental/esi/lib/DocNode.cc
+++ b/plugins/experimental/esi/lib/DocNode.cc
@@ -27,21 +27,6 @@
 using std::string;
 using namespace EsiLib;
 
-const DocNode::TYPE DocNode::TYPE_UNKNOWN = 0;
-const DocNode::TYPE DocNode::TYPE_PRE = 1;
-const DocNode::TYPE DocNode::TYPE_INCLUDE = 2;
-const DocNode::TYPE DocNode::TYPE_COMMENT = 3;
-const DocNode::TYPE DocNode::TYPE_REMOVE = 4;
-const DocNode::TYPE DocNode::TYPE_VARS = 5;
-const DocNode::TYPE DocNode::TYPE_CHOOSE = 6;
-const DocNode::TYPE DocNode::TYPE_WHEN = 7;
-const DocNode::TYPE DocNode::TYPE_OTHERWISE = 8;
-const DocNode::TYPE DocNode::TYPE_TRY = 9;
-const DocNode::TYPE DocNode::TYPE_ATTEMPT = 10;
-const DocNode::TYPE DocNode::TYPE_EXCEPT = 11;
-const DocNode::TYPE DocNode::TYPE_HTML_COMMENT = 12;
-const DocNode::TYPE DocNode::TYPE_SPECIAL_INCLUDE = 13;
-
 const char *DocNode::type_names_[] = { "UNKNOWN",
                                        "PRE",
                                        "INCLUDE",

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/DocNode.h
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/DocNode.h b/plugins/experimental/esi/lib/DocNode.h
index da6bdb6..c34dc3c 100644
--- a/plugins/experimental/esi/lib/DocNode.h
+++ b/plugins/experimental/esi/lib/DocNode.h
@@ -21,8 +21,8 @@
   limitations under the License.
  */
 
-#ifndef _ESI_DOC_NODE_H
-#define _ESI_DOC_NODE_H
+#ifndef _FETCHER_DOC_NODE_H
+#define _FETCHER_DOC_NODE_H
 
 #include <stdint.h>
 #include <list>
@@ -70,22 +70,22 @@ class DocNode
 {
   
 public:
-
-  typedef int32_t TYPE;
-  static const TYPE TYPE_UNKNOWN;
-  static const TYPE TYPE_PRE;
-  static const TYPE TYPE_INCLUDE;
-  static const TYPE TYPE_COMMENT;
-  static const TYPE TYPE_REMOVE;
-  static const TYPE TYPE_VARS;
-  static const TYPE TYPE_CHOOSE;
-  static const TYPE TYPE_WHEN;
-  static const TYPE TYPE_OTHERWISE;
-  static const TYPE TYPE_TRY;
-  static const TYPE TYPE_ATTEMPT;
-  static const TYPE TYPE_EXCEPT;
-  static const TYPE TYPE_HTML_COMMENT;
-  static const TYPE TYPE_SPECIAL_INCLUDE;
+  enum TYPE {
+    TYPE_UNKNOWN = 0,
+    TYPE_PRE = 1,
+    TYPE_INCLUDE = 2,
+    TYPE_COMMENT = 3,
+    TYPE_REMOVE = 4,
+    TYPE_VARS = 5,
+    TYPE_CHOOSE = 6,
+    TYPE_WHEN = 7,
+    TYPE_OTHERWISE = 8,
+    TYPE_TRY = 9,
+    TYPE_ATTEMPT = 10,
+    TYPE_EXCEPT = 11,
+    TYPE_HTML_COMMENT = 12,
+    TYPE_SPECIAL_INCLUDE = 13,
+  };
 
   // Use with care - only types defined above will have valid names 
   static const char *type_names_[];
@@ -113,4 +113,4 @@ private:
 
 };
 
-#endif // _ESI_DOC_NODE_H
+#endif // _FETCHER_DOC_NODE_H

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/EsiParser.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/EsiParser.cc b/plugins/experimental/esi/lib/EsiParser.cc
index 4a0ebb1..29f132f 100644
--- a/plugins/experimental/esi/lib/EsiParser.cc
+++ b/plugins/experimental/esi/lib/EsiParser.cc
@@ -175,8 +175,10 @@ EsiParser::_compareData(const string &data, size_t pos, const char *str, int str
       }
     }
     else {
+      /*
       _debugLog(_debug_tag, "[%s] string [%.*s] is not equal to data at position %d", 
                 __FUNCTION__, str_len, str, pos);
+      */
       return NO_MATCH;
     }
   }
@@ -337,43 +339,54 @@ EsiParser::_parse(const string &data, int &parse_start_pos,
       }
     }
 
-    parse_result = false;
-    
     // now we process only complete nodes
-    if (node_info->type == DocNode::TYPE_INCLUDE) {
-      _debugLog(_debug_tag, "[%s] Handling include tag...", __FUNCTION__);
-      parse_result = _processIncludeTag(data, curr_pos, end_pos, node_list);
-    } else if ((node_info->type == DocNode::TYPE_COMMENT) || (node_info->type == DocNode::TYPE_REMOVE)) {
-      _debugLog(_debug_tag, "[%s] Adding node [%s]", __FUNCTION__,
-                DocNode::type_names_[node_info->type]);
-      node_list.push_back(DocNode(node_info->type)); // no data required
-      parse_result = true;
-    } else if (node_info->type == DocNode::TYPE_WHEN) {
-      _debugLog(_debug_tag, "[%s] Handling when tag...", __FUNCTION__);
-      parse_result = _processWhenTag(data, curr_pos, end_pos, node_list);
-    } else if (node_info->type == DocNode::TYPE_TRY) {
-      _debugLog(_debug_tag, "[%s] Handling try tag...", __FUNCTION__);
-      parse_result = _processTryTag(data, curr_pos, end_pos, node_list);
-    } else if (node_info->type == DocNode::TYPE_CHOOSE) {
-      _debugLog(_debug_tag, "[%s] Handling choose tag...", __FUNCTION__);
-      parse_result = _processChooseTag(data, curr_pos, end_pos, node_list);
-    } else if ((node_info->type == DocNode::TYPE_OTHERWISE) ||
-               (node_info->type == DocNode::TYPE_ATTEMPT) ||
-               (node_info->type == DocNode::TYPE_EXCEPT)) {
-      _debugLog(_debug_tag, "[%s] Handling %s tag...", __FUNCTION__,
-                DocNode::type_names_[node_info->type]);
-      parse_result = _processSimpleContentTag(node_info->type, data.data() + curr_pos,
-                                              end_pos - curr_pos, node_list);
-    } else if ((node_info->type == DocNode::TYPE_VARS) || 
-               (node_info->type == DocNode::TYPE_HTML_COMMENT)) {
-      _debugLog(_debug_tag, "[%s] added string of size %d starting with [%.5s] for node %s",
-                __FUNCTION__, end_pos - curr_pos, data.data() + curr_pos,
-                DocNode::type_names_[node_info->type]);
-      node_list.push_back(DocNode(node_info->type, data.data() + curr_pos, end_pos - curr_pos));
-      parse_result = true;
-    } else if (node_info->type == DocNode::TYPE_SPECIAL_INCLUDE) {
-      _debugLog(_debug_tag, "[%s] Handling special include tag...", __FUNCTION__);
-      parse_result = _processSpecialIncludeTag(data, curr_pos, end_pos, node_list);
+    switch(node_info->type) {
+      case DocNode::TYPE_INCLUDE:
+        _debugLog(_debug_tag, "[%s] Handling include tag...", __FUNCTION__);
+        parse_result = _processIncludeTag(data, curr_pos, end_pos, node_list);
+        break;
+      case DocNode::TYPE_COMMENT:
+      case DocNode::TYPE_REMOVE:
+        _debugLog(_debug_tag, "[%s] Adding node [%s]", __FUNCTION__,
+            DocNode::type_names_[node_info->type]);
+        node_list.push_back(DocNode(node_info->type)); // no data required
+        parse_result = true;
+        break;
+      case DocNode::TYPE_WHEN:
+        _debugLog(_debug_tag, "[%s] Handling when tag...", __FUNCTION__);
+        parse_result = _processWhenTag(data, curr_pos, end_pos, node_list);
+        break;
+      case DocNode::TYPE_TRY:
+        _debugLog(_debug_tag, "[%s] Handling try tag...", __FUNCTION__);
+        parse_result = _processTryTag(data, curr_pos, end_pos, node_list);
+        break;
+      case DocNode::TYPE_CHOOSE:
+        _debugLog(_debug_tag, "[%s] Handling choose tag...", __FUNCTION__);
+        parse_result = _processChooseTag(data, curr_pos, end_pos, node_list);
+        break;
+      case DocNode::TYPE_OTHERWISE:
+      case DocNode::TYPE_ATTEMPT:
+      case DocNode::TYPE_EXCEPT:
+        _debugLog(_debug_tag, "[%s] Handling %s tag...", __FUNCTION__,
+            DocNode::type_names_[node_info->type]);
+        parse_result = _processSimpleContentTag(node_info->type, data.data() + curr_pos,
+            end_pos - curr_pos, node_list);
+        break;
+      case DocNode::TYPE_VARS:
+      case DocNode::TYPE_HTML_COMMENT:
+        _debugLog(_debug_tag, "[%s] added string of size %d starting with [%.5s] for node %s",
+            __FUNCTION__, end_pos - curr_pos, data.data() + curr_pos,
+            DocNode::type_names_[node_info->type]);
+        node_list.push_back(DocNode(node_info->type, data.data() + curr_pos, end_pos - curr_pos));
+        parse_result = true;
+        break;
+      case DocNode::TYPE_SPECIAL_INCLUDE:
+        _debugLog(_debug_tag, "[%s] Handling special include tag...", __FUNCTION__);
+        parse_result = _processSpecialIncludeTag(data, curr_pos, end_pos, node_list);
+        break;
+      default:
+        parse_result = false;
+        break;
     }
 
     if (!parse_result) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/EsiParser.h
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/EsiParser.h b/plugins/experimental/esi/lib/EsiParser.h
index c3779ce..2dffc59 100644
--- a/plugins/experimental/esi/lib/EsiParser.h
+++ b/plugins/experimental/esi/lib/EsiParser.h
@@ -26,8 +26,8 @@
 
 #include <string>
 
-#include "ComponentBase.h"
-#include "DocNode.h"
+#include "lib/ComponentBase.h"
+#include "lib/DocNode.h"
 
 class EsiParser : private EsiLib::ComponentBase
 {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/EsiProcessor.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/EsiProcessor.cc b/plugins/experimental/esi/lib/EsiProcessor.cc
index 48677b4..15a3e87 100644
--- a/plugins/experimental/esi/lib/EsiProcessor.cc
+++ b/plugins/experimental/esi/lib/EsiProcessor.cc
@@ -150,6 +150,18 @@ EsiProcessor::_getIncludeData(const DocNode &node, const char **content_ptr /* =
                               int *content_len_ptr /* = 0 */) {
   if (node.type == DocNode::TYPE_INCLUDE) {
     const Attribute &url = node.attr_list.front();
+
+    if (url.value_len == 0) {  //allow empty url
+      if (content_ptr && content_len_ptr) {
+        *content_ptr = NULL;
+        *content_len_ptr = 0;
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+
     string raw_url(url.value, url.value_len);
     StringHash::iterator iter = _include_urls.find(raw_url);
     if (iter == _include_urls.end()) {
@@ -298,7 +310,7 @@ EsiProcessor::process(const char *&data, int &data_len) {
   _curr_state = PROCESSED;
   for (node_iter = _node_list.begin(); node_iter != _node_list.end(); ++node_iter) {
     DocNode &doc_node = *node_iter; // handy reference
-    _debugLog(_debug_tag, "[%s] Processing ESI node [%s] with data of size %d starting with [%.5s...]", 
+    _debugLog(_debug_tag, "[%s] Processing ESI node [%s] with data of size %d starting with [%.10s...]",
               __FUNCTION__, DocNode::type_names_[doc_node.type], doc_node.data_len,
               (doc_node.data_len ? doc_node.data : "(null)"));
     if (doc_node.type == DocNode::TYPE_PRE) {
@@ -348,7 +360,9 @@ EsiProcessor::_processEsiNode(const DocNodeList::iterator &iter) {
     const char *content;
     int content_len;
     if ((retval = _getIncludeData(node, &content, &content_len))) {
-      _output_data.append(content, content_len);
+      if (content_len > 0) {
+        _output_data.append(content, content_len);
+      }
     }
   } else if ((node.type == DocNode::TYPE_COMMENT) || (node.type == DocNode::TYPE_REMOVE) ||
              (node.type == DocNode::TYPE_TRY) || (node.type == DocNode::TYPE_CHOOSE) ||
@@ -426,8 +440,7 @@ EsiProcessor::_handleTry(DocNodeList::iterator &curr_node) {
   DocNodeList::iterator attempt_node = end_node, except_node = end_node;
   for (iter = curr_node->child_nodes.begin(); iter != end_node; ++iter) {
     if (iter->type == DocNode::TYPE_ATTEMPT) {
-        
-          attempt_node = iter;
+      attempt_node = iter;
     } else if (iter->type == DocNode::TYPE_EXCEPT) {
       except_node = iter;
     }
@@ -476,116 +489,129 @@ EsiProcessor::_preprocess(DocNodeList &node_list, int &n_prescanned_nodes) {
   for (int i = 0; i < n_prescanned_nodes; ++i, ++list_iter);
   
   for (; list_iter != node_list.end(); ++list_iter, ++n_prescanned_nodes) {
-    if (list_iter->type == DocNode::TYPE_CHOOSE) {
-      if (!_handleChoose(list_iter)) {
-        _errorLog("[%s] Failed to preprocess choose node", __FUNCTION__);
-        return false;
-      } 
-      _debugLog(_debug_tag, "[%s] handled choose node successfully", __FUNCTION__);
-    } else if (list_iter->type == DocNode::TYPE_TRY) {
-      if (!_handleTry(list_iter)) {
-        _errorLog("[%s] Failed to preprocess try node", __FUNCTION__);
-        return false;
-      }
-      _debugLog(_debug_tag, "[%s] handled try node successfully", __FUNCTION__);
-    } else if (list_iter->type == DocNode::TYPE_HTML_COMMENT) {
-      if (!_handleHtmlComment(list_iter)) {
-        _errorLog("[%s] Failed to preprocess try node", __FUNCTION__);
-        return false;
-      }
-    } else if (list_iter->type == DocNode::TYPE_INCLUDE) {
-      Stats::increment(Stats::N_INCLUDES);
-      const Attribute &src = list_iter->attr_list.front();
-      raw_url.assign(src.value, src.value_len);
-      _debugLog(_debug_tag, "[%s] Adding fetch request for url [%.*s]", 
+    switch (list_iter->type) {
+      case DocNode::TYPE_CHOOSE:
+        if (!_handleChoose(list_iter)) {
+          _errorLog("[%s] Failed to preprocess choose node", __FUNCTION__);
+          return false;
+        }
+        _debugLog(_debug_tag, "[%s] handled choose node successfully", __FUNCTION__);
+        break;
+      case DocNode::TYPE_TRY:
+        if (!_handleTry(list_iter)) {
+          _errorLog("[%s] Failed to preprocess try node", __FUNCTION__);
+          return false;
+        }
+        _debugLog(_debug_tag, "[%s] handled try node successfully", __FUNCTION__);
+        break;
+      case DocNode::TYPE_HTML_COMMENT:
+        if (!_handleHtmlComment(list_iter)) {
+          _errorLog("[%s] Failed to preprocess try node", __FUNCTION__);
+          return false;
+        }
+        break;
+      case DocNode::TYPE_INCLUDE:
+        {
+          Stats::increment(Stats::N_INCLUDES);
+          const Attribute &src = list_iter->attr_list.front();
+          raw_url.assign(src.value, src.value_len);
+          _debugLog(_debug_tag, "[%s] Adding fetch request for url [%.*s]",
+              __FUNCTION__, raw_url.size(), raw_url.data());
+          hash_iter = _include_urls.find(raw_url);
+          if (hash_iter != _include_urls.end()) { // we have already processed this URL
+            _debugLog(_debug_tag, "[%s] URL [%.*s] already processed",
                 __FUNCTION__, raw_url.size(), raw_url.data());
-      hash_iter = _include_urls.find(raw_url);
-      if (hash_iter != _include_urls.end()) { // we have already processed this URL
-        _debugLog(_debug_tag, "[%s] URL [%.*s] already processed",
-                  __FUNCTION__, raw_url.size(), raw_url.data());
-        continue;
-      }
-      const string &expanded_url = _expression.expand(raw_url);
-      if (!expanded_url.size()) {
-        _errorLog("[%s] Couldn't expand raw URL [%.*s]", __FUNCTION__, raw_url.size(), raw_url.data());
-        Stats::increment(Stats::N_INCLUDE_ERRS);
-        continue;
-      }
+            continue;
+          }
+          const string &expanded_url = _expression.expand(raw_url);
+          if (!expanded_url.size()) {
+            _errorLog("[%s] Couldn't expand raw URL [%.*s]", __FUNCTION__, raw_url.size(), raw_url.data());
+            Stats::increment(Stats::N_INCLUDE_ERRS);
+            continue;
+          }
 
-      bool fetch=true;
-      FailureData* threadData;
-      /* FAILURE CACHE */
-      if((threadData=static_cast<FailureData*>(pthread_getspecific(threadKey))) == NULL){
-          threadData=new FailureData();  
-          if(pthread_setspecific(threadKey,threadData))
-          {
+          bool fetch=true;
+          FailureData* threadData;
+          /* FAILURE CACHE */
+          if((threadData=static_cast<FailureData*>(pthread_getspecific(threadKey))) == NULL){
+            threadData=new FailureData();
+            if(pthread_setspecific(threadKey,threadData))
+            {
               _errorLog("[%s] Unable to set the key", __FUNCTION__);
               abort();
-          }
-          _debugLog("plugin_esi_failureInfo", "[%s] Data is set for this thread [threadData]%p [threadID]%u [%.*s]", __FUNCTION__,threadData,pthread_self(),expanded_url.size(),expanded_url.data());
-      }else {
-       
-          _debugLog("plugin_esi_failureInfo", "[%s] URL request [%.*s] %u",
-                  __FUNCTION__, expanded_url.size(), expanded_url.data(),pthread_self());
-      
-          FailureData::iterator it =threadData->find(expanded_url);
-          FailureInfo* info;
-
-          if(it != threadData->end()) {
+            }
+            _debugLog("plugin_esi_failureInfo", "[%s] Data is set for this thread [threadData]%p [threadID]%u [%.*s]", __FUNCTION__,threadData,pthread_self(),expanded_url.size(),expanded_url.data());
+          }else {
+
+            _debugLog("plugin_esi_failureInfo", "[%s] URL request [%.*s] %u",
+                __FUNCTION__, expanded_url.size(), expanded_url.data(),pthread_self());
+
+            FailureData::iterator it =threadData->find(expanded_url);
+            FailureInfo* info;
+
+            if(it != threadData->end()) {
               info=it->second; 
               fetch=_reqAdded=info->isAttemptReq();
               _debugLog(_debug_tag,"[%s] Fetch result is %d",__FUNCTION__,fetch);
-        }
-      }
-     
-      if(fetch){
-          if (!_fetcher.addFetchRequest(expanded_url)) {
-            _errorLog("[%s] Couldn't add fetch request for URL [%.*s]", 
+            }
+          }
+
+          if(fetch){
+            if (!_fetcher.addFetchRequest(expanded_url)) {
+              _errorLog("[%s] Couldn't add fetch request for URL [%.*s]",
                   __FUNCTION__, raw_url.size(), raw_url.data());
-            Stats::increment(Stats::N_INCLUDE_ERRS);
+              Stats::increment(Stats::N_INCLUDE_ERRS);
+              continue;
+            }
+            _include_urls.insert(StringHash::value_type(raw_url, expanded_url));
+          }
+          else{
+            _debugLog("plugin_esi_failureInfo","[%s] Not adding fetch request for [%.*s]",__FUNCTION__,expanded_url.size(),expanded_url.data());
             continue;
           }
-          _include_urls.insert(StringHash::value_type(raw_url, expanded_url));
-      }
-      else{
-          _debugLog("plugin_esi_failureInfo","[%s] Not adding fetch request for [%.*s]",__FUNCTION__,expanded_url.size(),expanded_url.data());
-          continue;
-      }
-    } else if (list_iter->type == DocNode::TYPE_SPECIAL_INCLUDE) {
-      Stats::increment(Stats::N_SPCL_INCLUDES);
-      const Attribute &handler_attr = list_iter->attr_list.front();
-      string handler_id(handler_attr.value, handler_attr.value_len);
-      SpecialIncludeHandler *handler;
-      IncludeHandlerMap::const_iterator map_iter = _include_handlers.find(handler_id);
-      if (map_iter == _include_handlers.end()) {
-        handler = _handler_manager.getHandler(_esi_vars, _expression, _fetcher, handler_id);
-        if (!handler) {
-          _errorLog("[%s] Couldn't create handler with id [%s]", __FUNCTION__, handler_id.c_str());
-          Stats::increment(Stats::N_SPCL_INCLUDE_ERRS);
-          return false;
+          break;
         }
-        _include_handlers.insert(IncludeHandlerMap::value_type(handler_id, handler));
-        _debugLog(_debug_tag, "[%s] Created new special include handler object for id [%s]",
-                  __FUNCTION__, handler_id.c_str());
-      } else {
-        handler = map_iter->second;
-      }
-      int special_data_id = handler->handleInclude(list_iter->data, list_iter->data_len);
-      if (special_data_id == -1) {
-        _errorLog("[%s] Include handler [%s] couldn't process include with data [%.*s]",
-                  __FUNCTION__, handler_id.c_str(), list_iter->data_len, list_iter->data);
-        Stats::increment(Stats::N_SPCL_INCLUDE_ERRS);
-        return false;
-      }
-      // overloading this structure's members
-      // handler will be in value and include id will be in value_len of the structure
-      list_iter->attr_list.push_back(Attribute(INCLUDE_DATA_ID_ATTR, 0,
-                                               reinterpret_cast<const char *>(handler),
-                                               special_data_id));
-      _debugLog(_debug_tag, "[%s] Got id %d for special include at node %d from handler [%s]",
-                __FUNCTION__, special_data_id, n_prescanned_nodes + 1, handler_id.c_str());
+      case DocNode::TYPE_SPECIAL_INCLUDE:
+        {
+          Stats::increment(Stats::N_SPCL_INCLUDES);
+          const Attribute &handler_attr = list_iter->attr_list.front();
+          string handler_id(handler_attr.value, handler_attr.value_len);
+          SpecialIncludeHandler *handler;
+          IncludeHandlerMap::const_iterator map_iter = _include_handlers.find(handler_id);
+          if (map_iter == _include_handlers.end()) {
+            handler = _handler_manager.getHandler(_esi_vars, _expression, _fetcher, handler_id);
+            if (!handler) {
+              _errorLog("[%s] Couldn't create handler with id [%s]", __FUNCTION__, handler_id.c_str());
+              Stats::increment(Stats::N_SPCL_INCLUDE_ERRS);
+              return false;
+            }
+            _include_handlers.insert(IncludeHandlerMap::value_type(handler_id, handler));
+            _debugLog(_debug_tag, "[%s] Created new special include handler object for id [%s]",
+                __FUNCTION__, handler_id.c_str());
+          } else {
+            handler = map_iter->second;
+          }
+          int special_data_id = handler->handleInclude(list_iter->data, list_iter->data_len);
+          if (special_data_id == -1) {
+            _errorLog("[%s] Include handler [%s] couldn't process include with data [%.*s]",
+                __FUNCTION__, handler_id.c_str(), list_iter->data_len, list_iter->data);
+            Stats::increment(Stats::N_SPCL_INCLUDE_ERRS);
+            return false;
+          }
+          // overloading this structure's members
+          // handler will be in value and include id will be in value_len of the structure
+          list_iter->attr_list.push_back(Attribute(INCLUDE_DATA_ID_ATTR, 0,
+                reinterpret_cast<const char *>(handler),
+                special_data_id));
+          _debugLog(_debug_tag, "[%s] Got id %d for special include at node %d from handler [%s]",
+              __FUNCTION__, special_data_id, n_prescanned_nodes + 1, handler_id.c_str());
+        }
+        break;
+      default:
+        break;
     }
   }
+
   return true;
 }
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/EsiProcessor.h
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/EsiProcessor.h b/plugins/experimental/esi/lib/EsiProcessor.h
index eb40a33..eeae62a 100644
--- a/plugins/experimental/esi/lib/EsiProcessor.h
+++ b/plugins/experimental/esi/lib/EsiProcessor.h
@@ -27,9 +27,9 @@
 #include <string>
 #include <map>
 #include<pthread.h>
-#include "ComponentBase.h"
-#include "StringHash.h"
-#include "DocNode.h"
+#include "lib/ComponentBase.h"
+#include "lib/StringHash.h"
+#include "lib/DocNode.h"
 #include "EsiParser.h"
 #include "HttpDataFetcher.h"
 #include "Variables.h"

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/lib/FailureInfo.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/lib/FailureInfo.cc b/plugins/experimental/esi/lib/FailureInfo.cc
index 803f337..24954ab 100644
--- a/plugins/experimental/esi/lib/FailureInfo.cc
+++ b/plugins/experimental/esi/lib/FailureInfo.cc
@@ -59,7 +59,7 @@ void FailureInfo::registerSuccFail(bool isSuccess)
    if(isSuccess)
    {
        _statistics[_windowMarker].second++;
-   } 
+   }
    
    else
    {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/plugin.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/plugin.cc b/plugins/experimental/esi/plugin.cc
index 4b89623..bc3b4f1 100644
--- a/plugins/experimental/esi/plugin.cc
+++ b/plugins/experimental/esi/plugin.cc
@@ -38,13 +38,13 @@
 #include "ts/experimental.h"
 #include <ts/remap.h>
 
+#include "lib/Utils.h"
+#include "lib/gzip.h"
 #include "EsiProcessor.h"
 #include "HttpDataFetcher.h"
-#include "Utils.h"
 #include "HandlerManager.h"
 #include "serverIntercept.h"
 #include "Stats.h"
-#include "gzip.h"
 #include "HttpDataFetcherImpl.h"
 #include "FailureInfo.h"
 using std::string;
@@ -1553,6 +1553,7 @@ static int esiPluginInit(int argc, const char *argv[], struct OptionInfo *pOptio
     bKeySet = true;
     if ((result=pthread_key_create(&threadKey, NULL)) != 0) {
       TSError("[%s] Could not create key", __FUNCTION__);
+      TSDebug(DEBUG_TAG, "[%s] Could not create key", __FUNCTION__);
     }
   }
   else {
@@ -1600,12 +1601,14 @@ TSReturnCode
 TSRemapInit(TSRemapInterface* api_info, char *errbuf, int errbuf_size)
 {
   if (!api_info) {
-    TSstrlcpy(errbuf, "[TSRemapInit] - Invalid TSRemapInterface argument", errbuf_size);
+    snprintf(errbuf, errbuf_size, "[TSRemapInit] - Invalid TSRemapInterface argument");
+    TSError("[TSRemapInit] - Invalid TSRemapInterface argument");
     return TS_ERROR;
   }
 
   if (api_info->size < sizeof(TSRemapInterface)) {
-    TSstrlcpy(errbuf, "[TSRemapInit] - Incorrect size of TSRemapInterface structure", errbuf_size);
+    snprintf(errbuf, errbuf_size, "[TSRemapInit] - Incorrect size of TSRemapInterface structure");
+    TSError("[TSRemapInit] - Incorrect size of TSRemapInterface structure");
     return TS_ERROR;
   }
 
@@ -1616,8 +1619,10 @@ TSRemapInit(TSRemapInterface* api_info, char *errbuf, int errbuf_size)
 TSReturnCode
 TSRemapNewInstance(int argc, char* argv[], void** ih, char* errbuf, int errbuf_size)
 {
-  if (argc < 3) {
-    TSError("Unable to create remap instance, need configuration file");
+  if (argc < 2) {
+    snprintf(errbuf, errbuf_size, "Unable to create remap instance, " \
+        "argc: %d < 2", argc);
+    TSError("Unable to create remap instance! argc: %d < 2", argc);
     return TS_ERROR;
   }
 
@@ -1632,6 +1637,7 @@ TSRemapNewInstance(int argc, char* argv[], void** ih, char* errbuf, int errbuf_s
 
   struct OptionInfo *pOptionInfo = (struct OptionInfo *)TSmalloc(sizeof(struct OptionInfo));
   if (pOptionInfo == NULL) {
+    snprintf(errbuf, errbuf_size, "malloc %d bytes fail", (int)sizeof(struct OptionInfo));
     TSError("[%s] malloc %d bytes fail", __FUNCTION__, (int)sizeof(struct OptionInfo));
     return TS_ERROR;
   }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/3f82a9be/plugins/experimental/esi/test/sampleProb.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/test/sampleProb.cc b/plugins/experimental/esi/test/sampleProb.cc
index 15fe859..a303e0d 100644
--- a/plugins/experimental/esi/test/sampleProb.cc
+++ b/plugins/experimental/esi/test/sampleProb.cc
@@ -123,7 +123,7 @@ void registerSuccFail(string URL,FailureData& data,bool isSuccess)
    if(isSuccess)
    {
        passFail[marker].second++;
-   } 
+   }
    
    else
    {