You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by su...@apache.org on 2015/06/30 02:11:02 UTC

trafficserver git commit: [TS-3714]: Summary of changes below: a) Issue a SSL_read right after SSL handshake to ensure data already in the SSL buffers is not lost. b) Add vc to net thread's read_ready_list immediately after accept, to ensure data already

Repository: trafficserver
Updated Branches:
  refs/heads/ts3714 [created] 8525ab9b6


[TS-3714]: Summary of changes below:
a) Issue a SSL_read right after SSL handshake to ensure
data already in the SSL buffers is not lost.
b) Add vc to net thread's read_ready_list immediately after
accept, to ensure data already in the socket buffers is not lost.
c) Add a timer for SSL handshake with default to no timer (as today).
d) Fix a bunch of error cases to correctly release resources.


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

Branch: refs/heads/ts3714
Commit: 8525ab9b69fd41072b3107d2512cc43eb4917738
Parents: 8dbe560
Author: Sudheer Vinukonda <su...@yahoo-inc.com>
Authored: Tue Jun 30 00:07:24 2015 +0000
Committer: Sudheer Vinukonda <su...@yahoo-inc.com>
Committed: Tue Jun 30 00:07:24 2015 +0000

----------------------------------------------------------------------
 iocore/net/P_SSLConfig.h            |  1 +
 iocore/net/P_SSLNetVConnection.h    | 23 +++++++++++
 iocore/net/SSLConfig.cc             |  3 ++
 iocore/net/SSLNetVConnection.cc     | 71 ++++++++++++++++++++++++++++----
 iocore/net/SSLNextProtocolAccept.cc |  3 +-
 iocore/net/UnixNetVConnection.cc    | 23 ++++++++++-
 mgmt/RecordsConfig.cc               |  2 +
 proxy/ProtocolProbeSessionAccept.cc | 21 +++++++---
 proxy/http/HttpClientSession.cc     |  8 ++++
 proxy/http/HttpSM.cc                | 11 +++--
 10 files changed, 146 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/P_SSLConfig.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_SSLConfig.h b/iocore/net/P_SSLConfig.h
index 68dd50f..1a6cd60 100644
--- a/iocore/net/P_SSLConfig.h
+++ b/iocore/net/P_SSLConfig.h
@@ -92,6 +92,7 @@ struct SSLConfigParams : public ConfigInfo {
   static int ssl_ocsp_cache_timeout;
   static int ssl_ocsp_request_timeout;
   static int ssl_ocsp_update_period;
+  static int ssl_handshake_timeout_in;
 
   static size_t session_cache_number_buckets;
   static size_t session_cache_max_bucket_size;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/P_SSLNetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index d4b79e9..51748cf 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -219,6 +219,24 @@ public:
   // least some of the hooks
   bool calledHooks(TSHttpHookID /* eventId */) { return (this->sslHandshakeHookState != HANDSHAKE_HOOKS_PRE); }
 
+  MIOBuffer*
+  get_ssl_iobuf()
+  {
+    return iobuf;
+  }
+
+  IOBufferReader*
+  get_ssl_reader()
+  {
+    return reader;
+  }
+
+  bool
+  isEosRcvd()
+  {
+    return eosRcvd;
+  }
+
 private:
   SSLNetVConnection(const SSLNetVConnection &);
   SSLNetVConnection &operator=(const SSLNetVConnection &);
@@ -256,6 +274,11 @@ private:
   const SSLNextProtocolSet *npnSet;
   Continuation *npnEndpoint;
   SessionAccept *sessionAcceptPtr;
+
+  MIOBuffer *iobuf;
+  IOBufferReader *reader;
+  bool eosRcvd;
+
 };
 
 typedef int (SSLNetVConnection::*SSLNetVConnHandler)(int, void *);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/SSLConfig.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 8e7766d..4876800 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -48,6 +48,7 @@ bool SSLConfigParams::ssl_ocsp_enabled = false;
 int SSLConfigParams::ssl_ocsp_cache_timeout = 3600;
 int SSLConfigParams::ssl_ocsp_request_timeout = 10;
 int SSLConfigParams::ssl_ocsp_update_period = 60;
+int SSLConfigParams::ssl_handshake_timeout_in = 0;
 size_t SSLConfigParams::session_cache_number_buckets = 1024;
 bool SSLConfigParams::session_cache_skip_on_lock_contention = false;
 size_t SSLConfigParams::session_cache_max_bucket_size = 100;
@@ -273,6 +274,8 @@ SSLConfigParams::initialize()
   client_verify_depth = 7;
   REC_ReadConfigInt32(clientVerify, "proxy.config.ssl.client.verify.server");
 
