| 276 | } |
| 277 | |
| 278 | EsiProcessor::ReturnCode |
| 279 | EsiProcessor::process(const char *&data, int &data_len) |
| 280 | { |
| 281 | if (_curr_state == ERRORED) { |
| 282 | return FAILURE; |
| 283 | } |
| 284 | if (_curr_state != WAITING_TO_PROCESS) { |
| 285 | TSError("[%s] Processor has to finish parsing via completeParse() before process() call", __FUNCTION__); |
| 286 | return FAILURE; |
| 287 | } |
| 288 | DocNodeList::iterator node_iter, iter; |
| 289 | bool attempt_succeeded; |
| 290 | TryBlockList::iterator try_iter = _try_blocks.begin(); |
| 291 | for (int i = 0; i < _n_try_blocks_processed; ++i, ++try_iter) { |
| 292 | ; |
| 293 | } |
| 294 | for (; _n_try_blocks_processed < static_cast<int>(_try_blocks.size()); ++try_iter) { |
| 295 | ++_n_try_blocks_processed; |
| 296 | attempt_succeeded = true; |
| 297 | for (node_iter = try_iter->attempt_nodes.begin(); node_iter != try_iter->attempt_nodes.end(); ++node_iter) { |
| 298 | if ((node_iter->type == DocNode::TYPE_INCLUDE) || (node_iter->type == DocNode::TYPE_SPECIAL_INCLUDE)) { |
| 299 | const Attribute &url = (*node_iter).attr_list.front(); |
| 300 | string raw_url(url.value, url.value_len); |
| 301 | if (!_getIncludeData(*node_iter)) { |
| 302 | attempt_succeeded = false; |
| 303 | TSError("[%s] attempt section errored; due to url [%s]", __FUNCTION__, raw_url.c_str()); |
| 304 | break; |
| 305 | } |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | if (attempt_succeeded) { |
| 310 | DBG("[%s] attempt section succeeded; using attempt section", __FUNCTION__); |
| 311 | _node_list.splice(try_iter->pos, try_iter->attempt_nodes); |
| 312 | } else { |
| 313 | DBG("[%s] attempt section errored; trying except section", __FUNCTION__); |
| 314 | int n_prescanned_nodes = 0; |
| 315 | if (!_preprocess(try_iter->except_nodes, n_prescanned_nodes)) { |
| 316 | TSError("[%s] Failed to preprocess except nodes", __FUNCTION__); |
| 317 | stop(); |
| 318 | return FAILURE; |
| 319 | } |
| 320 | _node_list.splice(try_iter->pos, try_iter->except_nodes); |
| 321 | if (_fetcher.getNumPendingRequests()) { |
| 322 | DBG("[%s] New fetch requests were triggered by except block; " |
| 323 | "Returning NEED_MORE_DATA...", |
| 324 | __FUNCTION__); |
| 325 | return NEED_MORE_DATA; |
| 326 | } |
| 327 | } |
| 328 | } |
| 329 | _curr_state = PROCESSED; |
| 330 | for (node_iter = _node_list.begin(); node_iter != _node_list.end(); ++node_iter) { |
| 331 | DocNode &doc_node = *node_iter; // handy reference |
| 332 | DBG("[%s] Processing ESI node [%s] with data of size %d starting with [%.10s...]", __FUNCTION__, |
| 333 | DocNode::type_names_[doc_node.type], doc_node.data_len, (doc_node.data_len ? doc_node.data : "(null)")); |
| 334 | if (doc_node.type == DocNode::TYPE_PRE) { |
| 335 | // just copy the data |