trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jpe...@apache.org
Subject [1/2] git commit: TS-2729: update HTTP/2 to h2-14 draft
Date Fri, 03 Oct 2014 20:54:53 GMT
Repository: trafficserver
Updated Branches:
  refs/heads/master 4ace71932 -> 2a84c6b9f


TS-2729: update HTTP/2 to h2-14 draft


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

Branch: refs/heads/master
Commit: fc1ea62c1e7edfd93c8f21f707834eaf032a034f
Parents: 4ace719
Author: Ryo Okubo <rokubo@yahoo-corp.jp>
Authored: Fri Oct 3 13:41:29 2014 -0700
Committer: James Peach <jpeach@apache.org>
Committed: Fri Oct 3 13:53:52 2014 -0700

----------------------------------------------------------------------
 lib/records/RecHttp.cc              |  2 +-
 proxy/http2/HTTP2.cc                | 47 ++++++++++++++++++++------------
 proxy/http2/HTTP2.h                 | 17 ++++++------
 proxy/http2/Http2ConnectionState.cc | 37 ++++++++++++++-----------
 4 files changed, 61 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fc1ea62c/lib/records/RecHttp.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecHttp.cc b/lib/records/RecHttp.cc
index 4e62bb2..788b864 100644
--- a/lib/records/RecHttp.cc
+++ b/lib/records/RecHttp.cc
@@ -36,7 +36,7 @@ SessionProtocolNameRegistry globalSessionProtocolNameRegistry;
 const char * const TS_NPN_PROTOCOL_HTTP_0_9 = "http/0.9";
 const char * const TS_NPN_PROTOCOL_HTTP_1_0 = "http/1.0";
 const char * const TS_NPN_PROTOCOL_HTTP_1_1 = "http/1.1";
-const char * const TS_NPN_PROTOCOL_HTTP_2_0 = "h2-12";    // draft-ietf-httpbis-http2-12
+const char * const TS_NPN_PROTOCOL_HTTP_2_0 = "h2-14";    // draft-ietf-httpbis-http2-14
 const char * const TS_NPN_PROTOCOL_SPDY_1   = "spdy/1";   // obsolete
 const char * const TS_NPN_PROTOCOL_SPDY_2   = "spdy/2";
 const char * const TS_NPN_PROTOCOL_SPDY_3   = "spdy/3";

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fc1ea62c/proxy/http2/HTTP2.cc
----------------------------------------------------------------------
diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
index 567fc3c..59b1e0f 100644
--- a/proxy/http2/HTTP2.cc
+++ b/proxy/http2/HTTP2.cc
@@ -52,6 +52,8 @@ write_and_advance(byte_pointer& dst, uint32_t src)
   dst.u8 += sizeof(pval.bytes);
 }
 
+// Avoid a [-Werror,-Wunused-function] error until we need this overload ...
+#if 0
 static void
 write_and_advance(byte_pointer& dst, uint16_t src)
 {
@@ -61,6 +63,7 @@ write_and_advance(byte_pointer& dst, uint16_t src)
   memcpy(dst.u8, pval.bytes, sizeof(pval.bytes));
   dst.u8 += sizeof(pval.bytes);
 }
+#endif
 
 static void
 write_and_advance(byte_pointer& dst, uint8_t src)
