You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2015/04/20 01:34:33 UTC

trafficserver git commit: TS-974: Additional fixes. Cherry-pick from 5.2.x version.

Repository: trafficserver
Updated Branches:
  refs/heads/ts-974-5-3-x 799a83bb4 -> f82fd704f


TS-974: Additional fixes. Cherry-pick from 5.2.x version.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/f82fd704
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/f82fd704
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/f82fd704

Branch: refs/heads/ts-974-5-3-x
Commit: f82fd704fc0037968e340a844114a703cd50f3a5
Parents: 799a83b
Author: Alan M. Carroll <so...@yahoo-inc.com>
Authored: Sun Apr 19 12:37:19 2015 -0500
Committer: Alan M. Carroll <am...@apache.org>
Committed: Sun Apr 19 18:33:36 2015 -0500

----------------------------------------------------------------------
 iocore/cache/Cache.cc           |   6 +-
 iocore/cache/CacheRead.cc       |   8 +-
 iocore/cache/CacheWrite.cc      |  18 ++--
 iocore/cache/I_Cache.h          |   5 +-
 iocore/cache/P_CacheInternal.h  |   4 +-
 iocore/cluster/P_ClusterCache.h |   1 -
 proxy/hdrs/HTTP.cc              |   2 +
 proxy/http/HttpSM.cc            | 138 ++++++++++++++---------------
 proxy/http/HttpTransact.cc      | 167 +++++++++++++++++++----------------
 proxy/http/HttpTransact.h       |   5 +-
 proxy/http/HttpTunnel.cc        |  14 +--
 11 files changed, 186 insertions(+), 182 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cache/Cache.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
index 78f8d14..c685c11 100644
--- a/iocore/cache/Cache.cc
+++ b/iocore/cache/Cache.cc
@@ -509,10 +509,10 @@ bool CacheVC::set_pin_in_cache(time_t time_pin)
 }
 
 bool
