You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2017/10/13 04:07:05 UTC

[trafficserver] 01/03: Avoid sending duplicate push promise on same client session #2205

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 9b603606f600d4c4277ffab322a9a30dd65cba8e
Author: Rahul Malik <rm...@linkedin.com>
AuthorDate: Fri Aug 4 13:53:32 2017 -0700

    Avoid sending duplicate push promise on same client session #2205
    
    (cherry picked from commit 22733a32b81346cd758b69377c61d3569a63c13a)
    
    Conflicts:
          doc/admin-guide/files/records.config.en.rst
          proxy/http2/Http2ClientSession.h
---
 doc/admin-guide/files/records.config.en.rst |  7 +++++++
 mgmt/RecordsConfig.cc                       |  2 ++
 proxy/InkAPI.cc                             |  6 +++++-
 proxy/http2/HTTP2.cc                        |  2 ++
 proxy/http2/HTTP2.h                         |  1 +
 proxy/http2/Http2ClientSession.cc           |  6 ++++++
 proxy/http2/Http2ClientSession.h            | 23 +++++++++++++++++++++++
 7 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 54ce8ce..8776917 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -3340,6 +3340,13 @@ HTTP/2 Configuration
 
    Enable the experimental HTTP/2 Stream Priority feature.
 
+.. ts:cv:: CONFIG proxy.config.http2.push_diary_size INT 256
+   :reloadable:
+
+   Indicates the maximum number of HTTP/2 server pushes that are remembered per
+   HTTP/2 connection to avoid duplicate pushes on the same connection. If the
+   maximum number is reached, new entries are not remembered.
+
 Plug-in Configuration
 =====================
 
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 383ede2..61c79cd 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1434,6 +1434,8 @@ static const RecordElement RecordsConfig[] =
   ,
   {RECT_CONFIG, "proxy.config.http2.active_timeout_in", RECD_INT, "900", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.http2.push_diary_size", RECD_INT, "256", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  ,
 
   //# Add LOCAL Records Here
   {RECT_LOCAL, "proxy.local.incoming_ip_to_bind", RECD_STRING, nullptr, RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index c2ad922..2f4626f 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -7684,7 +7684,11 @@ TSHttpTxnServerPush(TSHttpTxn txnp, const char *url, int url_len)
   HttpSM *sm          = reinterpret_cast<HttpSM *>(txnp);
   Http2Stream *stream = dynamic_cast<Http2Stream *>(sm->ua_session);
   if (stream) {
-    stream->push_promise(url_obj);
+    Http2ClientSession *parent = static_cast<Http2ClientSession *>(stream->get_parent());
+    if (!parent->is_url_pushed(url, url_len)) {
+      stream->push_promise(url_obj);
+      parent->add_url_to_pushed_table(url, url_len);
+    }
   }
   url_obj.destroy();
 }
diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
index 16b518b..67af7b6 100644
--- a/proxy/http2/HTTP2.cc
+++ b/proxy/http2/HTTP2.cc
@@ -725,6 +725,7 @@ uint32_t Http2::max_request_header_size    = 131072;
 uint32_t Http2::accept_no_activity_timeout = 120;
 uint32_t Http2::no_activity_timeout_in     = 120;
 uint32_t Http2::active_timeout_in          = 0;
+uint32_t Http2::push_diary_size            = 256;
 
 void
 Http2::init()
@@ -741,6 +742,7 @@ Http2::init()
   REC_EstablishStaticConfigInt32U(accept_no_activity_timeout, "proxy.config.http2.accept_no_activity_timeout");
   REC_EstablishStaticConfigInt32U(no_activity_timeout_in, "proxy.config.http2.no_activity_timeout_in");
   REC_EstablishStaticConfigInt32U(active_timeout_in, "proxy.config.http2.active_timeout_in");
+  REC_EstablishStaticConfigInt32U(push_diary_size, "proxy.config.http2.push_diary_size");
 
   // If any settings is broken, ATS should not start
   ink_release_assert(http2_settings_parameter_is_valid({HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, max_concurrent_streams_in}));
diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h
index 19272a5..2c0ec8c 100644
--- a/proxy/http2/HTTP2.h
+++ b/proxy/http2/HTTP2.h
@@ -376,6 +376,7 @@ public:
   static uint32_t accept_no_activity_timeout;
   static uint32_t no_activity_timeout_in;
   static uint32_t active_timeout_in;
+  static uint32_t push_diary_size;
 
   static void init();
 };
diff --git a/proxy/http2/Http2ClientSession.cc b/proxy/http2/Http2ClientSession.cc
index b7ee905..f545918 100644
--- a/proxy/http2/Http2ClientSession.cc
+++ b/proxy/http2/Http2ClientSession.cc
@@ -86,6 +86,10 @@ Http2ClientSession::destroy()
 void
 Http2ClientSession::free()
 {
+  if (h2_pushed_urls) {
+    this->h2_pushed_urls = ink_hash_table_destroy(this->h2_pushed_urls);
+  }
+
   if (client_vc) {
     release_netvc();
     client_vc->do_io_close();
@@ -190,6 +194,8 @@ Http2ClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOB
   this->read_buffer             = iobuf ? iobuf : new_MIOBuffer(HTTP2_HEADER_BUFFER_SIZE_INDEX);
   this->read_buffer->water_mark = connection_state.server_settings.get(HTTP2_SETTINGS_MAX_FRAME_SIZE);
   this->sm_reader               = reader ? reader : this->read_buffer->alloc_reader();
+  this->h2_pushed_urls          = ink_hash_table_create(InkHashTableKeyType_String);
+  this->h2_pushed_urls_size     = 0;
 
   this->write_buffer = new_MIOBuffer(HTTP2_HEADER_BUFFER_SIZE_INDEX);
   this->sm_writer    = this->write_buffer->alloc_reader();
diff --git a/proxy/http2/Http2ClientSession.h b/proxy/http2/Http2ClientSession.h
index 5de4e80..2851528 100644
--- a/proxy/http2/Http2ClientSession.h
+++ b/proxy/http2/Http2ClientSession.h
@@ -283,6 +283,26 @@ public:
     return half_close_local;
   }
 
+  bool
+  is_url_pushed(const char *url, int url_len)
+  {
+    char *dup_url            = ats_strndup(url, url_len);
+    InkHashTableEntry *entry = ink_hash_table_lookup_entry(h2_pushed_urls, dup_url);
+    ats_free(dup_url);
+    return entry != nullptr;
+  }
+
+  void
+  add_url_to_pushed_table(const char *url, int url_len)
+  {
+    if (h2_pushed_urls_size < Http2::push_diary_size) {
+      char *dup_url = ats_strndup(url, url_len);
+      ink_hash_table_insert(h2_pushed_urls, dup_url, nullptr);
+      h2_pushed_urls_size++;
+      ats_free(dup_url);
+    }
+  }
+
 private:
   Http2ClientSession(Http2ClientSession &);                  // noncopyable
   Http2ClientSession &operator=(const Http2ClientSession &); // noncopyable
@@ -316,6 +336,9 @@ private:
   bool kill_me;
   bool half_close_local;
   int recursion;
+
+  InkHashTable *h2_pushed_urls;
+  uint32_t h2_pushed_urls_size;
 };
 
 extern ClassAllocator<Http2ClientSession> http2ClientSessionAllocator;

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.