@@ -127,13 +130,14 @@ bool
 http2_settings_parameter_is_valid(const Http2SettingsParameter& param)
 {
   // Static maximum values for Settings parameters.
-  static const unsigned settings_max[HTTP2_SETTINGS_MAX] = {
+  static const uint32_t settings_max[HTTP2_SETTINGS_MAX] = {
     0,
     UINT_MAX, // HTTP2_SETTINGS_HEADER_TABLE_SIZE
     1,        // HTTP2_SETTINGS_ENABLE_PUSH
     UINT_MAX, // HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS
     HTTP2_MAX_WINDOW_SIZE, // HTTP2_SETTINGS_INITIAL_WINDOW_SIZE
-    1,        // HTTP2_SETTINGS_COMPRESS_DATA
+    16777215, // HTTP2_SETTINGS_MAX_FRAME_SIZE
+    UINT_MAX, // HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE
   };
 
   if (param.id == 0 || param.id >= HTTP2_SETTINGS_MAX) {
@@ -149,13 +153,15 @@ http2_settings_parameter_is_valid(const Http2SettingsParameter&
param)
 
 // 4.1.  Frame Format
 //
-// 0                   1                   2                   3
-// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+//  0                   1                   2                   3
+//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | R |     Length (14)           |   Type (8)    |   Flags (8)   |
+// |                 Length (24)                   |
+// +---------------+---------------+---------------+
+// |   Type (8)    |   Flags (8)   |
 // +-+-+-----------+---------------+-------------------------------+
 // |R|                 Stream Identifier (31)                      |
-// +-+-------------------------------------------------------------+
+// +=+=============================================================+
 // |                   Frame Payload (0...)                      ...
 // +---------------------------------------------------------------+
 
@@ -163,21 +169,20 @@ bool
 http2_parse_frame_header(IOVec iov, Http2FrameHeader& hdr)
 {
   byte_pointer ptr(iov.iov_base);
-  byte_addressable_value<uint16_t> length;
+  byte_addressable_value<uint32_t> length_and_type;
   byte_addressable_value<uint32_t> streamid;
 
   if (unlikely(iov.iov_len < HTTP2_FRAME_HEADER_LEN)) {
     return false;
   }
 
-  memcpy_and_advance(length.bytes, ptr);
-  memcpy_and_advance(hdr.type, ptr);
+  memcpy_and_advance(length_and_type.bytes, ptr);
   memcpy_and_advance(hdr.flags, ptr);
   memcpy_and_advance(streamid.bytes, ptr);
 
-  length.bytes[0] &= 0x3F;  // Clear the 2 reserved high bits
+  hdr.length = ntohl(length_and_type.value) >> 8;
+  hdr.type = ntohl(length_and_type.value) & 0xff;
   streamid.bytes[0] &= 0x7f;// Clear the high reserved bit
-  hdr.length = ntohs(length.value);
   hdr.streamid = ntohl(streamid.value);
 
   return true;
@@ -192,7 +197,13 @@ http2_write_frame_header(const Http2FrameHeader& hdr, IOVec iov)
     return false;
   }
 
-  write_and_advance(ptr, hdr.length);
+  byte_addressable_value<uint32_t> length;
+  length.value = htonl(hdr.length);
+  // MSB length.bytes[0] is unused.
+  write_and_advance(ptr, length.bytes[1]);
+  write_and_advance(ptr, length.bytes[2]);
+  write_and_advance(ptr, length.bytes[3]);
+
   write_and_advance(ptr, hdr.type);
   write_and_advance(ptr, hdr.flags);
   write_and_advance(ptr, hdr.streamid);
@@ -232,24 +243,26 @@ http2_write_goaway(const Http2Goaway& goaway, IOVec iov)
 // 0                   1                   2                   3
 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | Identifier (8)|        Value (32)                             |
-// +---------------+-----------------------------------------------+
-// |               |
-// +---------------+
+// |       Identifier (16)         |
+// +-------------------------------+-------------------------------+
+// |                        Value (32)                             |
+// +---------------------------------------------------------------+
 
 bool
 http2_parse_settings_parameter(IOVec iov, Http2SettingsParameter& param)
 {
   byte_pointer ptr(iov.iov_base);
+  byte_addressable_value<uint16_t> pid;
   byte_addressable_value<uint32_t> pval;
 
   if (unlikely(iov.iov_len < HTTP2_SETTINGS_PARAMETER_LEN)) {
     return false;
   }
 
-  memcpy_and_advance(param.id, ptr);
+  memcpy_and_advance(pid.bytes, ptr);
   memcpy_and_advance(pval.bytes, ptr);
 
+  param.id = ntohs(pid.value);
   param.value = ntohl(pval.value);
 
   return true;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fc1ea62c/proxy/http2/HTTP2.h
----------------------------------------------------------------------
diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h
index c7c2fec..306d69d 100644
--- a/proxy/http2/HTTP2.h
+++ b/proxy/http2/HTTP2.h
@@ -36,9 +36,9 @@ typedef int32_t Http2WindowSize;
 extern const char * const HTTP2_CONNECTION_PREFACE;
 const size_t HTTP2_CONNECTION_PREFACE_LEN = 24;
 
-const size_t HTTP2_FRAME_HEADER_LEN = 8;
+const size_t HTTP2_FRAME_HEADER_LEN = 9;
 const size_t HTTP2_GOAWAY_LEN = 8;
-const size_t HTTP2_SETTINGS_PARAMETER_LEN = 5;
+const size_t HTTP2_SETTINGS_PARAMETER_LEN = 6;
 
 // 4.2. Frame Size. The absolute maximum size of a frame payload is 2^14-1 (16,383) octets.
 const size_t HTTP2_MAX_FRAME_PAYLOAD = 16383;
@@ -183,7 +183,8 @@ enum Http2SettingsIdentifier
   HTTP2_SETTINGS_ENABLE_PUSH = 2,
   HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 3,
   HTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 4,
-  HTTP2_SETTINGS_COMPRESS_DATA = 5,
+  HTTP2_SETTINGS_MAX_FRAME_SIZE = 5,
+  HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 6,
 
   HTTP2_SETTINGS_MAX
 };
@@ -191,16 +192,16 @@ enum Http2SettingsIdentifier
 // 4.1. Frame Format
 struct Http2FrameHeader
 {
-  uint16_t      length;
-  uint8_t       type;
-  uint8_t       flags;
-  Http2StreamId streamid;
+  uint32_t         length;
+  uint8_t          type;
+  uint8_t          flags;
+  Http2StreamId    streamid;
 };
 
 // 6.5.1. SETTINGS Format
 struct Http2SettingsParameter
 {
-  uint8_t   id;
+  uint16_t  id;
   uint32_t  value;
 };
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fc1ea62c/proxy/http2/Http2ConnectionState.cc
----------------------------------------------------------------------
diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
index afbbceb..cb9640e 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -30,6 +30,22 @@
 
 typedef Http2ErrorCode (*http2_frame_dispatch)(Http2ClientSession&, Http2ConnectionState&,
const Http2Frame&);
 
+static const int buffer_size_index[HTTP2_FRAME_TYPE_MAX] =
+{
+  -1,   // HTTP2_FRAME_TYPE_DATA
+  -1,   // HTTP2_FRAME_TYPE_HEADERS
+  -1,   // HTTP2_FRAME_TYPE_PRIORITY
+  -1,   // HTTP2_FRAME_TYPE_RST_STREAM
+  BUFFER_SIZE_INDEX_128,   // HTTP2_FRAME_TYPE_SETTINGS
+  -1,   // HTTP2_FRAME_TYPE_PUSH_PROMISE
+  -1,   // HTTP2_FRAME_TYPE_PING
+  BUFFER_SIZE_INDEX_128,   // HTTP2_FRAME_TYPE_GOAWAY
+  -1,   // HTTP2_FRAME_TYPE_WINDOW_UPDATE
+  -1,   // HTTP2_FRAME_TYPE_CONTINUATION
+  -1,   // HTTP2_FRAME_TYPE_ALTSVC
+  -1,   // HTTP2_FRAME_TYPE_BLOCKED
+};
+
 static Http2ErrorCode
 rcv_settings_frame(Http2ClientSession& cs, Http2ConnectionState& cstate, const Http2Frame&
frame)
 {
@@ -69,25 +85,14 @@ rcv_settings_frame(Http2ClientSession& cs, Http2ConnectionState&
cstate, const H
     cstate.client_settings.set((Http2SettingsIdentifier)param.id, param.value);
   }
 
+  // 6.5 Once all values have been applied, the recipient MUST immediately emit a
+  // SETTINGS frame with the ACK flag set.
+  Http2Frame ackFrame(HTTP2_FRAME_TYPE_SETTINGS, 0, HTTP2_FLAGS_SETTINGS_ACK);
+  cstate.ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &ackFrame);
+
   return HTTP2_ERROR_NO_ERROR;
 }
 
-static const int buffer_size_index[HTTP2_FRAME_TYPE_MAX] =
-{
-  -1,   // HTTP2_FRAME_TYPE_DATA
-  -1,   // HTTP2_FRAME_TYPE_HEADERS
-  -1,   // HTTP2_FRAME_TYPE_PRIORITY
-  -1,   // HTTP2_FRAME_TYPE_RST_STREAM
-  -1,   // HTTP2_FRAME_TYPE_SETTINGS
-  -1,   // HTTP2_FRAME_TYPE_PUSH_PROMISE
-  -1,   // HTTP2_FRAME_TYPE_PING
-  BUFFER_SIZE_INDEX_128,   // HTTP2_FRAME_TYPE_GOAWAY
-  -1,   // HTTP2_FRAME_TYPE_WINDOW_UPDATE
-  -1,   // HTTP2_FRAME_TYPE_CONTINUATION
-  -1,   // HTTP2_FRAME_TYPE_ALTSVC
-  -1,   // HTTP2_FRAME_TYPE_BLOCKED
-};
-
 static const http2_frame_dispatch frame_handlers[HTTP2_FRAME_TYPE_MAX] =
 {
   NULL,   // HTTP2_FRAME_TYPE_DATA


Mime
View raw message