-CacheVC::get_uncached(HTTPRangeSpec& result)
+CacheVC::get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result)
 {
-  HTTPRangeSpec::Range r = od ? write_vector->get_uncached_hull(earliest_key, resp_range.getRangeSpec())
-    : alternate.get_uncached_hull(resp_range.getRangeSpec())
+  HTTPRangeSpec::Range r = od ? write_vector->get_uncached_hull(earliest_key, req)
+    : alternate.get_uncached_hull(req)
     ;
   if (r.isValid()) {
     result.add(r);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cache/CacheRead.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/CacheRead.cc b/iocore/cache/CacheRead.cc
index 6a41267..8c49076 100644
--- a/iocore/cache/CacheRead.cc
+++ b/iocore/cache/CacheRead.cc
@@ -105,6 +105,9 @@ Cache::open_read(Continuation* cont, CacheVConnection* vc, HTTPHdr* client_reque
 
     c->vol = write_vc->vol;
     c->first_key = write_vc->first_key;
+    // [amc] Need to fix this as it's pointless. In general @a earliest_key in the write VC
+    // won't be the correct value - it's randomly generated and for a partial fill won't be
+    // set to the actual alternate value until later (in @c set_http_info).
     c->earliest_key = c->key = write_vc->earliest_key;
     c->vio.op = VIO::READ;
     c->base_stat = cache_read_active_stat;
@@ -257,7 +260,7 @@ CacheVC::openReadChooseWriter(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSE
 //  intptr_t err = ECACHE_DOC_BUSY;
 //  CacheVC *w = NULL;
 
-  ink_assert(vol->mutex->thread_holding == mutex->thread_holding && write_vc == NULL);
+  ink_assert(od->mutex->thread_holding == mutex->thread_holding && write_vc == NULL);
 
   if (frag_type != CACHE_FRAG_TYPE_HTTP) {
     ink_release_assert(! "[amc] Fix reader from writer for non-HTTP");
@@ -348,8 +351,9 @@ CacheVC::openReadFromWriter(int event, Event *e)
 
   MUTEX_RELEASE(lock); // we have the OD lock now, don't need the vol lock.
 
-  if (write_vc && CACHE_ALT_INDEX_DEFAULT != (alternate_index = get_alternate_index(&(od->vector), earliest_key))) {
+  if (write_vc && CACHE_ALT_INDEX_DEFAULT != (alternate_index = get_alternate_index(&(od->vector), write_vc->earliest_key))) {
     alternate.copy_shallow(od->vector.get(alternate_index));
+    key = earliest_key = alternate.object_key_get();
     MUTEX_RELEASE(lock_od);
     SET_HANDLER(&CacheVC::openReadStartEarliest);
     return openReadStartEarliest(event, e);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cache/CacheWrite.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/CacheWrite.cc b/iocore/cache/CacheWrite.cc
index 18db8c1..f6ff4d4 100644
--- a/iocore/cache/CacheWrite.cc
+++ b/iocore/cache/CacheWrite.cc
@@ -1377,9 +1377,9 @@ CacheProcessor::get_fixed_fragment_size() const {
 
 
 Action*
-CacheVC::do_init_write()
+CacheVC::do_write_init()
 {
-  Debug("amc", "[do_init_write] vc=%p", this);
+  Debug("amc", "[do_write_init] vc=%p", this);
   SET_CONTINUATION_HANDLER(this, &CacheVC::openWriteInit);
   return EVENT_DONE == this->openWriteInit(EVENT_IMMEDIATE, 0) ? ACTION_RESULT_DONE : &_action;
 }
@@ -1398,7 +1398,11 @@ CacheVC::openWriteInit(int eid, Event* event)
     }
 
     // If we're not already in the alt vector, insert.
-    if (-1 == (alternate_index = get_alternate_index(write_vector, first_key))) {
+    if (earliest_key != alternate.object_key_get()) {
+      Debug("amc", "[CacheVC::openWriteInit] updating earliest key from alternate");
+      alternate.object_key_get(&earliest_key);
+    }
+    if (-1 == (alternate_index = get_alternate_index(write_vector, earliest_key))) {
       alternate_index = write_vector->insert(&alternate);
     }
     // mark us as an writer.
@@ -1419,6 +1423,7 @@ CacheVC::openWriteInit(int eid, Event* event)
 //  key = alternate.get_frag_key_of(write_pos);
   SET_HANDLER(&CacheVC::openWriteMain);
   return openWriteMain(eid, event);
+//  return callcont(CACHE_EVENT_OPEN_WRITE);
 //  return EVENT_DONE;
 }
 
@@ -1694,7 +1699,8 @@ Lsuccess:
   if (_action.cancelled)
     goto Lcancel;
   SET_HANDLER(&CacheVC::openWriteInit);
-  return this->openWriteInit(EVENT_IMMEDIATE, 0);
+  return callcont(CACHE_EVENT_OPEN_WRITE);
+//  return this->openWriteInit(EVENT_IMMEDIATE, 0);
 
 Lfailure:
   CACHE_INCREMENT_DYN_STAT(base_stat + CACHE_STAT_FAILURE);
@@ -1794,6 +1800,7 @@ Cache::open_write(Continuation *cont, CacheKey *key, CacheFragType frag_type, in
     SET_CONTINUATION_HANDLER(c, &CacheVC::openWriteInit);
     c->callcont(CACHE_EVENT_OPEN_WRITE);
     return ACTION_RESULT_DONE;
+//    return c->do_write_init();
   } else {
     SET_CONTINUATION_HANDLER(c, &CacheVC::openWriteOverwrite);
     if (c->openWriteOverwrite(EVENT_IMMEDIATE, 0) == EVENT_DONE)
@@ -1915,6 +1922,7 @@ Cache::open_write(Continuation *cont, CacheKey *key, CacheHTTPInfo *info, time_t
         goto Lmiss;
       } else {
         c->od->reading_vec = 1;
+        c->od->open_writer = c;
         // document exists, read vector
         SET_CONTINUATION_HANDLER(c, &CacheVC::openWriteStartDone);
         switch (c->do_read_call(&c->first_key)) {
@@ -1934,7 +1942,7 @@ Cache::open_write(Continuation *cont, CacheKey *key, CacheHTTPInfo *info, time_t
   }
 
 Lmiss:
-//  return c->do_init_write();
+//  return c->do_write_init();
   SET_CONTINUATION_HANDLER(c, &CacheVC::openWriteInit);
   c->callcont(CACHE_EVENT_OPEN_WRITE);
   return ACTION_RESULT_DONE;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cache/I_Cache.h
----------------------------------------------------------------------
diff --git a/iocore/cache/I_Cache.h b/iocore/cache/I_Cache.h
index 7ee6b37..c75430d 100644
--- a/iocore/cache/I_Cache.h
+++ b/iocore/cache/I_Cache.h
@@ -256,11 +256,12 @@ struct CacheVConnection : public VConnection {
   /// Check if this is HTTP partial content (range request/response).
   virtual bool is_http_partial_content() = 0;
 
-  /// Get the unchanged ranges.
+  /// Get the unchanged ranges for the request range @a req.
+  /// If @a req is empty it is treated as a full request (non-partial).
   /// @return @c true if the @a result is not empty.
   /// @internal Currently this just returns the single range that is convex hull of the uncached request.
   /// Someday we may want to do the exact range spec but we use the type for now because it's easier.
-  virtual bool get_uncached(HTTPRangeSpec& result) = 0;
+  virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result) { (void)req; (void)result; return false; }
 
   /** Set the range for the input (response content).
       The incoming bytes will be written to this section of the object.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cache/P_CacheInternal.h
----------------------------------------------------------------------
diff --git a/iocore/cache/P_CacheInternal.h b/iocore/cache/P_CacheInternal.h
index 1f7ac29..5290248 100644
--- a/iocore/cache/P_CacheInternal.h
+++ b/iocore/cache/P_CacheInternal.h
@@ -287,7 +287,7 @@ struct CacheVC: public CacheVConnection
     return -1;
   }
 
-  Action* do_init_write();
+  Action* do_write_init();
 
   //  bool writer_done();
   int calluser(int event);
@@ -392,7 +392,7 @@ struct CacheVC: public CacheVConnection
   virtual void set_full_content_length(int64_t size);
   virtual HTTPRangeSpec& get_http_range_spec();
   virtual bool is_http_partial_content();
-  virtual bool get_uncached(HTTPRangeSpec& result);
+  virtual bool get_uncached(HTTPRangeSpec const& req, HTTPRangeSpec& result);
   virtual int64_t set_inbound_range(int64_t min, int64_t max);
 
 #endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/iocore/cluster/P_ClusterCache.h
----------------------------------------------------------------------
diff --git a/iocore/cluster/P_ClusterCache.h b/iocore/cluster/P_ClusterCache.h
index b01d950..9f85ec5 100644
--- a/iocore/cluster/P_ClusterCache.h
+++ b/iocore/cluster/P_ClusterCache.h
@@ -366,7 +366,6 @@ struct ClusterVConnectionBase : public CacheVConnection {
   virtual void set_full_content_length(int64_t) { } // only used when writing to cache
   virtual HTTPRangeSpec& get_http_range_spec() { return resp_range.getRangeSpec(); }
   virtual bool is_http_partial_content() { return false; }
-  virtual bool get_uncached(HTTPRangeSpec& r) { r.clear(); return false; }
 
   // Set the timeouts associated with this connection.
   // active_timeout is for the total elasped time of the connection.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/proxy/hdrs/HTTP.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index 43fcdc7..3ead704 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -2654,6 +2654,8 @@ HTTPInfo::get_uncached_hull(HTTPRangeSpec const& req)
       if (s.isValid()) {
         r._min = std::max(r._min, s._min);
         r._max = s._max;
+      } else {
+        r._max = INT64_MAX;
       }
     }
     if (r.isValid() && m_alt->m_flag.content_length_p && static_cast<int64_t>(r._max) > this->object_size_get())

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index c4a677a..e2e0b95 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -418,7 +418,6 @@ HttpSM::init()
   t_state.force_dns = (ip_rule_in_CacheControlTable() || t_state.parent_params->ParentTable->ipMatch ||
                        !(t_state.txn_conf->doc_in_cache_skip_dns) || !(t_state.txn_conf->cache_http));
 
-  http_parser.m_allow_non_http = t_state.http_config_param->parser_allow_non_http;
   http_parser_init(&http_parser);
 
   SET_HANDLER(&HttpSM::main_handler);
@@ -671,39 +670,26 @@ HttpSM::state_read_client_request_header(int event, void *data)
   // We need to handle EOS as well as READ_READY because the client
   // may have sent all of the data already followed by a fIN and that
   // should be OK.
-  if (is_transparent_passthrough_allowed() && ua_raw_buffer_reader != NULL) {
-    bool do_blind_tunnel = false;
-    // If we had a parse error and we're done reading data
-    // blind tunnel
-    if ((event == VC_EVENT_READ_READY || event == VC_EVENT_EOS) && state == PARSE_ERROR) {
-      do_blind_tunnel = true;
-
-      // If we had a GET request that has data after the
-      // get request, do blind tunnel
-    } else if (state == PARSE_DONE && t_state.hdr_info.client_request.method_get_wksidx() == HTTP_WKSIDX_GET &&
-               ua_raw_buffer_reader->read_avail() > 0 && !t_state.hdr_info.client_request.is_keep_alive_set()) {
-      do_blind_tunnel = true;
-    }
-    if (do_blind_tunnel) {
-      DebugSM("http", "[%" PRId64 "] first request on connection failed parsing, switching to passthrough.", sm_id);
-
-      t_state.transparent_passthrough = true;
-      http_parser_clear(&http_parser);
-
-      // Turn off read eventing until we get the
-      // blind tunnel infrastructure set up
-      ua_session->get_netvc()->do_io_read(this, 0, NULL);
-
-      /* establish blind tunnel */
-      setup_blind_tunnel_port();
+  if ((event == VC_EVENT_READ_READY || event == VC_EVENT_EOS) && state == PARSE_ERROR && is_transparent_passthrough_allowed() &&
+      ua_raw_buffer_reader != NULL) {
+    DebugSM("http", "[%" PRId64 "] first request on connection failed parsing, switching to passthrough.", sm_id);
 
-      // Setting half close means we will send the FIN when we've written all of the data.
-      if (event == VC_EVENT_EOS) {
-        this->set_ua_half_close_flag();
-        t_state.client_info.keep_alive = HTTP_NO_KEEPALIVE;
-      }
-      return 0;
+    t_state.transparent_passthrough = true;
+    http_parser_clear(&http_parser);
+
+    // Turn off read eventing until we get the
+    // blind tunnel infrastructure set up
+    ua_session->get_netvc()->do_io_read(this, 0, NULL);
+
+    /* establish blind tunnel */
+    setup_blind_tunnel_port();
+
+    // Setting half close means we will send the FIN when we've written all of the data.
+    if (event == VC_EVENT_EOS) {
+      this->set_ua_half_close_flag();
+      t_state.client_info.keep_alive = HTTP_NO_KEEPALIVE;
     }
+    return 0;
   }
 
   // Check to see if we are done parsing the header
@@ -1553,7 +1539,7 @@ HttpSM::handle_api_return()
 
       setup_blind_tunnel(true);
     } else {
-      if (t_state.hdr_info.request_range.hasRanges() && HttpTransact::CACHE_DO_WRITE == t_state.cache_info.action) {
+      if (t_state.range_setup == HttpTransact::RANGE_PARTIAL_WRITE && HttpTransact::CACHE_DO_WRITE == t_state.cache_info.action) {
         Debug("amc", "Set up for partial read");
         CacheVConnection *save_write_vc = cache_sm.cache_write_vc;
         tunnel.tunnel_run(setup_server_transfer_to_cache_only());
@@ -2406,7 +2392,6 @@ HttpSM::state_cache_open_write(int event, void *data)
     // The write vector was locked and the cache_sm retried
     // and got the read vector again.
     cache_sm.cache_read_vc->get_http_info(&t_state.cache_info.object_read);
-    // ToDo: Should support other levels of cache hits here, but the cache does not support it (yet)
     if (cache_sm.cache_read_vc->is_ram_cache_hit()) {
       t_state.cache_info.hit_miss_code = SQUID_HIT_RAM;
     } else {
@@ -2494,7 +2479,7 @@ HttpSM::state_cache_open_read(int event, void *data)
     t_state.source = HttpTransact::SOURCE_CACHE;
 
     cache_sm.cache_read_vc->get_http_info(&t_state.cache_info.object_read);
-    // ToDo: Should support other levels of cache hits here, but the cache does not support it (yet)
+    // ToDo: Should support other levels of cache hits here, but the cache does
     if (cache_sm.cache_read_vc->is_ram_cache_hit()) {
       t_state.cache_info.hit_miss_code = SQUID_HIT_RAM;
     } else {
@@ -3069,7 +3054,6 @@ HttpSM::tunnel_handler_server(int event, HttpTunnelProducer *p)
       ua_session->attach_server_session(server_session);
     } else {
       // Release the session back into the shared session pool
-      server_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out));
       server_session->release();
     }
   }
@@ -4057,12 +4041,16 @@ HttpSM::do_hostdb_lookup()
   } else { /* we aren't using SRV stuff... */
     DebugSM("http_seq", "[HttpSM::do_hostdb_lookup] Doing DNS Lookup");
 
+    // If there is not a current server, we must be looking up the origin
+    //  server at the beginning of the transaction
+    int server_port = t_state.current.server ? t_state.current.server->port : t_state.server_info.port;
+
     if (t_state.api_txn_dns_timeout_value != -1) {
       DebugSM("http_timeout", "beginning DNS lookup. allowing %d mseconds for DNS lookup", t_state.api_txn_dns_timeout_value);
     }
 
     HostDBProcessor::Options opt;
-
+    opt.port = server_port;
     opt.flags = (t_state.cache_info.directives.does_client_permit_dns_storing) ? HostDBProcessor::HOSTDB_DO_NOT_FORCE_DNS :
                                                                                  HostDBProcessor::HOSTDB_FORCE_DNS_RELOAD;
     opt.timeout = (t_state.api_txn_dns_timeout_value != -1) ? t_state.api_txn_dns_timeout_value : 0;
@@ -4180,6 +4168,10 @@ HttpSM::do_hostdb_update_if_necessary()
 void
 HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
 {
+  (void)field;
+  (void)content_length;
+  return;
+#if 0
   int prev_good_range = -1;
   const char *value;
   int value_len;
@@ -4227,7 +4219,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
   t_state.range_in_cache = true;
 
   for (; value; value = csv.get_next(&value_len)) {
-    if (!(tmp = (const char *)memchr(value, '-', value_len))) {
+    if (!(tmp = (const char *) memchr(value, '-', value_len))) {
       t_state.range_setup = HttpTransact::RANGE_NONE;
       goto Lfaild;
     }
@@ -4236,8 +4228,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
     s = value;
     e = tmp;
     // skip leading white spaces
-    for (; s < e && ParseRules::is_ws(*s); ++s)
-      ;
+    for (; s < e && ParseRules::is_ws(*s); ++s) ;
 
     if (s >= e)
       start = -1;
@@ -4245,8 +4236,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
       for (start = 0; s < e && *s >= '0' && *s <= '9'; ++s)
         start = start * 10 + (*s - '0');
       // skip last white spaces
-      for (; s < e && ParseRules::is_ws(*s); ++s)
-        ;
+      for (; s < e && ParseRules::is_ws(*s); ++s) ;
 
       if (s < e || start < 0) {
         t_state.range_setup = HttpTransact::RANGE_NONE;
@@ -4258,8 +4248,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
     s = tmp + 1;
     e = value + value_len;
     // skip leading white spaces
-    for (; s < e && ParseRules::is_ws(*s); ++s)
-      ;
+    for (; s < e && ParseRules::is_ws(*s); ++s) ;
 
     if (s >= e) {
       if (start < 0) {
@@ -4274,8 +4263,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
       for (end = 0; s < e && *s >= '0' && *s <= '9'; ++s)
         end = end * 10 + (*s - '0');
       // skip last white spaces
-      for (; s < e && ParseRules::is_ws(*s); ++s)
-        ;
+      for (; s < e && ParseRules::is_ws(*s); ++s) ;
 
       if (s < e || end < 0) {
         t_state.range_setup = HttpTransact::RANGE_NONE;
@@ -4316,7 +4304,7 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
 #if 0
     if (!cache_sm.cache_read_vc->is_pread_capable() && cache_config_read_while_writer==2) {
       // write in progress, check if request range not in cache yet
-      HTTPInfo::FragOffset *frag_offset_tbl = t_state.cache_info.object_read->get_frag_table();
+      HTTPInfo::FragOffset* frag_offset_tbl = t_state.cache_info.object_read->get_frag_table();
       int frag_offset_cnt = t_state.cache_info.object_read->get_frag_offset_count();
 
       if (!frag_offset_tbl || !frag_offset_cnt || (frag_offset_tbl[frag_offset_cnt - 1] < (uint64_t)end)) {
@@ -4340,16 +4328,22 @@ HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length)
 Lfaild:
   t_state.range_in_cache = false;
   t_state.num_range_fields = -1;
-  delete[] ranges;
+  delete []ranges;
   return;
+#endif
 }
 
 void
-HttpSM::calculate_output_cl(int64_t num_chars_for_ct, int64_t num_chars_for_cl)
+HttpSM::calculate_output_cl(int64_t content_length, int64_t num_chars)
 {
+#if 1
+  (void)content_length;
+  (void)num_chars;
+  return;
+#else
   int i;
 
-  if (t_state.range_setup != HttpTransact::RANGE_REQUESTED && t_state.range_setup != HttpTransact::RANGE_NOT_TRANSFORM_REQUESTED)
+  if (t_state.range_setup != HttpTransact::RANGE_REQUESTED)
     return;
 
   ink_assert(t_state.ranges);
@@ -4360,9 +4354,9 @@ HttpSM::calculate_output_cl(int64_t num_chars_for_ct, int64_t num_chars_for_cl)
     for (i = 0; i < t_state.num_range_fields; i++) {
       if (t_state.ranges[i]._start >= 0) {
         t_state.range_output_cl += boundary_size;
-        t_state.range_output_cl += sub_header_size + num_chars_for_ct;
+        t_state.range_output_cl += sub_header_size + content_length;
         t_state.range_output_cl +=
-          num_chars_for_int(t_state.ranges[i]._start) + num_chars_for_int(t_state.ranges[i]._end) + num_chars_for_cl + 2;
+          num_chars_for_int(t_state.ranges[i]._start) + num_chars_for_int(t_state.ranges[i]._end) + num_chars + 2;
         t_state.range_output_cl += t_state.ranges[i]._end - t_state.ranges[i]._start + 1;
         t_state.range_output_cl += 2;
       }
@@ -4372,19 +4366,17 @@ HttpSM::calculate_output_cl(int64_t num_chars_for_ct, int64_t num_chars_for_cl)
   }
 
   Debug("http_range", "Pre-calculated Content-Length for Range response is %" PRId64, t_state.range_output_cl);
+#endif
 }
 
 void
 HttpSM::do_range_parse(MIMEField *range_field)
 {
-  int num_chars_for_ct = 0;
-  t_state.cache_info.object_read->response_get()->value_get(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE, &num_chars_for_ct);
-
   int64_t content_length = t_state.cache_info.object_read->object_size_get();
   int64_t num_chars_for_cl = num_chars_for_int(content_length);
 
   parse_range_and_compare(range_field, content_length);
-  calculate_output_cl(num_chars_for_ct, num_chars_for_cl);
+  calculate_output_cl(content_length, num_chars_for_cl);
 }
 
 // this function looks for any Range: headers, parses them and either
@@ -6989,15 +6981,7 @@ HttpSM::set_next_state()
   case HttpTransact::SM_ACTION_DNS_LOOKUP: {
     sockaddr const *addr;
 
-    if ((strncmp(t_state.dns_info.lookup_name, "127.0.0.1", 9) == 0 || strncmp(t_state.dns_info.lookup_name, "::1", 3) == 0) &&
-        ats_ip_pton(t_state.dns_info.lookup_name, t_state.host_db_info.ip()) == 0) {
-      // If it's 127.0.0.1 or ::1 don't bother with hostdb
-      DebugSM("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup for %s because it's loopback",
-              t_state.dns_info.lookup_name);
-      t_state.dns_info.lookup_success = true;
-      call_transact_and_set_next_state(NULL);
-      break;
-    } else if (t_state.api_server_addr_set) {
+    if (t_state.api_server_addr_set) {
       /* If the API has set the server address before the OS DNS lookup
        * then we can skip the lookup
        */
@@ -7123,6 +7107,16 @@ HttpSM::set_next_state()
     break;
   }
 
+  case HttpTransact::SM_ACTION_CACHE_OPEN_PARTIAL_READ: {
+#if 0
+      HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_cache_open_partial_read);
+      t_state.source = HttpTransact::SOURCE_CACHE;
+      pending_action = cache_sm.open_partial_read();
+#endif
+    ink_assert(!"[amc] Shouldn't get here");
+    break;
+  }
+
   case HttpTransact::SM_ACTION_SERVER_READ: {
     t_state.source = HttpTransact::SOURCE_HTTP_ORIGIN_SERVER;
 
@@ -7612,9 +7606,6 @@ HttpSM::redirect_request(const char *redirect_url, const int redirect_len)
         // the client request didn't have a host, so use the current origin host
         DebugSM("http_redirect", "[HttpSM::redirect_request] keeping client request host %s://%s", next_hop_scheme, origHost);
         char *origHost1 = strtok_r(origHost, ":", &saveptr);
-        if (origHost1 == NULL) {
-          goto LhostError;
-        }
         origHost_len = strlen(origHost1);
         int origHostPort_len = origHost_len;
         char buf[origHostPort_len + 7];
@@ -7647,7 +7638,6 @@ HttpSM::redirect_request(const char *redirect_url, const int redirect_len)
         t_state.hdr_info.client_request.m_target_cached = false;
         clientUrl.scheme_set(scheme_str, scheme_len);
       } else {
-      LhostError:
         // the server request didn't have a host, so remove it from the headers
         t_state.hdr_info.client_request.field_delete(MIME_FIELD_HOST, MIME_LEN_HOST);
       }
@@ -7729,11 +7719,11 @@ HttpSM::is_redirect_required()
     HTTPStatus status = t_state.hdr_info.client_response.status_get();
     // check to see if the response from the orgin was a 301, 302, or 303
     switch (status) {
-    case HTTP_STATUS_MULTIPLE_CHOICES:   // 300
-    case HTTP_STATUS_MOVED_PERMANENTLY:  // 301
-    case HTTP_STATUS_MOVED_TEMPORARILY:  // 302
-    case HTTP_STATUS_SEE_OTHER:          // 303
-    case HTTP_STATUS_USE_PROXY:          // 305
+    case HTTP_STATUS_MULTIPLE_CHOICES: // 300
+    case HTTP_STATUS_MOVED_PERMANENTLY: // 301
+    case HTTP_STATUS_MOVED_TEMPORARILY: // 302
+    case HTTP_STATUS_SEE_OTHER: // 303
+    case HTTP_STATUS_USE_PROXY: // 305
     case HTTP_STATUS_TEMPORARY_REDIRECT: // 307
       redirect_required = true;
       break;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index ffc4293..e383ba9 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -1760,7 +1760,7 @@ HttpTransact::OSDNSLookup(State *s)
     } else {
       if ((s->cache_info.action == CACHE_DO_NO_ACTION) &&
           (((s->hdr_info.client_request.presence(MIME_PRESENCE_RANGE) && !s->txn_conf->cache_range_write) ||
-            s->range_setup == RANGE_NOT_SATISFIABLE || s->range_setup == RANGE_NOT_HANDLED))) {
+            s->range_setup == RANGE_NOT_SATISFIABLE))) {
         TRANSACT_RETURN(SM_ACTION_API_OS_DNS, HandleCacheOpenReadMiss);
       } else if (!s->txn_conf->cache_http || s->cache_lookup_result == HttpTransact::CACHE_LOOKUP_SKIPPED) {
         TRANSACT_RETURN(SM_ACTION_API_OS_DNS, LookupSkipOpenServer);
@@ -1768,7 +1768,7 @@ HttpTransact::OSDNSLookup(State *s)
         // from the DNS we need to call LookupSkipOpenServer
       } else if (s->cache_lookup_result == CACHE_LOOKUP_HIT_FRESH || s->cache_lookup_result == CACHE_LOOKUP_HIT_WARNING ||
                  s->cache_lookup_result == CACHE_LOOKUP_HIT_STALE) {
-        //DNS lookup is done if the content is stale need to call handle cache open read hit
+        // DNS lookup is done if the content is stale need to call handle cache open read hit
         TRANSACT_RETURN(SM_ACTION_API_OS_DNS, HandleCacheOpenReadHit);
       } else if (s->cache_lookup_result == CACHE_LOOKUP_MISS || s->cache_info.action == CACHE_DO_NO_ACTION) {
         TRANSACT_RETURN(SM_ACTION_API_OS_DNS, HandleCacheOpenReadMiss);
@@ -2691,9 +2691,23 @@ HttpTransact::HandleCacheOpenReadHit(State *s)
     }
   }
 
-  // Check if it's a range request and we need to get some data from the origin.
-  if (s->state_machine->get_cache_sm().cache_read_vc->get_uncached(range)) {
-    build_request(s, &s->hdr_info.client_request, &s->hdr_info.server_request, s->current.server->http_version, &range);
+  // Check if we need to get some data from the origin.
+  if (s->state_machine->get_cache_sm().cache_read_vc->get_uncached(s->hdr_info.request_range, range)) {
+    Debug("amc", "Request has uncached fragments");
+    find_server_and_update_current_info(s);
+    if (!ats_is_ip(&s->current.server->addr)) {
+      if (s->current.request_to == PARENT_PROXY) {
+        TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, PPDNSLookup);
+      } else if (s->current.request_to == ORIGIN_SERVER) {
+        TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, OSDNSLookup);
+      } else {
+        ink_assert(!"[amc] - where was this going?");
+        return;
+      }
+    }
+    build_request(s, &s->hdr_info.client_request, &s->hdr_info.server_request, s->client_info.http_version, &range);
+    s->cache_info.action = CACHE_PREPARE_TO_WRITE;
+    s->range_setup = RANGE_PARTIAL_WRITE;
     s->next_action = how_to_open_connection(s);
     if (s->stale_icp_lookup && s->next_action == SM_ACTION_ORIGIN_SERVER_OPEN) {
       s->next_action = SM_ACTION_ICP_QUERY;
@@ -2821,7 +2835,7 @@ HttpTransact::build_response_from_cache(State *s, HTTPWarningCode warning_code)
       // send back the full document to the client.
       DebugTxn("http_trans", "[build_response_from_cache] Match! Serving full document.");
       s->cache_info.action = CACHE_DO_SERVE;
-# if 0
+#if 0
       // Check if cached response supports Range. If it does, append
       // Range transformation plugin
       // only if the cached response is a 200 OK
@@ -2856,10 +2870,10 @@ HttpTransact::build_response_from_cache(State *s, HTTPWarningCode warning_code)
         build_response(s, cached_response, &s->hdr_info.client_response, s->client_info.http_version);
       }
       s->next_action = SM_ACTION_SERVE_FROM_CACHE;
-# else
+#else
       build_response(s, cached_response, &s->hdr_info.client_response, s->client_info.http_version);
       s->next_action = SM_ACTION_SERVE_FROM_CACHE;
-# endif
+#endif
     }
     // If the client request is a HEAD, then serve the header from cache.
     else if (s->method == HTTP_WKSIDX_HEAD) {
@@ -3025,14 +3039,16 @@ HttpTransact::HandleCacheOpenReadMiss(State *s)
   // We must, however, not cache the responses to these requests.
   if (does_method_require_cache_copy_deletion(s->http_config_param, s->method) && s->api_req_cacheable == false) {
     s->cache_info.action = CACHE_DO_NO_ACTION;
-# if 0
+#if 0
   } else if ((s->hdr_info.client_request.presence(MIME_PRESENCE_RANGE) && !s->txn_conf->cache_range_write) ||
              does_method_effect_cache(s->method) == false || s->range_setup == RANGE_NOT_SATISFIABLE ||
              s->range_setup == RANGE_NOT_HANDLED) {
     s->cache_info.action = CACHE_DO_NO_ACTION;
-# endif
+#endif
   } else {
     s->cache_info.action = CACHE_PREPARE_TO_WRITE;
+    if (s->hdr_info.request_range.hasRanges())
+      s->range_setup = RANGE_PARTIAL_WRITE;
   }
 
   // We should not issue an ICP lookup if the request has a
@@ -3074,7 +3090,8 @@ HttpTransact::HandleCacheOpenReadMiss(State *s)
         return;
       }
     }
-    build_request(s, &s->hdr_info.client_request, &s->hdr_info.server_request, s->current.server->http_version, &s->hdr_info.request_range);
+    build_request(s, &s->hdr_info.client_request, &s->hdr_info.server_request, s->current.server->http_version,
+                  &s->hdr_info.request_range);
     s->next_action = how_to_open_connection(s);
   } else { // miss, but only-if-cached is set
     build_error_response(s, HTTP_STATUS_GATEWAY_TIMEOUT, "Not Cached", "cache#not_in_cache", NULL);
@@ -4378,7 +4395,7 @@ HttpTransact::handle_cache_operation_on_forward_server_response(State *s)
   }
 
 
-# if 0
+#if 0
   /* If we plan to do a write and the request was partial, then we need to open a
      cache read to service the request and not just pass through.
   */
@@ -4388,7 +4405,7 @@ HttpTransact::handle_cache_operation_on_forward_server_response(State *s)
   ) {
     s->next_action = SM_ACTION_CACHE_OPEN_PARTIAL_READ;
   }
-# endif
+#endif
 
   // update stat, set via string, etc
 
@@ -5177,7 +5194,7 @@ HttpTransact::add_client_ip_to_outgoing_request(State *s, HTTPHdr *request)
 HttpTransact::RequestError_t
 HttpTransact::check_request_validity(State *s, HTTPHdr *incoming_hdr)
 {
-  MIMEField* f; // temp for field checks.
+  MIMEField *f; // temp for field checks.
 
   if (incoming_hdr == 0) {
     return NON_EXISTANT_REQUEST_HEADER;
@@ -5300,7 +5317,7 @@ HttpTransact::check_request_validity(State *s, HTTPHdr *incoming_hdr)
 
   if (0 != (f = incoming_hdr->field_find(MIME_FIELD_RANGE, MIME_LEN_RANGE))) {
     int len;
-    char const* val = f->value_get(&len);
+    char const *val = f->value_get(&len);
     if (!s->hdr_info.request_range.parseRangeFieldValue(val, len))
       return INVALID_RANGE_FIELD;
   }
@@ -5650,7 +5667,7 @@ HttpTransact::initialize_state_variables_from_request(State *s, HTTPHdr *obsolet
 void
 HttpTransact::initialize_state_variables_from_response(State *s, HTTPHdr *incoming_response)
 {
-  MIMEField* field;
+  MIMEField *field;
 
   /* check if the server permits caching */
   s->cache_info.directives.does_server_permit_storing =
@@ -5764,9 +5781,10 @@ HttpTransact::initialize_state_variables_from_response(State *s, HTTPHdr *incomi
   // Get the incoming range to store from the origin.
   if (NULL != (field = incoming_response->field_find(MIME_FIELD_CONTENT_RANGE, MIME_LEN_CONTENT_RANGE))) {
     int len;
-    char const* cr = field->value_get(&len);
-    s->hdr_info.response_content_size = HTTPRangeSpec::parseContentRangeFieldValue(cr, len, s->hdr_info.response_range, s->hdr_info.response_range_boundary);
-  }      
+    char const *cr = field->value_get(&len);
+    s->hdr_info.response_content_size =
+      HTTPRangeSpec::parseContentRangeFieldValue(cr, len, s->hdr_info.response_range, s->hdr_info.response_range_boundary);
+  }
 
 
   s->current.server->transfer_encoding = NO_TRANSFER_ENCODING;
@@ -6072,9 +6090,6 @@ HttpTransact::is_response_cacheable(State *s, HTTPHdr *request, HTTPHdr *respons
                            "request is not cache lookupable, response is not cachable");
     return (false);
   }
-  // already has a fresh copy in the cache
-  if (s->range_setup == RANGE_NOT_HANDLED)
-    return false;
 
   // Check whether the response is cachable based on its cookie
   // If there are cookies in response but a ttl is set, allow caching
@@ -6163,13 +6178,17 @@ HttpTransact::is_response_cacheable(State *s, HTTPHdr *request, HTTPHdr *respons
   }
   // do not cache partial content - Range response
   if (response_code == HTTP_STATUS_RANGE_NOT_SATISFIABLE) {
-    DebugTxn("http_trans", "[is_response_cacheable] " "response code %d - don't cache", response_code);
+    DebugTxn("http_trans", "[is_response_cacheable] "
+                           "response code %d - don't cache",
+             response_code);
     return false;
   } else if (response->presence(MIME_PRESENCE_CONTENT_RANGE) && !s->hdr_info.response_range.isValid()) {
     if (0 <= s->hdr_info.response_content_size) {
-      DebugTxn("http_trans", "[is_response_cacheable] " "Content-Range header present with unsatisfiable range");
+      DebugTxn("http_trans", "[is_response_cacheable] "
+                             "Content-Range header present with unsatisfiable range");
     } else {
-      DebugTxn("http_trans", "[is_response_cacheable] " "Content-Range header present but unparsable");
+      DebugTxn("http_trans", "[is_response_cacheable] "
+                             "Content-Range header present but unparsable");
     }
     return false;
   }
@@ -6234,12 +6253,10 @@ HttpTransact::is_response_cacheable(State *s, HTTPHdr *request, HTTPHdr *respons
   }
   // default cacheability
   if (!s->txn_conf->negative_caching_enabled) {
-    if ((response_code == HTTP_STATUS_OK) ||
-        (response_code == HTTP_STATUS_NOT_MODIFIED) ||
-        (response_code == HTTP_STATUS_PARTIAL_CONTENT) ||
-        (response_code == HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION) ||
-        (response_code == HTTP_STATUS_MOVED_PERMANENTLY) ||
-        (response_code == HTTP_STATUS_MULTIPLE_CHOICES) || (response_code == HTTP_STATUS_GONE)) {
+    if ((response_code == HTTP_STATUS_OK) || (response_code == HTTP_STATUS_NOT_MODIFIED) ||
+        (response_code == HTTP_STATUS_PARTIAL_CONTENT) || (response_code == HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION) ||
+        (response_code == HTTP_STATUS_MOVED_PERMANENTLY) || (response_code == HTTP_STATUS_MULTIPLE_CHOICES) ||
+        (response_code == HTTP_STATUS_GONE)) {
       DebugTxn("http_trans", "[is_response_cacheable] YES by default ");
       return true;
     } else {
@@ -6358,33 +6375,29 @@ HttpTransact::is_request_valid(State *s, HTTPHdr *incoming_request)
     SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
     build_error_response(s, HTTP_STATUS_FORBIDDEN, "Tunnel Forbidden", "access#connect_forbidden", NULL);
     return false;
-  case NO_POST_CONTENT_LENGTH:
-    {
-      DebugTxn("http_trans", "[is_request_valid] post request without content length");
-      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
-      build_error_response(s, HTTP_STATUS_LENGTH_REQUIRED, "Content Length Required", "request#no_content_length", NULL);
-      return false;
-    }
-  case UNACCEPTABLE_TE_REQUIRED:
-    {
-      DebugTxn("http_trans", "[is_request_valid] TE required is unacceptable.");
-      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
-      build_error_response(s, HTTP_STATUS_NOT_ACCEPTABLE, "Transcoding Not Available", "transcoding#unsupported", NULL);
-      return false;
-    }
-  case INVALID_POST_CONTENT_LENGTH :
-    {
-      DebugTxn("http_trans", "[is_request_valid] post request with negative content length value");
-      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
-      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid Content Length", "request#invalid_content_length", NULL);
-      return false;
-    }
-  case INVALID_RANGE_FIELD :
-    {
-      DebugTxn("http_trans", "[is_request_valid] a Range field was present with an invalid range specification");
-      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
-      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid Range", "request#syntax_error", NULL);
-    }
+  case NO_POST_CONTENT_LENGTH: {
+    DebugTxn("http_trans", "[is_request_valid] post request without content length");
+    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
+    build_error_response(s, HTTP_STATUS_LENGTH_REQUIRED, "Content Length Required", "request#no_content_length", NULL);
+    return false;
+  }
+  case UNACCEPTABLE_TE_REQUIRED: {
+    DebugTxn("http_trans", "[is_request_valid] TE required is unacceptable.");
+    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
+    build_error_response(s, HTTP_STATUS_NOT_ACCEPTABLE, "Transcoding Not Available", "transcoding#unsupported", NULL);
+    return false;
+  }
+  case INVALID_POST_CONTENT_LENGTH: {
+    DebugTxn("http_trans", "[is_request_valid] post request with negative content length value");
+    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
+    build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid Content Length", "request#invalid_content_length", NULL);
+    return false;
+  }
+  case INVALID_RANGE_FIELD: {
+    DebugTxn("http_trans", "[is_request_valid] a Range field was present with an invalid range specification");
+    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
+    build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid Range", "request#syntax_error", NULL);
+  }
   default:
     return true;
   }
@@ -6670,7 +6683,7 @@ HttpTransact::handle_content_length_header(State *s, HTTPHdr *header, HTTPHdr *b
         // We made our decision about whether to trust the
         //   response content length in init_state_vars_from_response()
         if (s->hdr_info.request_range.hasRanges()) {
-          change_response_header_because_of_range_request(s,header);
+          change_response_header_because_of_range_request(s, header);
           s->hdr_info.trust_response_cl = true;
         }
         break;
@@ -6679,7 +6692,7 @@ HttpTransact::handle_content_length_header(State *s, HTTPHdr *header, HTTPHdr *b
         // if we are doing a single Range: request, calculate the new
         // C-L: header
         if (s->hdr_info.request_range.hasRanges()) {
-          change_response_header_because_of_range_request(s,header);
+          change_response_header_because_of_range_request(s, header);
           s->hdr_info.trust_response_cl = true;
         }
         ////////////////////////////////////////////////
@@ -6698,7 +6711,7 @@ HttpTransact::handle_content_length_header(State *s, HTTPHdr *header, HTTPHdr *b
         break;
 
       case SOURCE_TRANSFORM:
-        if (s->range_setup == HttpTransact::RANGE_REQUESTED) {
+        if (s->hdr_info.request_range.hasRanges()) {
           header->set_content_length(s->range_output_cl);
           s->hdr_info.trust_response_cl = true;
         } else if (s->hdr_info.transform_response_cl == HTTP_UNDEFINED_CL) {
@@ -6731,7 +6744,7 @@ HttpTransact::handle_content_length_header(State *s, HTTPHdr *header, HTTPHdr *b
         s->hdr_info.trust_response_cl = false;
         s->hdr_info.request_content_length = HTTP_UNDEFINED_CL;
         ink_assert(s->range_setup == RANGE_NONE);
-      } else if (s->range_setup == RANGE_NOT_TRANSFORM_REQUESTED) {
+      } else if (s->hdr_info.response_range.isValid()) {
         // if we are doing a single Range: request, calculate the new
         // C-L: header
         change_response_header_because_of_range_request(s, header);
@@ -6753,7 +6766,6 @@ HttpTransact::handle_content_length_header(State *s, HTTPHdr *header, HTTPHdr *b
         s->hdr_info.trust_response_cl = false;
       }
       header->field_delete(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH);
-      ink_assert(s->range_setup != RANGE_NOT_TRANSFORM_REQUESTED);
     }
   }
   return;
@@ -7693,7 +7705,8 @@ HttpTransact::is_request_likely_cacheable(State *s, HTTPHdr *request)
 }
 
 void
-HttpTransact::build_request(State* s, HTTPHdr* base_request, HTTPHdr* outgoing_request, HTTPVersion outgoing_version, HTTPRangeSpec const* ranges)
+HttpTransact::build_request(State *s, HTTPHdr *base_request, HTTPHdr *outgoing_request, HTTPVersion outgoing_version,
+                            HTTPRangeSpec const *ranges)
 {
   // this part is to restore the original URL in case, multiple cache
   // lookups have happened - client request has been changed as the result
@@ -7720,7 +7733,8 @@ HttpTransact::build_request(State* s, HTTPHdr* base_request, HTTPHdr* outgoing_r
   HttpTransactHeaders::remove_privacy_headers_from_request(s->http_config_param, s->txn_conf, outgoing_request);
   HttpTransactHeaders::add_global_user_agent_header_to_request(s->txn_conf, outgoing_request);
   handle_request_keep_alive_headers(s, outgoing_version, outgoing_request);
-  if (ranges) HttpTransactHeaders::insert_request_range_header(outgoing_request, ranges);
+  if (ranges)
+    HttpTransactHeaders::insert_request_range_header(outgoing_request, ranges);
 
   // handle_conditional_headers appears to be obsolete.  Nothing happens
   // unelss s->cache_info.action == HttpTransact::CACHE_DO_UPDATE.  In that
@@ -8940,10 +8954,10 @@ HttpTransact::change_response_header_because_of_range_request(State *s, HTTPHdr
 {
   MIMEField *field = header->field_find(MIME_FIELD_CONTENT_TYPE, MIME_LEN_CONTENT_TYPE);
   char *reason_phrase;
-//  CacheVConnection* cache_read_vc = s->state_machine->get_cache_sm().cache_read_vc;
-//  HTTPHdr* cached_response = find_appropriate_cached_resp(s);
-//  HTTPRangeSpec& rs = cache_read_vc->get_http_range_spec();
-  HTTPRangeSpec& rs = s->state_machine->t_state.hdr_info.request_range;
+  //  CacheVConnection* cache_read_vc = s->state_machine->get_cache_sm().cache_read_vc;
+  //  HTTPHdr* cached_response = find_appropriate_cached_resp(s);
+  //  HTTPRangeSpec& rs = cache_read_vc->get_http_range_spec();
+  HTTPRangeSpec &rs = s->state_machine->t_state.hdr_info.request_range;
 
   Debug("http_trans", "Partial content requested, re-calculating content-length");
 
@@ -8954,7 +8968,7 @@ HttpTransact::change_response_header_because_of_range_request(State *s, HTTPHdr
   // set the right Content-Type for multiple entry Range
   if (rs.isMulti()) { // means we need a boundary string.
     ink_release_assert(!"[amc] Computation of boundary string not correct working");
-#   if 0
+#if 0
     int rbs_len;
     char const* rbs = cache_read_vc->get_http_range_boundary_string(&rbs_len);
     char buff[(sizeof(HTTP_RANGE_MULTIPART_CONTENT_TYPE)-1) + HTTP_RANGE_BOUNDARY_LEN];
@@ -8967,22 +8981,19 @@ HttpTransact::change_response_header_because_of_range_request(State *s, HTTPHdr
     field->value_append(header->m_heap, header->m_mime, buff, sizeof(buff));
 
     header->field_attach(field);
-#   endif
+#endif
   } else if (rs.isSingle()) {
     int n;
-    char buff[HTTP_LEN_BYTES + (18+1)*3];
+    char buff[HTTP_LEN_BYTES + (18 + 1) * 3];
     header->field_delete(MIME_FIELD_CONTENT_RANGE, MIME_LEN_CONTENT_RANGE);
     field = header->field_create(MIME_FIELD_CONTENT_RANGE, MIME_LEN_CONTENT_RANGE);
-    n = snprintf(buff, sizeof(buff), "%s %" PRIu64"-%" PRIu64"/%" PRId64
-                , HTTP_VALUE_BYTES
-                , rs[0]._min, rs[0]._max
-                , s->state_machine->t_state.hdr_info.response_content_size
-      );
+    n = snprintf(buff, sizeof(buff), "%s %" PRIu64 "-%" PRIu64 "/%" PRId64, HTTP_VALUE_BYTES, rs[0]._min, rs[0]._max,
+                 s->state_machine->t_state.hdr_info.response_content_size);
     field->value_set(header->m_heap, header->m_mime, buff, n);
     header->field_attach(field);
     header->set_content_length(rs.size());
   }
-//  header->set_content_length(cache_read_vc->get_effective_content_size());
+  //  header->set_content_length(cache_read_vc->get_effective_content_size());
 }
 
 #if TS_HAS_TESTS

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/proxy/http/HttpTransact.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 64ee656..44d686c 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -524,10 +524,9 @@ public:
 
   enum RangeSetup_t {
     RANGE_NONE = 0,
-    RANGE_REQUESTED,
     RANGE_NOT_SATISFIABLE,
-    RANGE_NOT_HANDLED,
-    RANGE_NOT_TRANSFORM_REQUESTED,
+    RANGE_PARTIAL_WRITE, // Do a partial write to the object.
+                         // Includes a partial request cache miss and a cache hit with uncached ranges
   };
 
   enum CacheAuth_t {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f82fd704/proxy/http/HttpTunnel.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
index c5eb009..4cf6b04 100644
--- a/proxy/http/HttpTunnel.cc
+++ b/proxy/http/HttpTunnel.cc
@@ -830,13 +830,7 @@ HttpTunnel::producer_run(HttpTunnelProducer *p)
     }
   }
 
-  int64_t read_start_pos = 0;
-  if (p->vc_type == HT_CACHE_READ && sm->t_state.range_setup == HttpTransact::RANGE_NOT_TRANSFORM_REQUESTED) {
-    ink_assert(sm->t_state.num_range_fields == 1); // we current just support only one range entry
-    read_start_pos = sm->t_state.ranges[0]._start;
-    producer_n = (sm->t_state.ranges[0]._end - sm->t_state.ranges[0]._start) + 1;
-    consumer_n = (producer_n + sm->client_response_hdr_bytes);
-  } else if (p->nbytes >= 0) {
+  if (p->nbytes >= 0) {
     consumer_n = p->nbytes;
     producer_n = p->ntodo;
   } else {
@@ -988,11 +982,7 @@ HttpTunnel::producer_run(HttpTunnelProducer *p)
       Debug("http_tunnel", "[%" PRId64 "] [tunnel_run] producer already done", sm->sm_id);
       producer_handler(HTTP_TUNNEL_EVENT_PRECOMPLETE, p);
     } else {
-      if (read_start_pos > 0) {
-        p->read_vio = ((CacheVC *)p->vc)->do_io_pread(this, producer_n, p->read_buffer, read_start_pos);
-      } else {
-        p->read_vio = p->vc->do_io_read(this, producer_n, p->read_buffer);
-      }
+      p->read_vio = p->vc->do_io_read(this, producer_n, p->read_buffer);
     }
   }