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 2012/10/26 10:20:23 UTC
[1/2] git commit: TS-1534: ESI plugin deals HTTP HEAD method properly.
Updated Branches:
refs/heads/master f72392bea -> 2167d53d3
TS-1534: ESI plugin deals HTTP HEAD method properly.
ESI plugin only support HEAD, GET and POST methods.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/ce5b6f52
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/ce5b6f52
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/ce5b6f52
Branch: refs/heads/master
Commit: ce5b6f52b2a233a3af1d0c2ef860937c02cddce5
Parents: f72392b
Author: Yu Qing <zh...@taobao.com>
Authored: Thu Oct 25 09:51:36 2012 +0800
Committer: Zhao Yongming <mi...@gmail.com>
Committed: Fri Oct 26 16:19:53 2012 +0800
----------------------------------------------------------------------
plugins/experimental/esi/plugin.cc | 82 ++++++++++++++++++++++--------
1 files changed, 60 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce5b6f52/plugins/experimental/esi/plugin.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/esi/plugin.cc b/plugins/experimental/esi/plugin.cc
index 70ecec1..1b1444d 100644
--- a/plugins/experimental/esi/plugin.cc
+++ b/plugins/experimental/esi/plugin.cc
@@ -96,6 +96,7 @@ struct ContData
bool xform_closed;
bool intercept_header;
bool cache_txn;
+ bool head_only;
#ifdef ESI_PACKED_NODE_SUPPORT
bool os_response_cacheable;
@@ -110,7 +111,7 @@ struct ContData
input_type(DATA_TYPE_RAW_ESI), packed_node_list(""),
gzipped_data(""), gzip_output(false),
initialized(false), xform_closed(false),
- intercept_header(false), cache_txn(false)
+ intercept_header(false), cache_txn(false), head_only(false)
#ifdef ESI_PACKED_NODE_SUPPORT
, os_response_cacheable(true)
#endif
@@ -415,13 +416,13 @@ ContData::getServerState() {
if (cache_txn) {
if (intercept_header) {
input_type = DATA_TYPE_PACKED_ESI;
- } else {
+ return;
+ } else if (TSHttpTxnCachedRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
+ TSError("[%s] Could not get server response; set input type to RAW_ESI", __FUNCTION__);
input_type = DATA_TYPE_RAW_ESI;
+ return;
}
- return;
- }
-
- if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
+ } else if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
TSError("[%s] Could not get server response; set input type to RAW_ESI", __FUNCTION__);
input_type = DATA_TYPE_RAW_ESI;
return;
@@ -435,7 +436,9 @@ ContData::getServerState() {
}
#ifdef ESI_PACKED_NODE_SUPPORT
- fillPostHeader(bufp, hdr_loc);
+ if (!cache_txn && !head_only) {
+ fillPostHeader(bufp, hdr_loc);
+ }
#endif
TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
@@ -693,7 +696,7 @@ transformData(TSCont contp)
}
if (cont_data->esi_proc->completeParse()) {
#ifdef ESI_PACKED_NODE_SUPPORT
- if (cont_data->os_response_cacheable && !cont_data->cache_txn) {
+ if (cont_data->os_response_cacheable && !cont_data->cache_txn && !cont_data->head_only) {
cacheNodeList(cont_data);
}
#endif
@@ -901,6 +904,7 @@ lShutdown:
struct RespHdrModData {
bool cache_txn;
bool gzip_encoding;
+ bool head_only;
};
static void
@@ -961,7 +965,12 @@ modifyResponseHeader(TSCont contp, TSEvent event, void *edata) {
} else if (Utils::areEqual(name, name_len, MIME_FIELD_XESI, MIME_FIELD_XESI_LEN)) {
destroy_header = true;
} else if ((name_len > HEADER_MASK_PREFIX_SIZE) &&
- (strncmp(name, HEADER_MASK_PREFIX, HEADER_MASK_PREFIX_SIZE) == 0)) {
+ (strncmp(name, HEADER_MASK_PREFIX, HEADER_MASK_PREFIX_SIZE) == 0))
+ {
+ destroy_header = true;
+ } else if (mod_data->head_only && Utils::areEqual(name, name_len,
+ TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH))
+ {
destroy_header = true;
} else {
int n_field_values = TSMimeHdrFieldValuesCount(bufp, hdr_loc, field_loc);
@@ -1121,7 +1130,7 @@ maskOsCacheHeaders(TSHttpTxn txnp) {
#endif
static bool
-isTxnTransformable(TSHttpTxn txnp, bool is_cache_txn, bool * intercept_header) {
+isTxnTransformable(TSHttpTxn txnp, bool is_cache_txn, bool * intercept_header, bool * head_only) {
// We are only interested in transforming "200 OK" responses with a
// Content-Type: text/ header and with X-Esi header
@@ -1131,6 +1140,32 @@ isTxnTransformable(TSHttpTxn txnp, bool is_cache_txn, bool * intercept_header) {
TSReturnCode header_obtained;
bool retval = false;
+ if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
+ TSError("[%s] Couldn't get txn header", __FUNCTION__);
+ return false;
+ }
+
+ int method_len;
+ const char *method;
+ method = TSHttpHdrMethodGet(bufp, hdr_loc, &method_len);
+ if (method == NULL) {
+ TSError("[%s] Couldn't get method", __FUNCTION__);
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+ return false;
+ }
+
+ if (method_len >= TS_HTTP_LEN_HEAD && memcmp(method, TS_HTTP_METHOD_HEAD, TS_HTTP_LEN_HEAD) == 0) {
+ *head_only = true;
+ }
+ else if (!(((method_len >= TS_HTTP_LEN_POST && memcmp(method, TS_HTTP_METHOD_POST, TS_HTTP_LEN_POST) == 0)) ||
+ ((method_len >= TS_HTTP_LEN_GET && memcmp(method, TS_HTTP_METHOD_GET, TS_HTTP_LEN_GET) == 0))))
+ {
+ TSDebug(DEBUG_TAG, "[%s] method %.*s will be ignored", __FUNCTION__, method_len, method);
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+ return false;
+ }
+ TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+
header_obtained = is_cache_txn ? TSHttpTxnCachedRespGet(txnp, &bufp, &hdr_loc) :
TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc);
if (header_obtained != TS_SUCCESS) {
@@ -1180,7 +1215,7 @@ isTxnTransformable(TSHttpTxn txnp, bool is_cache_txn, bool * intercept_header) {
}
static bool
-isCacheObjTransformable(TSHttpTxn txnp, bool * intercept_header) {
+isCacheObjTransformable(TSHttpTxn txnp, bool * intercept_header, bool * head_only) {
int obj_status;
if (TSHttpTxnCacheLookupStatusGet(txnp, &obj_status) == TS_ERROR) {
TSError("[%s] Couldn't get cache status of object", __FUNCTION__);
@@ -1195,7 +1230,7 @@ isCacheObjTransformable(TSHttpTxn txnp, bool * intercept_header) {
*/
TSDebug(DEBUG_TAG, "[%s] doc found in cache, will add transformation", __FUNCTION__);
- return isTxnTransformable(txnp, true, intercept_header);
+ return isTxnTransformable(txnp, true, intercept_header, head_only);
}
TSDebug(DEBUG_TAG, "[%s] cache object's status is %d; not transformable",
__FUNCTION__, obj_status);
@@ -1259,7 +1294,7 @@ checkForCacheHeader(const char *name, int name_len, const char *value, int value
}
static bool
-addSendResponseHeaderHook(TSHttpTxn txnp, bool cache_txn, bool gzip_encoding) {
+addSendResponseHeaderHook(TSHttpTxn txnp, const ContData * src_cont_data) {
TSCont contp = TSContCreate(modifyResponseHeader, NULL);
if (!contp) {
TSError("[%s] Could not create continuation", __FUNCTION__);
@@ -1267,14 +1302,15 @@ addSendResponseHeaderHook(TSHttpTxn txnp, bool cache_txn, bool gzip_encoding) {
}
TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
RespHdrModData *cont_data = new RespHdrModData();
- cont_data->cache_txn = cache_txn;
- cont_data->gzip_encoding = gzip_encoding;
+ cont_data->cache_txn = src_cont_data->cache_txn;
+ cont_data->head_only = src_cont_data->head_only;
+ cont_data->gzip_encoding = src_cont_data->gzip_output;
TSContDataSet(contp, cont_data);
return true;
}
static bool
-addTransform(TSHttpTxn txnp, const bool processing_os_response, const bool intercept_header) {
+addTransform(TSHttpTxn txnp, const bool processing_os_response, const bool intercept_header, const bool head_only) {
TSCont contp = 0;
ContData *cont_data = 0;
@@ -1289,6 +1325,7 @@ addTransform(TSHttpTxn txnp, const bool processing_os_response, const bool inter
cont_data->cache_txn = !processing_os_response;
cont_data->intercept_header = intercept_header;
+ cont_data->head_only = head_only;
cont_data->getClientState();
cont_data->getServerState();
@@ -1306,7 +1343,7 @@ addTransform(TSHttpTxn txnp, const bool processing_os_response, const bool inter
TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, contp);
- if (!addSendResponseHeaderHook(txnp, cont_data->cache_txn, cont_data->gzip_output)) {
+ if (!addSendResponseHeaderHook(txnp, cont_data)) {
TSError("[%s] Couldn't add send response header hook", __FUNCTION__);
goto lFail;
}
@@ -1336,6 +1373,7 @@ static int
globalHookHandler(TSCont contp, TSEvent event, void *edata) {
TSHttpTxn txnp = (TSHttpTxn) edata;
bool intercept_header = false;
+ bool head_only = false;
bool intercept_req = isInterceptRequest(txnp);
switch (event) {
@@ -1358,15 +1396,15 @@ globalHookHandler(TSCont contp, TSEvent event, void *edata) {
if (event == TS_EVENT_HTTP_READ_RESPONSE_HDR) {
bool mask_cache_headers = false;
TSDebug(DEBUG_TAG, "[%s] handling read response header event...", __FUNCTION__);
- if (isCacheObjTransformable(txnp, &intercept_header)) {
+ if (isCacheObjTransformable(txnp, &intercept_header, &head_only)) {
// transformable cache object will definitely have a
// transformation already as cache_lookup_complete would
// have been processed before this
TSDebug(DEBUG_TAG, "[%s] xform should already have been added on cache lookup. Not adding now",
__FUNCTION__);
mask_cache_headers = true;
- } else if (isTxnTransformable(txnp, false, &intercept_header)) {
- addTransform(txnp, true, intercept_header);
+ } else if (isTxnTransformable(txnp, false, &intercept_header, &head_only)) {
+ addTransform(txnp, true, intercept_header, head_only);
Stats::increment(Stats::N_OS_DOCS);
mask_cache_headers = true;
}
@@ -1380,11 +1418,11 @@ globalHookHandler(TSCont contp, TSEvent event, void *edata) {
}
} else {
TSDebug(DEBUG_TAG, "[%s] handling cache lookup complete event...", __FUNCTION__);
- if (isCacheObjTransformable(txnp, &intercept_header)) {
+ if (isCacheObjTransformable(txnp, &intercept_header, &head_only)) {
// we make the assumption above that a transformable cache
// object would already have a tranformation. We should revisit
// that assumption in case we change the statement below
- addTransform(txnp, false, intercept_header);
+ addTransform(txnp, false, intercept_header, head_only);
Stats::increment(Stats::N_CACHE_DOCS);
}
}