| 146 | } |
| 147 | |
| 148 | bool |
| 149 | HttpDataFetcherImpl::handleFetchEvent(TSEvent event, void *edata) |
| 150 | { |
| 151 | int base_event_id; |
| 152 | if (!_isFetchEvent(event, base_event_id)) { |
| 153 | TSError("[HttpDataFetcherImpl][%s] Event %d is not a fetch event", __FUNCTION__, event); |
| 154 | return false; |
| 155 | } |
| 156 | |
| 157 | UrlToContentMap::iterator &req_entry = _page_entry_lookup[base_event_id]; |
| 158 | const string &req_str = req_entry->first; |
| 159 | RequestData &req_data = req_entry->second; |
| 160 | |
| 161 | if (req_data.complete) { |
| 162 | // can only happen if there's a bug in this or fetch API code |
| 163 | TSError("[HttpDataFetcherImpl][%s] URL [%s] already completed; Retaining original data", __FUNCTION__, req_str.c_str()); |
| 164 | return false; |
| 165 | } |
| 166 | |
| 167 | --_n_pending_requests; |
| 168 | req_data.complete = true; |
| 169 | |
| 170 | int event_id = (static_cast<int>(event) - FETCH_EVENT_ID_BASE) % 3; |
| 171 | if (event_id != 0) { // failure or timeout |
| 172 | TSError("[HttpDataFetcherImpl][%s] Received failure/timeout event id %d for request [%s]", __FUNCTION__, event_id, |
| 173 | req_str.data()); |
| 174 | return true; |
| 175 | } |
| 176 | |
| 177 | int page_data_len; |
| 178 | const char *page_data = TSFetchRespGet(static_cast<TSHttpTxn>(edata), &page_data_len); |
| 179 | req_data.response.assign(page_data, page_data_len); |
| 180 | bool valid_data_received = false; |
| 181 | const char *startptr = req_data.response.data(), *endptr = startptr + page_data_len; |
| 182 | |
| 183 | req_data.bufp = TSMBufferCreate(); |
| 184 | req_data.hdr_loc = TSHttpHdrCreate(req_data.bufp); |
| 185 | TSHttpHdrTypeSet(req_data.bufp, req_data.hdr_loc, TS_HTTP_TYPE_RESPONSE); |
| 186 | TSHttpParserClear(_http_parser); |
| 187 | |
| 188 | if (TSHttpHdrParseResp(_http_parser, req_data.bufp, req_data.hdr_loc, &startptr, endptr) == TS_PARSE_DONE) { |
| 189 | req_data.resp_status = TSHttpHdrStatusGet(req_data.bufp, req_data.hdr_loc); |
| 190 | valid_data_received = true; |
| 191 | if (req_data.resp_status == TS_HTTP_STATUS_OK) { |
| 192 | req_data.body_len = endptr - startptr; |
| 193 | req_data.body = startptr; |
| 194 | DBG("[%s] Inserted page data of size %d starting with [%.6s] for request [%s]", __FUNCTION__, req_data.body_len, |
| 195 | (req_data.body_len ? req_data.body : "(null)"), req_str.c_str()); |
| 196 | |
| 197 | if (_checkHeaderValue(req_data.bufp, req_data.hdr_loc, TS_MIME_FIELD_CONTENT_ENCODING, TS_MIME_LEN_CONTENT_ENCODING, |
| 198 | TS_HTTP_VALUE_GZIP, TS_HTTP_LEN_GZIP, false)) { |
| 199 | BufferList buf_list; |
| 200 | req_data.raw_response = ""; |
| 201 | if (gunzip(req_data.body, req_data.body_len, buf_list)) { |
| 202 | for (BufferList::iterator iter = buf_list.begin(); iter != buf_list.end(); ++iter) { |
| 203 | req_data.raw_response.append(iter->data(), iter->size()); |
| 204 | } |
| 205 | } else { |
no test coverage detected