You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2015/11/09 20:17:29 UTC

trafficserver git commit: TS-4001: Separate Http2Stream from Http2ConnectionState.h

Repository: trafficserver
Updated Branches:
  refs/heads/master 0f05774d3 -> cba128253


TS-4001: Separate Http2Stream from Http2ConnectionState.h

This closes #327


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

Branch: refs/heads/master
Commit: cba128253733c3bb88248565c5b5b11c044bbe45
Parents: 0f05774
Author: Masaori Koshiba <mk...@yahoo-corp.jp>
Authored: Mon Nov 9 11:15:01 2015 -0800
Committer: Bryan Call <bc...@apache.org>
Committed: Mon Nov 9 11:15:01 2015 -0800

----------------------------------------------------------------------
 proxy/Main.cc                       |   2 +-
 proxy/http2/Http2ConnectionState.cc | 114 +------------------------
 proxy/http2/Http2ConnectionState.h  | 109 +-----------------------
 proxy/http2/Http2Stream.cc          | 139 +++++++++++++++++++++++++++++++
 proxy/http2/Http2Stream.h           | 138 ++++++++++++++++++++++++++++++
 proxy/http2/Makefile.am             |   2 +
 6 files changed, 282 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/Main.cc
----------------------------------------------------------------------
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 2b6d39f..e74d50b 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -1417,7 +1417,7 @@ change_uid_gid(const char *user)
     elevation only on an explicit permission failure.
 */
 static int
-elevating_open(char const* path, unsigned int flags, unsigned int fperms)
+elevating_open(char const *path, unsigned int flags, unsigned int fperms)
 {
   int fd = open(path, flags, fperms);
   if (fd < 0 && EPERM == errno) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/http2/Http2ConnectionState.cc
----------------------------------------------------------------------
diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
index 283f8ed..d6c4775 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -24,12 +24,10 @@
 #include "P_Net.h"
 #include "Http2ConnectionState.h"
 #include "Http2ClientSession.h"
+#include "Http2Stream.h"
 
 #define DebugHttp2Ssn(fmt, ...) DebugSsn("http2_cs", "[%" PRId64 "] " fmt, this->con_id, __VA_ARGS__)
 
-// Currently use only HTTP/1.1 for requesting to origin server
-const static char *HTTP2_FETCHING_HTTP_VERSION = "HTTP/1.1";
-
 typedef Http2Error (*http2_frame_dispatch)(Http2ClientSession &, Http2ConnectionState &, const Http2Frame &);
 
 static const int buffer_size_index[HTTP2_FRAME_TYPE_MAX] = {
@@ -1114,113 +1112,3 @@ Http2ConnectionState::send_window_update_frame(Http2StreamId id, uint32_t size)
   SCOPED_MUTEX_LOCK(lock, this->ua_session->mutex, this_ethread());
   this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &window_update);
 }