+  REC_ReadConfigInt32(ssl_handshake_timeout_in, "proxy.config.ssl.handshake_timeout_in");
+
   ssl_client_cert_filename = NULL;
   ssl_client_cert_path = NULL;
   REC_ReadConfigStringAlloc(ssl_client_cert_filename, "proxy.config.ssl.client.cert.filename");

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/SSLNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 60061fd..8f9bf0a 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -190,8 +190,8 @@ ssl_read_from_net(SSLNetVConnection *sslvc, EThread *lthread, int64_t &ret)
   MIOBufferAccessor &buf = s->vio.buffer;
   IOBufferBlock *b = buf.writer()->first_write_block();
   int event = SSL_READ_ERROR_NONE;
-  int64_t bytes_read;
-  int64_t block_write_avail;
+  int64_t bytes_read = 0;
+  int64_t block_write_avail = 0;
   ssl_error_t sslErr = SSL_ERROR_NONE;
   int64_t nread = 0;
 
@@ -214,7 +214,10 @@ ssl_read_from_net(SSLNetVConnection *sslvc, EThread *lthread, int64_t &ret)
         SSLDebugBufferPrint("ssl_buff", b->end() + offset, nread, "SSL Read");
 #endif
 
-        ink_assert(nread);
+        if(nread == 0) {
+          Debug ("ssl", "SSL_read 0 bytes read, total bytes read till now %" PRId64 ", for vc %p", bytes_read, sslvc);
+          break;
+        }
 
         bytes_read += nread;
         offset += nread;
@@ -267,7 +270,7 @@ ssl_read_from_net(SSLNetVConnection *sslvc, EThread *lthread, int64_t &ret)
     } // while( block_write_avail > 0 )
   }   // for ( bytes_read = 0; (b != 0); b = b->next)
 
