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();
 

Reply via email to