-
-void
-Http2Stream::init_fetcher(Http2ConnectionState &cstate)
-{
-  extern ClassAllocator<FetchSM> FetchSMAllocator;
-
-  // Convert header to HTTP/1.1 format
-  convert_from_2_to_1_1_header(&_req_header);
-
-  // Get null-terminated URL and method
-  Arena arena;
-  int url_len, method_len;
-  const char *url_ref = _req_header.url_get()->string_get_ref(&url_len);
-  const char *url = arena.str_store(url_ref, url_len);
-  const char *method_ref = _req_header.method_get(&method_len);
-  const char *method = arena.str_store(method_ref, method_len);
-
-  // Initialize FetchSM
-  _fetch_sm = FetchSMAllocator.alloc();
-  _fetch_sm->ext_init((Continuation *)cstate.ua_session, method, url, HTTP2_FETCHING_HTTP_VERSION,
-                      cstate.ua_session->get_client_addr(), (TS_FETCH_FLAGS_DECHUNK | TS_FETCH_FLAGS_NOT_INTERNAL_REQUEST));
-
-  // Set request header
-  MIMEFieldIter fiter;
-  for (const MIMEField *field = _req_header.iter_get_first(&fiter); field != NULL; field = _req_header.iter_get_next(&fiter)) {
-    int name_len, value_len;
-    const char *name = field->name_get(&name_len);
-    const char *value = field->value_get(&value_len);
-
-    _fetch_sm->ext_add_header(name, name_len, value, value_len);
-  }
-
-  _fetch_sm->ext_set_user_data(this);
-  _fetch_sm->ext_launch();
-}
-
-void
-Http2Stream::set_body_to_fetcher(const void *data, size_t len)
-{
-  ink_assert(_fetch_sm != NULL);
-
-  _fetch_sm->ext_write_data(data, len);
-}
-
-bool
-Http2Stream::change_state(uint8_t type, uint8_t flags)
-{
-  switch (_state) {
-  case HTTP2_STREAM_STATE_IDLE:
-    if (type == HTTP2_FRAME_TYPE_HEADERS) {
-      if (end_stream && flags & HTTP2_FLAGS_HEADERS_END_HEADERS) {
-        _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
-      } else {
-        _state = HTTP2_STREAM_STATE_OPEN;
-      }
-    } else if (type == HTTP2_FRAME_TYPE_CONTINUATION) {
-      if (end_stream && flags & HTTP2_FLAGS_CONTINUATION_END_HEADERS) {
-        _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
-      } else {
-        _state = HTTP2_STREAM_STATE_OPEN;
-      }
-    } else if (type == HTTP2_FRAME_TYPE_PUSH_PROMISE) {
-      // XXX Server Push have been supported yet.
-    } else {
-      return false;
-    }
-    break;
-
-  case HTTP2_STREAM_STATE_OPEN:
-    if (type == HTTP2_FRAME_TYPE_RST_STREAM) {
-      _state = HTTP2_STREAM_STATE_CLOSED;
-    } else if (type == HTTP2_FRAME_TYPE_DATA && flags & HTTP2_FLAGS_DATA_END_STREAM) {
-      _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
-    } else {
-      // Currently ATS supports only HTTP/2 server features
-      return false;
-    }
-    break;
-
-  case HTTP2_STREAM_STATE_RESERVED_LOCAL:
-    // Currently ATS supports only HTTP/2 server features
-    return false;
-
-  case HTTP2_STREAM_STATE_RESERVED_REMOTE:
-    // XXX Server Push have been supported yet.
-    return false;
-
-  case HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL:
-    // Currently ATS supports only HTTP/2 server features
-    return false;
-
-  case HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE:
-    if (type == HTTP2_FRAME_TYPE_RST_STREAM || (type == HTTP2_FRAME_TYPE_HEADERS && flags & HTTP2_FLAGS_HEADERS_END_STREAM) ||
-        (type == HTTP2_FRAME_TYPE_DATA && flags & HTTP2_FLAGS_DATA_END_STREAM)) {
-      _state = HTTP2_STREAM_STATE_CLOSED;
-    } else {
-      return false;
-    }
-    break;
-
-  case HTTP2_STREAM_STATE_CLOSED:
-    // No state changing
-    return false;
-
-  default:
-    return false;
-  }
-
-  return true;
-}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/http2/Http2ConnectionState.h
----------------------------------------------------------------------
diff --git a/proxy/http2/Http2ConnectionState.h b/proxy/http2/Http2ConnectionState.h
index a0b5065..200f3d3 100644
--- a/proxy/http2/Http2ConnectionState.h
+++ b/proxy/http2/Http2ConnectionState.h
@@ -27,6 +27,7 @@
 #include "HTTP2.h"
 #include "HPACK.h"
 #include "FetchSM.h"
+#include "Http2Stream.h"
 
 class Http2ClientSession;
 
@@ -94,114 +95,6 @@ private:
   unsigned settings[HTTP2_SETTINGS_MAX - 1];
 };
 