-  if (bytes_read > 0) {
+  if ((bytes_read > 0) && (event != SSL_READ_EOS)) {
     Debug("ssl", "[SSL_NetVConnection::ssl_read_from_net] bytes_read=%" PRId64, bytes_read);
     buf.writer()->fill(bytes_read);
     s->vio.ndone += bytes_read;
@@ -464,7 +467,18 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
     if (ret == EVENT_ERROR) {
       this->read.triggered = 0;
       readSignalError(nh, err);
-    } else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT) {
+    } else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT || ret == EVENT_CONT) {
+      if (SSLConfigParams::ssl_handshake_timeout_in > 0) {
+        double handshake_time = ((ink_get_hrtime_internal() - sslHandshakeBeginTime)/1000000000);
+        Debug ("ssl", "ssl handshake for vc %p, took %.3f seconds, configured handshake_timer: %d", this, handshake_time, SSLConfigParams::ssl_handshake_timeout_in);
+        if (handshake_time > SSLConfigParams::ssl_handshake_timeout_in) {
+          Debug ("ssl", "ssl handshake for vc %p, expired, release the connection", this);
+          read.triggered = 0;
+          nh->read_ready_list.remove(this);
+          readSignalError(nh, VC_EVENT_EOS);
+          return;
+        }
+      }
       read.triggered = 0;
       nh->read_ready_list.remove(this);
       readReschedule(nh);
@@ -477,6 +491,26 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
       // the handshake is complete. Otherwise set up for continuing read
       // operations.
       if (ntodo <= 0) {
+        if (!getSSLClientConnection()) {
+          // we will not see another ET epoll event if the first byte is already
+          // in the ssl buffers, so, SSL_read if there's anything already..
+          Debug ("ssl", "ssl handshake completed on vc %p, check to see if first byte, is already in the ssl buffers", this);
+          this->iobuf = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
+          this->reader = this->iobuf->alloc_reader();
+          s->vio.buffer.writer_for(this->iobuf);
+          if (this->iobuf) {
+            ret = ssl_read_from_net(this, lthread, r);
+            if (ret == SSL_READ_EOS) {
+              this->eosRcvd = true;
+            }
+            int pending = SSL_pending (this->ssl);
+            if (r > 0 || pending > 0) {
+              Debug ("ssl", "ssl read right after handshake, read %" PRId64 ", pending %d bytes, for vc %p", r, pending, this);
+            }
+          }
+          read.triggered = 0;
+          read_disable(nh, this);
+        }
         readSignalDone(VC_EVENT_READ_COMPLETE, nh);
       } else {
         read.triggered = 1;
@@ -580,6 +614,7 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
     // close the connection if we have SSL_READ_EOS, this is the return value from ssl_read_from_net() if we get an
     // SSL_ERROR_ZERO_RETURN from SSL_get_error()
     // SSL_ERROR_ZERO_RETURN means that the origin server closed the SSL connection
+    eosRcvd = true;
     read.triggered = 0;
     readSignalDone(VC_EVENT_EOS, nh);
 
@@ -755,7 +790,8 @@ SSLNetVConnection::SSLNetVConnection()
   : ssl(NULL), sslHandshakeBeginTime(0), sslLastWriteTime(0), sslTotalBytesSent(0), hookOpRequested(TS_SSL_HOOK_OP_DEFAULT),
     sslHandShakeComplete(false), sslClientConnection(false), sslClientRenegotiationAbort(false), handShakeBuffer(NULL),
     handShakeHolder(NULL), handShakeReader(NULL), handShakeBioStored(0), sslPreAcceptHookState(SSL_HOOKS_INIT),
-    sslHandshakeHookState(HANDSHAKE_HOOKS_PRE), npnSet(NULL), npnEndpoint(NULL), sessionAcceptPtr(NULL)
+    sslHandshakeHookState(HANDSHAKE_HOOKS_PRE), npnSet(NULL), npnEndpoint(NULL), sessionAcceptPtr(NULL), iobuf(NULL),
+    reader(NULL), eosRcvd(false)
 {
 }
 
@@ -801,13 +837,24 @@ SSLNetVConnection::free(EThread *t)
   read.vio.mutex.clear();
   write.vio.mutex.clear();
   this->mutex.clear();
+  this->ep.stop();
+  this->con.close();
   flags = 0;
   SET_CONTINUATION_HANDLER(this, (SSLNetVConnHandler)&SSLNetVConnection::startEvent);
+  nh->read_ready_list.remove(this);
+  nh->write_ready_list.remove(this);
   nh = NULL;
   read.triggered = 0;
   write.triggered = 0;
+  read.enabled = 0;
+  write.enabled = 0;
+  read.vio._cont = NULL;
+  write.vio._cont = NULL;
+  read.vio.vc_server = NULL;
+  write.vio.vc_server = NULL;
   options.reset();
   closed = 0;
+
   ink_assert(con.fd == NO_FD);
   if (ssl != NULL) {
     SSL_free(ssl);
@@ -815,6 +862,7 @@ SSLNetVConnection::free(EThread *t)
   }
   sslHandShakeComplete = false;
   sslClientConnection = false;
+  sslHandshakeBeginTime = 0;
   sslLastWriteTime = 0;
   sslTotalBytesSent = 0;
   sslClientRenegotiationAbort = false;
@@ -827,6 +875,10 @@ SSLNetVConnection::free(EThread *t)
   npnSet = NULL;
   npnEndpoint = NULL;
   sessionAcceptPtr = NULL;
+  iobuf = NULL;
+  reader = NULL;
+  eosRcvd = false;
+  sslHandShakeComplete = false;
   free_handshake_buffers();
 
   if (from_accept_thread) {
@@ -839,6 +891,11 @@ SSLNetVConnection::free(EThread *t)
 int
 SSLNetVConnection::sslStartHandShake(int event, int &err)
 {
+  if (sslHandshakeBeginTime == 0) {
+    sslHandshakeBeginTime = ink_get_hrtime_internal();
+    set_inactivity_timeout(HRTIME_SECONDS(SSLConfigParams::ssl_handshake_timeout_in));
+  }
+
   switch (event) {
   case SSL_EVENT_SERVER:
     if (this->ssl == NULL) {
@@ -1008,8 +1065,8 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err)
 
     if (sslHandshakeBeginTime) {
       const ink_hrtime ssl_handshake_time = Thread::get_hrtime() - sslHandshakeBeginTime;
-      Debug("ssl", "ssl handshake time:%" PRId64, ssl_handshake_time);
       sslHandshakeBeginTime = 0;
+      Debug("ssl", "ssl handshake time:%" PRId64, ssl_handshake_time);
       SSL_INCREMENT_DYN_STAT_EX(ssl_total_handshake_time_stat, ssl_handshake_time);
       SSL_INCREMENT_DYN_STAT(ssl_total_success_handshake_count_in_stat);
     }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/SSLNextProtocolAccept.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLNextProtocolAccept.cc b/iocore/net/SSLNextProtocolAccept.cc
index 6399e1d..c4748c3 100644
--- a/iocore/net/SSLNextProtocolAccept.cc
+++ b/iocore/net/SSLNextProtocolAccept.cc
@@ -87,7 +87,7 @@ struct SSLNextProtocolTrampoline : public Continuation {
     case VC_EVENT_INACTIVITY_TIMEOUT:
       netvc->do_io(VIO::CLOSE);
       delete this;
-      return EVENT_CONT;
+      return EVENT_ERROR;
     case VC_EVENT_READ_COMPLETE:
       break;
     default:
@@ -117,7 +117,6 @@ SSLNextProtocolAccept::mainEvent(int event, void *edata)
 {
   SSLNetVConnection *netvc = ssl_netvc_cast(event, edata);
 
-  netvc->sslHandshakeBeginTime = Thread::get_hrtime();
   Debug("ssl", "[SSLNextProtocolAccept:mainEvent] event %d netvc %p", event, netvc);
 
   switch (event) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/iocore/net/UnixNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index ba96f24..7c688e8 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -589,8 +589,11 @@ UnixNetVConnection::get_data(int id, void *data)
 VIO *
 UnixNetVConnection::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf)
 {
-  ink_assert(!closed);
   ink_assert(c || 0 == nbytes);
+  if (closed) {
+    Error("do_io_read invoked on closed vc %p, cont %p, nbytes %" PRId64 ", buf %p", this, c, nbytes, buf);
+    return NULL;
+  }
   read.vio.op = VIO::READ;
   read.vio.mutex = c ? c->mutex : this->mutex;
   read.vio._cont = c;
@@ -611,7 +614,10 @@ UnixNetVConnection::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf)
 VIO *
 UnixNetVConnection::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *reader, bool owner)
 {
-  ink_assert(!closed);
+  if (closed) {
+    Error("do_io_write invoked on closed vc %p, cont %p, nbytes %" PRId64 ", reader %p", this, c, nbytes, reader);
+    return NULL;
+  }
   write.vio.op = VIO::WRITE;
   write.vio.mutex = c ? c->mutex : this->mutex;
   write.vio._cont = c;
@@ -1033,6 +1039,13 @@ UnixNetVConnection::acceptEvent(int event, Event *e)
 
   nh->open_list.enqueue(this);
 
+#ifdef USE_EDGE_TRIGGER
+    // Set the vc as triggered and place it in the read ready queue in case there is already data on the socket.
+    Debug("iocore_net", "acceptEvent : Setting triggered and adding to the read ready queue");
+    read.triggered = 1;
+    nh->read_ready_list.enqueue(this);
+#endif
+
   if (inactivity_timeout_in) {
     UnixNetVConnection::set_inactivity_timeout(inactivity_timeout_in);
   }
@@ -1227,6 +1240,12 @@ UnixNetVConnection::free(EThread *t)
   nh = NULL;
   read.triggered = 0;
   write.triggered = 0;
+  read.enabled = 0;
+  write.enabled = 0;
+  read.vio._cont = NULL;
+  write.vio._cont = NULL;
+  read.vio.vc_server = NULL;
+  write.vio.vc_server = NULL;
   options.reset();
   closed = 0;
   ink_assert(!read.ready_link.prev && !read.ready_link.next);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 0f9d8c8..750ea38 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1228,6 +1228,8 @@ static const RecordElement RecordsConfig[] =
   ,
   {RECT_CONFIG, "proxy.config.ssl.server_port", RECD_INT, "-1", RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-65535]", RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.ssl.handshake_timeout_in", RECD_INT, "0", RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-65535]", RECA_NULL}
+  ,
   {RECT_CONFIG, "proxy.config.ssl.client.certification_level", RECD_INT, "0", RECU_RESTART_TS, RR_NULL, RECC_INT, "[0-2]", RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.ssl.server.cert.path", RECD_STRING, TS_BUILD_SYSCONFDIR, RECU_RESTART_TS, RR_NULL, RECC_NULL, NULL, RECA_NULL}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/proxy/ProtocolProbeSessionAccept.cc
----------------------------------------------------------------------
diff --git a/proxy/ProtocolProbeSessionAccept.cc b/proxy/ProtocolProbeSessionAccept.cc
index f512aa1..11673f7c 100644
--- a/proxy/ProtocolProbeSessionAccept.cc
+++ b/proxy/ProtocolProbeSessionAccept.cc
@@ -59,11 +59,11 @@ struct ProtocolProbeTrampoline : public Continuation, public ProtocolProbeSessio
   static const unsigned buffer_size_index = CLIENT_CONNECTION_FIRST_READ_BUFFER_SIZE_INDEX;
   IOBufferReader *reader;
 
-  explicit ProtocolProbeTrampoline(const ProtocolProbeSessionAccept *probe, ProxyMutex *mutex)
+  explicit ProtocolProbeTrampoline(const ProtocolProbeSessionAccept *probe, ProxyMutex *mutex, MIOBuffer *buffer, IOBufferReader *reader)
     : Continuation(mutex), probeParent(probe)
   {
-    this->iobuf = new_MIOBuffer(buffer_size_index);
-    reader = iobuf->alloc_reader(); // reader must be allocated only on a new MIOBuffer.
+   this->iobuf = buffer ? buffer : new_MIOBuffer(buffer_size_index);
+   this->reader = reader ? reader : iobuf->alloc_reader(); // reader must be allocated only on a new MIOBuffer.
     SET_HANDLER(&ProtocolProbeTrampoline::ioCompletionEvent);
   }
 
@@ -124,7 +124,11 @@ struct ProtocolProbeTrampoline : public Continuation, public ProtocolProbeSessio
     return EVENT_CONT;
 
   done:
-    free_MIOBuffer(this->iobuf);
+    SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(netvc);
+    if (!ssl_vc || (this->iobuf != ssl_vc->get_ssl_iobuf())) {
+      free_MIOBuffer(this->iobuf);
+    }
+    this->iobuf = NULL;
     delete this;
     return EVENT_CONT;
   }
@@ -141,7 +145,14 @@ ProtocolProbeSessionAccept::mainEvent(int event, void *data)
 
     VIO *vio;
     NetVConnection *netvc = static_cast<NetVConnection *>(data);
-    ProtocolProbeTrampoline *probe = new ProtocolProbeTrampoline(this, netvc->mutex);
+    SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(netvc);
+    MIOBuffer* buf = NULL;
+    IOBufferReader *reader = NULL;
+    if (ssl_vc) {
+      buf = ssl_vc->get_ssl_iobuf();
+      reader = ssl_vc->get_ssl_reader();
+    }
+    ProtocolProbeTrampoline * probe = new ProtocolProbeTrampoline(this, netvc->mutex, buf, reader);
 
     // XXX we need to apply accept inactivity timeout here ...
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/proxy/http/HttpClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc
index b5e87f4..385da26 100644
--- a/proxy/http/HttpClientSession.cc
+++ b/proxy/http/HttpClientSession.cc
@@ -200,6 +200,14 @@ HttpClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBu
 
   DebugHttpSsn("[%" PRId64 "] session born, netvc %p", con_id, new_vc);
 
+  if (!iobuf) {
+    SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(new_vc);
+    if (ssl_vc) {
+      iobuf = ssl_vc->get_ssl_iobuf();
+      sm_reader = ssl_vc->get_ssl_reader();
+    }
+  }
+
   read_buffer = iobuf ? iobuf : new_MIOBuffer(HTTP_HEADER_BUFFER_SIZE_INDEX);
   sm_reader = reader ? reader : read_buffer->alloc_reader();
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8525ab9b/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 1de4acc..f9962f0 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -545,8 +545,7 @@ HttpSM::setup_client_read_request_header()
   ua_entry->read_vio = ua_session->do_io_read(this, INT64_MAX, ua_buffer_reader->mbuf);
   // The header may already be in the buffer if this
   //  a request from a keep-alive connection
-  if (ua_buffer_reader->read_avail() > 0)
-    handleEvent(VC_EVENT_READ_READY, ua_entry->read_vio);
+  handleEvent(VC_EVENT_READ_READY, ua_entry->read_vio);
 }
 
 void
@@ -569,6 +568,12 @@ HttpSM::state_read_client_request_header(int event, void *data)
   int bytes_used = 0;
   ink_assert(ua_entry->eos == false);
 
+  // check to see if there was an EOS received on the SSL connection
+  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(ua_session->get_netvc());
+  if (ssl_vc && ssl_vc->isEosRcvd()) {
+    DebugSM ("http", "EOS for ssl vc %p at read_first_btye state", ua_session->get_netvc());
+    event = VC_EVENT_EOS;
+  }
   switch (event) {
   case VC_EVENT_READ_READY:
   case VC_EVENT_READ_COMPLETE:
@@ -577,8 +582,6 @@ HttpSM::state_read_client_request_header(int event, void *data)
 
   case VC_EVENT_EOS:
     ua_entry->eos = true;
-    if (client_request_hdr_bytes != 0)
-      break;
   // Fall through
   case VC_EVENT_ERROR:
   case VC_EVENT_INACTIVITY_TIMEOUT: