TS-1062: Make TSFetchUrl handle chunked encoding automatically Signed-off-by: Yunkai Zhang <qiushu....@taobao.com>
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/6a5f55ab Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/6a5f55ab Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/6a5f55ab Branch: refs/heads/master Commit: 6a5f55abd2088e02e615639b182b757fbdc0590e Parents: 8a0bee4 Author: Yunkai Zhang <qiushu....@taobao.com> Authored: Mon Mar 3 21:44:18 2014 +0800 Committer: Yunkai Zhang <qiushu....@taobao.com> Committed: Wed Mar 12 11:02:15 2014 +0800 ---------------------------------------------------------------------- proxy/FetchSM.cc | 92 ++++++++++++++++++++++++++++++++++----------------- proxy/FetchSM.h | 2 +- 2 files changed, 63 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6a5f55ab/proxy/FetchSM.cc ---------------------------------------------------------------------- diff --git a/proxy/FetchSM.cc b/proxy/FetchSM.cc index 77d3197..b869837 100644 --- a/proxy/FetchSM.cc +++ b/proxy/FetchSM.cc @@ -289,43 +289,81 @@ out: void FetchSM::get_info_from_buffer(IOBufferReader *the_reader) { - char *info; -// char *info_start; - + char *buf, *info; int64_t read_avail, read_done; IOBufferBlock *blk; - char *buf; + IOBufferReader *reader = the_reader; - if (!the_reader) + if (!reader) { + client_bytes = 0; return ; + } - read_avail = the_reader->read_avail(); + read_avail = reader->read_avail(); Debug(DEBUG_TAG, "[%s] total avail %" PRId64 , __FUNCTION__, read_avail); - //size_t hdr_size = _headers.size(); - //info = (char *)ats_malloc(sizeof(char) * (read_avail+1) + hdr_size); + if (!read_avail) { + client_bytes = 0; + return; + } + info = (char *)ats_malloc(sizeof(char) * (read_avail+1)); client_response = info; - //ink_strlcpy(info, _headers.data(), sizeof(char) * (read_avail+1)); - //info += hdr_size; + if (!check_chunked()) { + /* Read the data out of the reader */ + while (read_avail > 0) { + if (reader->block != NULL) + reader->skip_empty_blocks(); + blk = reader->block; + + // This is the equivalent of TSIOBufferBlockReadStart() + buf = blk->start() + reader->start_offset; + read_done = blk->read_avail() - reader->start_offset; + + if (read_done > 0) { + memcpy(info, buf, read_done); + reader->consume(read_done); + read_avail -= read_done; + info += read_done; + client_bytes += read_done; + } + } + client_response[client_bytes] = '\0'; + return; + } - /* Read the data out of the reader */ - while (read_avail > 0) { - if (the_reader->block != NULL) - the_reader->skip_empty_blocks(); - blk = the_reader->block; + reader = chunked_handler.dechunked_reader; + do { + if (chunked_handler.state == ChunkedHandler::CHUNK_FLOW_CONTROL) { + chunked_handler.state = ChunkedHandler::CHUNK_READ_SIZE_START; + } - // This is the equivalent of TSIOBufferBlockReadStart() - buf = blk->start() + the_reader->start_offset; - read_done = blk->read_avail() - the_reader->start_offset; + if (!dechunk_body()) + break; - if (read_done > 0) { - memcpy(info, buf, read_done); - the_reader->consume(read_done); - read_avail -= read_done; - info += read_done; + /* Read the data out of the reader */ + read_avail = reader->read_avail(); + while (read_avail > 0) { + if (reader->block != NULL) + reader->skip_empty_blocks(); + blk = reader->block; + + // This is the equivalent of TSIOBufferBlockReadStart() + buf = blk->start() + reader->start_offset; + read_done = blk->read_avail() - reader->start_offset; + + if (read_done > 0) { + memcpy(info, buf, read_done); + reader->consume(read_done); + read_avail -= read_done; + info += read_done; + client_bytes += read_done; + } } - } + } while (chunked_handler.state == ChunkedHandler::CHUNK_FLOW_CONTROL); + + client_response[client_bytes] = '\0'; + return; } void @@ -360,13 +398,7 @@ FetchSM::process_fetch_read(int event) if (fetch_flags & TS_FETCH_FLAGS_STREAM) return InvokePluginExt(); if(callback_options == AFTER_HEADER || callback_options == AFTER_BODY) { - bytes = resp_reader->read_avail(); get_info_from_buffer(resp_reader); - Debug(DEBUG_TAG, "[%s] number of bytes %"PRId64"", __FUNCTION__, bytes); - if(client_response!=NULL) - client_response[bytes] = '\0'; - Debug(DEBUG_TAG, "[%s] Completed data fetch of size %"PRId64", notifying caller", __FUNCTION__, bytes); - client_bytes = bytes; InvokePlugin( callback_events.success_event_id, (void *) this); } Debug(DEBUG_TAG, "[%s] received EOS", __FUNCTION__); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6a5f55ab/proxy/FetchSM.h ---------------------------------------------------------------------- diff --git a/proxy/FetchSM.h b/proxy/FetchSM.h index 4a07a72..0de5d96 100644 --- a/proxy/FetchSM.h +++ b/proxy/FetchSM.h @@ -76,7 +76,7 @@ public: callback_events = events; callback_options = options; _addr.assign(addr); - fetch_flags = TS_FETCH_FLAGS_NONE; + fetch_flags = TS_FETCH_FLAGS_DECHUNK; writeRequest(headers,length); mutex = new_ProxyMutex();