-class Http2ConnectionState;
-
-class Http2Stream
-{
-public:
-  Http2Stream(Http2StreamId sid = 0, ssize_t initial_rwnd = Http2::initial_window_size)
-    : client_rwnd(initial_rwnd), server_rwnd(Http2::initial_window_size), header_blocks(NULL), header_blocks_length(0),
-      request_header_length(0), end_stream(false), _id(sid), _state(HTTP2_STREAM_STATE_IDLE), _fetch_sm(NULL), body_done(false),
-      data_length(0)
-  {
-    _thread = this_ethread();
-    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_STREAM_COUNT, _thread);
-    _start_time = Thread::get_hrtime();
-    // FIXME: Are you sure? every "stream" needs _req_header?
-    _req_header.create(HTTP_TYPE_REQUEST);
-  }
-
-  ~Http2Stream()
-  {
-    HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_STREAM_COUNT, _thread);
-    ink_hrtime end_time = Thread::get_hrtime();
-    HTTP2_SUM_THREAD_DYN_STAT(HTTP2_STAT_TOTAL_TRANSACTIONS_TIME, _thread, end_time - _start_time);
-    _req_header.destroy();
-
-    if (_fetch_sm) {
-      _fetch_sm->ext_destroy();
-      _fetch_sm = NULL;
-    }
-    if (header_blocks) {
-      ats_free(header_blocks);
-    }
-  }
-
-  // Operate FetchSM
-  void init_fetcher(Http2ConnectionState &cstate);
-  void set_body_to_fetcher(const void *data, size_t len);
-  FetchSM *
-  get_fetcher()
-  {
-    return _fetch_sm;
-  }
-  bool
-  is_body_done() const
-  {
-    return body_done;
-  }
-  void
-  mark_body_done()
-  {
-    body_done = true;
-  }
-
-  const Http2StreamId
-  get_id() const
-  {
-    return _id;
-  }
-  const Http2StreamState
-  get_state() const
-  {
-    return _state;
-  }
-  bool change_state(uint8_t type, uint8_t flags);
-
-  int64_t
-  decode_header_blocks(Http2DynamicTable &dynamic_table)
-  {
-    return http2_decode_header_blocks(&_req_header, (const uint8_t *)header_blocks,
-                                      (const uint8_t *)header_blocks + header_blocks_length, dynamic_table);
-  }
-
-  // Check entire DATA payload length if content-length: header is exist
-  void
-  increment_data_length(uint64_t length)
-  {
-    data_length += length;
-  }
-  bool
-  payload_length_is_valid() const
-  {
-    uint32_t content_length = _req_header.get_content_length();
-    return content_length == 0 || content_length == data_length;
-  }
-
-  // Stream level window size
-  ssize_t client_rwnd, server_rwnd;
-
-  LINK(Http2Stream, link);
-
-  uint8_t *header_blocks;
-  uint32_t header_blocks_length;  // total length of header blocks (not include
-                                  // Padding or other fields)
-  uint32_t request_header_length; // total length of payload (include Padding
-                                  // and other fields)
-  bool end_stream;
-
-private:
-  ink_hrtime _start_time;
-  EThread *_thread;
-  Http2StreamId _id;
-  Http2StreamState _state;
-
-  HTTPHdr _req_header;
-  FetchSM *_fetch_sm;
-  bool body_done;
-  uint64_t data_length;
-};
-
 // Http2ConnectionState
 //
 // Capture the semantics of a HTTP/2 connection. The client session captures the

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/http2/Http2Stream.cc
----------------------------------------------------------------------
diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc
new file mode 100644
index 0000000..2ea7020
--- /dev/null
+++ b/proxy/http2/Http2Stream.cc
@@ -0,0 +1,139 @@
+/** @file
+
+  Http2Stream
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "Http2Stream.h"
+#include "Http2ConnectionState.h"
+#include "Http2ClientSession.h"
+
+// Currently use only HTTP/1.1 for requesting to origin server
+const static char *HTTP2_FETCHING_HTTP_VERSION = "HTTP/1.1";
+
+void
+Http2Stream::init_fetcher(Http2ConnectionState &cstate)
+{
+  extern ClassAllocator<FetchSM> FetchSMAllocator;
+
+  // Convert header to HTTP/1.1 format
+  convert_from_2_to_1_1_header(&_req_header);
+
+  // Get null-terminated URL and method
+  Arena arena;
+  int url_len, method_len;
+  const char *url_ref = _req_header.url_get()->string_get_ref(&url_len);
+  const char *url = arena.str_store(url_ref, url_len);
+  const char *method_ref = _req_header.method_get(&method_len);
+  const char *method = arena.str_store(method_ref, method_len);
+
+  // Initialize FetchSM
+  _fetch_sm = FetchSMAllocator.alloc();
+  _fetch_sm->ext_init((Continuation *)cstate.ua_session, method, url, HTTP2_FETCHING_HTTP_VERSION,
+                      cstate.ua_session->get_client_addr(), (TS_FETCH_FLAGS_DECHUNK | TS_FETCH_FLAGS_NOT_INTERNAL_REQUEST));
+
+  // Set request header
+  MIMEFieldIter fiter;
+  for (const MIMEField *field = _req_header.iter_get_first(&fiter); field != NULL; field = _req_header.iter_get_next(&fiter)) {
+    int name_len, value_len;
+    const char *name = field->name_get(&name_len);
+    const char *value = field->value_get(&value_len);
+
+    _fetch_sm->ext_add_header(name, name_len, value, value_len);
+  }
+
+  _fetch_sm->ext_set_user_data(this);
+  _fetch_sm->ext_launch();
+}
+
+void
+Http2Stream::set_body_to_fetcher(const void *data, size_t len)
+{
+  ink_assert(_fetch_sm != NULL);
+
+  _fetch_sm->ext_write_data(data, len);
+}
+
+bool
+Http2Stream::change_state(uint8_t type, uint8_t flags)
+{
+  switch (_state) {
+  case HTTP2_STREAM_STATE_IDLE:
+    if (type == HTTP2_FRAME_TYPE_HEADERS) {
+      if (end_stream && flags & HTTP2_FLAGS_HEADERS_END_HEADERS) {
+        _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
+      } else {
+        _state = HTTP2_STREAM_STATE_OPEN;
+      }
+    } else if (type == HTTP2_FRAME_TYPE_CONTINUATION) {
+      if (end_stream && flags & HTTP2_FLAGS_CONTINUATION_END_HEADERS) {
+        _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
+      } else {
+        _state = HTTP2_STREAM_STATE_OPEN;
+      }
+    } else if (type == HTTP2_FRAME_TYPE_PUSH_PROMISE) {
+      // XXX Server Push have been supported yet.
+    } else {
+      return false;
+    }
+    break;
+
+  case HTTP2_STREAM_STATE_OPEN:
+    if (type == HTTP2_FRAME_TYPE_RST_STREAM) {
+      _state = HTTP2_STREAM_STATE_CLOSED;
+    } else if (type == HTTP2_FRAME_TYPE_DATA && flags & HTTP2_FLAGS_DATA_END_STREAM) {
+      _state = HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
+    } else {
+      // Currently ATS supports only HTTP/2 server features
+      return false;
+    }
+    break;
+
+  case HTTP2_STREAM_STATE_RESERVED_LOCAL:
+    // Currently ATS supports only HTTP/2 server features
+    return false;
+
+  case HTTP2_STREAM_STATE_RESERVED_REMOTE:
+    // XXX Server Push have been supported yet.
+    return false;
+
+  case HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL:
+    // Currently ATS supports only HTTP/2 server features
+    return false;
+
+  case HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE:
+    if (type == HTTP2_FRAME_TYPE_RST_STREAM || (type == HTTP2_FRAME_TYPE_HEADERS && flags & HTTP2_FLAGS_HEADERS_END_STREAM) ||
+        (type == HTTP2_FRAME_TYPE_DATA && flags & HTTP2_FLAGS_DATA_END_STREAM)) {
+      _state = HTTP2_STREAM_STATE_CLOSED;
+    } else {
+      return false;
+    }
+    break;
+
+  case HTTP2_STREAM_STATE_CLOSED:
+    // No state changing
+    return false;
+
+  default:
+    return false;
+  }
+
+  return true;
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/http2/Http2Stream.h
----------------------------------------------------------------------
diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h
new file mode 100644
index 0000000..f47f096
--- /dev/null
+++ b/proxy/http2/Http2Stream.h
@@ -0,0 +1,138 @@
+/** @file
+
+  Http2Stream
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#ifndef __HTTP2_STREAM_H__
+#define __HTTP2_STREAM_H__
+
+#include "HTTP2.h"
+#include "FetchSM.h"
+
+class Http2ConnectionState;
+
+class Http2Stream
+{
+public:
+  Http2Stream(Http2StreamId sid = 0, ssize_t initial_rwnd = Http2::initial_window_size)
+    : client_rwnd(initial_rwnd), server_rwnd(Http2::initial_window_size), header_blocks(NULL), header_blocks_length(0),
+      request_header_length(0), end_stream(false), _id(sid), _state(HTTP2_STREAM_STATE_IDLE), _fetch_sm(NULL), body_done(false),
+      data_length(0)
+  {
+    _thread = this_ethread();
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_STREAM_COUNT, _thread);
+    _start_time = Thread::get_hrtime();
+    // FIXME: Are you sure? every "stream" needs _req_header?
+    _req_header.create(HTTP_TYPE_REQUEST);
+  }
+
+  ~Http2Stream()
+  {
+    HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_CLIENT_STREAM_COUNT, _thread);
+    ink_hrtime end_time = Thread::get_hrtime();
+    HTTP2_SUM_THREAD_DYN_STAT(HTTP2_STAT_TOTAL_TRANSACTIONS_TIME, _thread, end_time - _start_time);
+    _req_header.destroy();
+
+    if (_fetch_sm) {
+      _fetch_sm->ext_destroy();
+      _fetch_sm = NULL;
+    }
+    if (header_blocks) {
+      ats_free(header_blocks);
+    }
+  }
+
+  // Operate FetchSM
+  void init_fetcher(Http2ConnectionState &cstate);
+  void set_body_to_fetcher(const void *data, size_t len);
+  FetchSM *
+  get_fetcher()
+  {
+    return _fetch_sm;
+  }
+  bool
+  is_body_done() const
+  {
+    return body_done;
+  }
+  void
+  mark_body_done()
+  {
+    body_done = true;
+  }
+
+  const Http2StreamId
+  get_id() const
+  {
+    return _id;
+  }
+  const Http2StreamState
+  get_state() const
+  {
+    return _state;
+  }
+  bool change_state(uint8_t type, uint8_t flags);
+
+  int64_t
+  decode_header_blocks(Http2DynamicTable &dynamic_table)
+  {
+    return http2_decode_header_blocks(&_req_header, (const uint8_t *)header_blocks,
+                                      (const uint8_t *)header_blocks + header_blocks_length, dynamic_table);
+  }
+
+  // Check entire DATA payload length if content-length: header is exist
+  void
+  increment_data_length(uint64_t length)
+  {
+    data_length += length;
+  }
+  bool
+  payload_length_is_valid() const
+  {
+    uint32_t content_length = _req_header.get_content_length();
+    return content_length == 0 || content_length == data_length;
+  }
+
+  // Stream level window size
+  ssize_t client_rwnd, server_rwnd;
+
+  LINK(Http2Stream, link);
+
+  uint8_t *header_blocks;
+  uint32_t header_blocks_length;  // total length of header blocks (not include
+                                  // Padding or other fields)
+  uint32_t request_header_length; // total length of payload (include Padding
+                                  // and other fields)
+  bool end_stream;
+
+private:
+  ink_hrtime _start_time;
+  EThread *_thread;
+  Http2StreamId _id;
+  Http2StreamState _state;
+
+  HTTPHdr _req_header;
+  FetchSM *_fetch_sm;
+  bool body_done;
+  uint64_t data_length;
+};
+
+#endif // __HTTP2_STREAM_H__

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cba12825/proxy/http2/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/http2/Makefile.am b/proxy/http2/Makefile.am
index 76fa41c..5d526da 100644
--- a/proxy/http2/Makefile.am
+++ b/proxy/http2/Makefile.am
@@ -40,6 +40,8 @@ libhttp2_a_SOURCES = \
   Http2ClientSession.h \
   Http2ConnectionState.cc \
   Http2ConnectionState.h \
+  Http2Stream.cc \
+  Http2Stream.h \
   Http2SessionAccept.cc \
   Http2SessionAccept.h \
   HuffmanCodec.cc \