You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by je...@apache.org on 2015/04/12 23:52:36 UTC
[3/8] mina git commit: Multiple HTTP2 PDUs
Multiple HTTP2 PDUs
Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/27938fb1
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/27938fb1
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/27938fb1
Branch: refs/heads/trunk
Commit: 27938fb1e54c5e93ea14da20da03856ee395681e
Parents: 9979693
Author: Jeff MAURY <je...@apache.org>
Authored: Mon Mar 23 22:43:42 2015 +0100
Committer: Jeff MAURY <je...@apache.org>
Committed: Mon Mar 23 22:43:42 2015 +0100
----------------------------------------------------------------------
.../apache/mina/http2/api/Http2Constants.java | 2 +
.../mina/http2/api/Http2ContinuationFrame.java | 68 +++++++++
.../apache/mina/http2/api/Http2DataFrame.java | 87 +++++++++++
.../org/apache/mina/http2/api/Http2Frame.java | 120 +++++++--------
.../api/Http2FrameHeadePartialDecoder.java | 106 ++++++++++++++
.../apache/mina/http2/api/Http2GoAwayFrame.java | 104 +++++++++++++
.../mina/http2/api/Http2HeadersFrame.java | 145 +++++++++++++++++++
.../apache/mina/http2/api/Http2PingFrame.java | 66 +++++++++
.../mina/http2/api/Http2PriorityFrame.java | 105 ++++++++++++++
.../mina/http2/api/Http2PushPromiseFrame.java | 107 ++++++++++++++
.../mina/http2/api/Http2RstStreamFrame.java | 66 +++++++++
.../mina/http2/api/Http2SettingsFrame.java | 68 +++++++++
.../mina/http2/api/Http2UnknownFrame.java | 66 +++++++++
.../mina/http2/api/Http2WindowUpdateFrame.java | 66 +++++++++
.../apache/mina/http2/impl/Http2Connection.java | 77 +++++++++-
.../impl/Http2ContinuationFrameDecoder.java | 51 +++++++
.../mina/http2/impl/Http2DataFrameDecoder.java | 96 ++++++++++++
.../mina/http2/impl/Http2FrameDecoder.java | 82 +++--------
.../http2/impl/Http2GoAwayFrameDecoder.java | 82 +++++++++++
.../http2/impl/Http2HeadersFrameDecoder.java | 117 +++++++++++++++
.../mina/http2/impl/Http2PingFrameDecoder.java | 70 +++++++++
.../http2/impl/Http2PriorityFrameDecoder.java | 83 +++++++++++
.../impl/Http2PushPromiseFrameDecoder.java | 101 +++++++++++++
.../http2/impl/Http2RstStreamFrameDecoder.java | 75 ++++++++++
.../http2/impl/Http2SettingsFrameDecoder.java | 64 ++++++++
.../http2/impl/Http2UnknownFrameDecoder.java | 52 +++++++
.../impl/Http2WindowUpdateFrameDecoder.java | 73 ++++++++++
.../api/Htp2PushPromiseFrameDecoderTest.java | 45 ++----
.../api/Http2FrameHeaderPartialDecoderTest.java | 2 -
29 files changed, 2089 insertions(+), 157 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
index ba8a8fe..3bf58f6 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
@@ -190,4 +190,6 @@ public final class Http2Constants {
public static final Charset US_ASCII_CHARSET = Charset.forName("US-ASCII");
+ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
new file mode 100644
index 0000000..0138d17
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2ContinuationFrame extends Http2Frame {
+
+ private final byte[] headerBlockFragment;
+
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+
+ protected <T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> Http2ContinuationFrame(AbstractHttp2ContinuationFrameBuilder<T, V> builder) {
+ super(builder);
+ this.headerBlockFragment = builder.getHeaderBlockFragment();
+ }
+
+
+ public static abstract class AbstractHttp2ContinuationFrameBuilder<T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] headerBlockFragment = new byte[0];
+
+ @SuppressWarnings("unchecked")
+ public T headerBlockFragment(byte[] headerBlockFragment) {
+ this.headerBlockFragment = headerBlockFragment;
+ return (T) this;
+ }
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2ContinuationFrameBuilder<Builder, Http2ContinuationFrame> {
+
+ @Override
+ public Http2ContinuationFrame build() {
+ return new Http2ContinuationFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
new file mode 100644
index 0000000..2a4802d
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2DataFrame extends Http2Frame {
+ private final byte[] data;
+
+ private final byte[] padding;
+
+ public byte[] getData() {
+ return data;
+ }
+
+ public byte[] getPadding() {
+ return padding;
+ }
+
+ protected <T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> Http2DataFrame(AbstractHttp2DataFrameBuilder<T, V> builder) {
+ super(builder);
+ this.data = builder.getData();
+ this.padding = builder.getPadding();
+ }
+
+
+ public static abstract class AbstractHttp2DataFrameBuilder<T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] data = EMPTY_BYTE_ARRAY;
+
+ private byte[] padding = EMPTY_BYTE_ARRAY;
+
+ @SuppressWarnings("unchecked")
+ public T data(byte[] data) {
+ this.data = data;
+ return (T) this;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T padding(byte[] padding) {
+ this.padding = padding;
+ return (T) this;
+ }
+
+ public byte[] getPadding() {
+ return padding;
+ }
+}
+
+ public static class Builder extends AbstractHttp2DataFrameBuilder<Builder, Http2Frame> {
+
+ @Override
+ public Http2Frame build() {
+ return new Http2DataFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
index b6a3ed2..356c2b8 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
@@ -20,89 +20,93 @@
package org.apache.mina.http2.api;
/**
- * An SPY frame
+ * An SPY data frame
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*
*/
-public class Http2Frame {
- private int length;
+public abstract class Http2Frame {
+
+ private final int length;
- private short type;
+ private final short type;
- private short flags;
+ private final short flags;
- private int streamID;
+ private final int streamID;
- public byte[] payload;
-
- /**
- * @return the length
- */
public int getLength() {
return length;
}
- /**
- * @param length the length to set
- */
- public void setLength(int length) {
- this.length = length;
- }
-
- /**
- * @return the type
- */
public short getType() {
return type;
}
-
- /**
- * @param type the type to set
- */
- public void setType(short type) {
- this.type = type;
- }
-
- /**
- * @return the flags
- */
+
public short getFlags() {
return flags;
}
- /**
- * @param flags the flags to set
- */
- public void setFlags(short flags) {
- this.flags = flags;
- }
-
- /**
- * @return the streamID
- */
public int getStreamID() {
return streamID;
}
- /**
- * @param streamID the streamID to set
- */
- public void setStreamID(int streamID) {
- this.streamID = streamID;
+ protected <T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame> Http2Frame(AbstractHttp2FrameBuilder<T, V> builder) {
+ this.length = builder.getLength();
+ this.type = builder.getType();
+ this.flags = builder.getFlags();
+ this.streamID = builder.getStreamID();
}
- /**
- * @return the payload
- */
- public byte[] getPayload() {
- return payload;
- }
+ public static abstract class AbstractHttp2FrameBuilder<T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame> {
+ private int length;
+
+ private short type;
+
+ private short flags;
+
+ private int streamID;
+
+ @SuppressWarnings("unchecked")
+ public T length(int length) {
+ this.length = length;
+ return (T) this;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T type(short type) {
+ this.type = type;
+ return (T) this;
+ }
+
+ public short getType() {
+ return type;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T flags(short flags) {
+ this.flags = flags;
+ return (T) this;
+ }
+
+ public short getFlags() {
+ return flags;
+ }
- /**
- * @param payload the payload to set
- */
- public void setPayload(byte[] payload) {
- this.payload = payload;
+ @SuppressWarnings("unchecked")
+ public T streamID(int streamID) {
+ this.streamID = streamID;
+ return (T) this;
+ }
+
+ public int getStreamID() {
+ return streamID;
+ }
+
+ public abstract V build();
}
}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
new file mode 100644
index 0000000..059f193
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
@@ -0,0 +1,106 @@
+/**
+ *
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2FrameHeadePartialDecoder implements PartialDecoder<Http2FrameHeadePartialDecoder.Http2FrameHeader> {
+ public static class Http2FrameHeader {
+ private int length;
+ private short type;
+ private byte flags;
+ private int streamID;
+
+ public int getLength() {
+ return length;
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public short getType() {
+ return type;
+ }
+
+ public void setType(short type) {
+ this.type = type;
+ }
+
+ public byte getFlags() {
+ return flags;
+ }
+
+ public void setFlags(byte flags) {
+ this.flags = flags;
+ }
+
+ public int getStreamID() {
+ return streamID;
+ }
+
+ public void setStreamID(int streamID) {
+ this.streamID = streamID;
+ }
+ }
+
+ private static enum State {
+ LENGTH,
+ TYPE_FLAGS,
+ STREAMID,
+ END
+ }
+
+ private State state;
+ private PartialDecoder<?> decoder;
+ private Http2FrameHeader value;
+
+ public Http2FrameHeadePartialDecoder() {
+ reset();
+ }
+
+ public boolean consume(ByteBuffer buffer) {
+ while (buffer.hasRemaining() && state != State.END) {
+ if (decoder.consume(buffer)) {
+ switch (state) {
+ case LENGTH:
+ value.setLength(((IntPartialDecoder)decoder).getValue().intValue());
+ decoder = new BytePartialDecoder(2);
+ state = State.TYPE_FLAGS;
+ break;
+ case TYPE_FLAGS:
+ value.setType(((BytePartialDecoder)decoder).getValue()[0]);
+ value.setFlags(((BytePartialDecoder)decoder).getValue()[1]);
+ decoder = new IntPartialDecoder(4);
+ state = State.STREAMID;
+ break;
+ case STREAMID:
+ value.setStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+ state = State.END;
+ break;
+ }
+ }
+ }
+ return state == State.END;
+ }
+
+ public Http2FrameHeader getValue() {
+ return value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ state = State.LENGTH;
+ decoder = new IntPartialDecoder(3);
+ value = new Http2FrameHeader();
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
new file mode 100644
index 0000000..fbc5ea1
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2GoAwayFrame extends Http2Frame {
+ private final int lastStreamID;
+
+ private final int errorCode;
+
+ private byte[] data;
+
+ public int getLastStreamID() {
+ return lastStreamID;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ protected <T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> Http2GoAwayFrame(AbstractHttp2GoAwayFrameBuilder<T, V> builder) {
+ super(builder);
+ this.lastStreamID = builder.getLastStreamID();
+ this.errorCode = builder.getErrorCode();
+ this.data = builder.getData();
+ }
+
+
+ public static abstract class AbstractHttp2GoAwayFrameBuilder<T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private int lastStreamID;
+
+ private int errorCode;
+
+ private byte[] data;
+
+ @SuppressWarnings("unchecked")
+ public T lastStreamID(int lastStreamID) {
+ this.lastStreamID = lastStreamID;
+ return (T) this;
+ }
+
+ public int getLastStreamID() {
+ return lastStreamID;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T errorCode(int errorCode) {
+ this.errorCode = errorCode;
+ return (T) this;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T data(byte[] data) {
+ this.data = data;
+ return (T) this;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2GoAwayFrameBuilder<Builder, Http2GoAwayFrame> {
+
+ @Override
+ public Http2GoAwayFrame build() {
+ return new Http2GoAwayFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
new file mode 100644
index 0000000..aadb1bc
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2HeadersFrame extends Http2Frame {
+
+ private final byte[] padding;
+
+ private final int streamDependencyID;
+
+ private final boolean exclusiveMode;
+
+ private final byte weight;
+
+ private final byte[] headerBlockFragment;
+
+
+ public byte[] getPadding() {
+ return padding;
+ }
+
+ public int getStreamDependencyID() {
+ return streamDependencyID;
+ }
+
+ public boolean getExclusiveMode() {
+ return exclusiveMode;
+ }
+
+ public byte getWeight() {
+ return weight;
+ }
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+
+ protected <T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> Http2HeadersFrame(AbstractHttp2HeadersFrameBuilder<T, V> builder) {
+ super(builder);
+ this.padding = builder.getPadding();
+ this.streamDependencyID = builder.getStreamDependencyID();
+ this.exclusiveMode = builder.getExclusiveMode();
+ this.weight = builder.getWeight();
+ this.headerBlockFragment = builder.getHeaderBlockFragment();
+ }
+
+
+ public static abstract class AbstractHttp2HeadersFrameBuilder<T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] padding;
+
+ private int streamDependencyID;
+
+ private byte weight;
+
+ private byte[] headerBlockFragment;
+
+ private boolean exclusiveMode;
+
+ @SuppressWarnings("unchecked")
+ public T padding(byte[] padding) {
+ this.padding = padding;
+ return (T) this;
+ }
+
+ public byte[] getPadding() {
+ return padding;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T streamDependencyID(int streamDependencyID) {
+ this.streamDependencyID = streamDependencyID;
+ return (T) this;
+ }
+
+ public int getStreamDependencyID() {
+ return streamDependencyID;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T exclusiveMode(boolean exclusiveMode) {
+ this.exclusiveMode = exclusiveMode;
+ return (T) this;
+ }
+
+ public boolean getExclusiveMode() {
+ return exclusiveMode;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T weight(byte weight) {
+ this.weight = weight;
+ return (T) this;
+ }
+
+ public byte getWeight() {
+ return weight;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T headerBlockFragment(byte[] headerBlockFragment) {
+ this.headerBlockFragment = headerBlockFragment;
+ return (T) this;
+ }
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2HeadersFrameBuilder<Builder, Http2HeadersFrame> {
+
+ @Override
+ public Http2HeadersFrame build() {
+ return new Http2HeadersFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
new file mode 100644
index 0000000..c1df709
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2PingFrame extends Http2Frame {
+ private final byte[] data;
+
+ public byte[] getData() {
+ return data;
+ }
+
+ protected <T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> Http2PingFrame(AbstractHttp2PingFrameBuilder<T, V> builder) {
+ super(builder);
+ this.data = builder.getData();
+ }
+
+
+ public static abstract class AbstractHttp2PingFrameBuilder<T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] data;
+
+ @SuppressWarnings("unchecked")
+ public T data(byte[] data) {
+ this.data = data;
+ return (T) this;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2PingFrameBuilder<Builder, Http2PingFrame> {
+
+ @Override
+ public Http2PingFrame build() {
+ return new Http2PingFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
new file mode 100644
index 0000000..5478c69
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2PriorityFrame extends Http2Frame {
+ private final int streamDependencyID;
+
+ private boolean exclusiveMode;
+
+ private final short weight;
+
+ public int getStreamDependencyID() {
+ return streamDependencyID;
+ }
+
+ public boolean getExclusiveMode() {
+ return exclusiveMode;
+ }
+
+ public short getWeight() {
+ return weight;
+ }
+
+ protected <T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> Http2PriorityFrame(AbstractHttp2PriorityFrameBuilder<T, V> builder) {
+ super(builder);
+ this.streamDependencyID = builder.getStreamDependencyID();
+ this.exclusiveMode = builder.exclusiveMode;
+ this.weight = builder.getWeight();
+ }
+
+
+ public static abstract class AbstractHttp2PriorityFrameBuilder<T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private int streamDependencyID;
+
+ private boolean exclusiveMode;
+
+ private short weight;
+
+ @SuppressWarnings("unchecked")
+ public T streamDependencyID(int streamDependencyID) {
+ this.streamDependencyID = streamDependencyID;
+ return (T) this;
+ }
+
+ public int getStreamDependencyID() {
+ return streamDependencyID;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T exclusiveMode(boolean exclusiveMode) {
+ this.exclusiveMode = exclusiveMode;
+ return (T) this;
+ }
+
+ public boolean getExclusiveMode() {
+ return exclusiveMode;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public T weight(short weight) {
+ this.weight = weight;
+ return (T) this;
+ }
+
+ public short getWeight() {
+ return weight;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2PriorityFrameBuilder<Builder, Http2PriorityFrame> {
+
+ @Override
+ public Http2PriorityFrame build() {
+ return new Http2PriorityFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
new file mode 100644
index 0000000..a2ab2c7
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2PushPromiseFrame extends Http2Frame {
+
+ private final byte[] padding;
+
+ private final int promisedStreamID;
+
+ private final byte[] headerBlockFragment;
+
+
+ public byte[] getPadding() {
+ return padding;
+ }
+
+ public int getPromisedStreamID() {
+ return promisedStreamID;
+ }
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+
+ protected <T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> Http2PushPromiseFrame(AbstractHttp2PushPromiseFrameBuilder<T, V> builder) {
+ super(builder);
+ this.padding = builder.getPadding();
+ this.promisedStreamID = builder.getPromisedStreamID();
+ this.headerBlockFragment = builder.getHeaderBlockFragment();
+ }
+
+ public static abstract class AbstractHttp2PushPromiseFrameBuilder<T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] padding = EMPTY_BYTE_ARRAY;
+
+ private int promisedStreamID;
+
+ private byte[] headerBlockFragment = EMPTY_BYTE_ARRAY;
+
+ @SuppressWarnings("unchecked")
+ public T padding(byte[] padding) {
+ this.padding = padding;
+ return (T) this;
+ }
+
+ public byte[] getPadding() {
+ return padding;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T promisedStreamID(int promisedStreamID) {
+ this.promisedStreamID = promisedStreamID;
+ return (T) this;
+ }
+
+ public int getPromisedStreamID() {
+ return promisedStreamID;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T headerBlockFragment(byte[] headerBlockFragment) {
+ this.headerBlockFragment = headerBlockFragment;
+ return (T) this;
+ }
+
+ public byte[] getHeaderBlockFragment() {
+ return headerBlockFragment;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2PushPromiseFrameBuilder<Builder, Http2PushPromiseFrame> {
+
+ @Override
+ public Http2PushPromiseFrame build() {
+ return new Http2PushPromiseFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
new file mode 100644
index 0000000..1536594
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2RstStreamFrame extends Http2Frame {
+ private final long errorCode;
+
+ public long getErrorCode() {
+ return errorCode;
+ }
+
+ protected <T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> Http2RstStreamFrame(AbstractHttp2RstStreamFrameBuilder<T, V> builder) {
+ super(builder);
+ this.errorCode = builder.getErrorCode();
+ }
+
+
+ public static abstract class AbstractHttp2RstStreamFrameBuilder<T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private long errorCode;
+
+ @SuppressWarnings("unchecked")
+ public T errorCode(long errorCode) {
+ this.errorCode = errorCode;
+ return (T) this;
+ }
+
+ public long getErrorCode() {
+ return errorCode;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2RstStreamFrameBuilder<Builder, Http2RstStreamFrame> {
+
+ @Override
+ public Http2RstStreamFrame build() {
+ return new Http2RstStreamFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
new file mode 100644
index 0000000..66c44ba
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+import java.util.Collection;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2SettingsFrame extends Http2Frame {
+ private final Collection<Http2Setting> settings;
+
+ public Collection<Http2Setting> getSettings() {
+ return settings;
+ }
+
+ protected <T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> Http2SettingsFrame(AbstractHttp2SettingsFrameBuilder<T, V> builder) {
+ super(builder);
+ this.settings = builder.getSettings();
+ }
+
+
+ public static abstract class AbstractHttp2SettingsFrameBuilder<T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private Collection<Http2Setting> settings;
+
+ @SuppressWarnings("unchecked")
+ public T settings(Collection<Http2Setting> settings) {
+ this.settings = settings;
+ return (T) this;
+ }
+
+ public Collection<Http2Setting> getSettings() {
+ return settings;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2SettingsFrameBuilder<Builder, Http2SettingsFrame> {
+
+ @Override
+ public Http2SettingsFrame build() {
+ return new Http2SettingsFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
new file mode 100644
index 0000000..1cdcaef
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2UnknownFrame extends Http2Frame {
+ private final byte[] payload;
+
+ public byte[] getPayload() {
+ return payload;
+ }
+
+ protected <T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> Http2UnknownFrame(AbstractHttp2UnknownFrameBuilder<T, V> builder) {
+ super(builder);
+ this.payload = builder.getPayload();
+ }
+
+
+ public static abstract class AbstractHttp2UnknownFrameBuilder<T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private byte[] payload = new byte[0];
+
+ @SuppressWarnings("unchecked")
+ public T payload(byte[] payload) {
+ this.payload = payload;
+ return (T) this;
+ }
+
+ public byte[] getPayload() {
+ return payload;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2UnknownFrameBuilder<Builder, Http2UnknownFrame> {
+
+ @Override
+ public Http2UnknownFrame build() {
+ return new Http2UnknownFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
new file mode 100644
index 0000000..f552aaf
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.mina.http2.api;
+
+/**
+ * An SPY data frame
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ *
+ */
+public class Http2WindowUpdateFrame extends Http2Frame {
+ private final int windowUpdateIncrement;
+
+ public int getWindowUpdateIncrement() {
+ return windowUpdateIncrement;
+ }
+
+ protected <T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> Http2WindowUpdateFrame(AbstractHttp2WindowUpdateFrameBuilder<T, V> builder) {
+ super(builder);
+ this.windowUpdateIncrement = builder.getWindowUpdateIncrement();
+ }
+
+
+ public static abstract class AbstractHttp2WindowUpdateFrameBuilder<T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> extends AbstractHttp2FrameBuilder<T,V> {
+ private int windowUpdateIncrement;
+
+ @SuppressWarnings("unchecked")
+ public T windowUpdateIncrement(int windowUpdateIncrement) {
+ this.windowUpdateIncrement = windowUpdateIncrement;
+ return (T) this;
+ }
+
+ public int getWindowUpdateIncrement() {
+ return windowUpdateIncrement;
+ }
+ }
+
+ public static class Builder extends AbstractHttp2WindowUpdateFrameBuilder<Builder, Http2WindowUpdateFrame> {
+
+ @Override
+ public Http2WindowUpdateFrame build() {
+ return new Http2WindowUpdateFrame(this);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
index 3019b20..9ec5b4f 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
@@ -3,10 +3,29 @@ package org.apache.mina.http2.impl;
import java.nio.ByteBuffer;
import org.apache.mina.http2.api.Http2Frame;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_DATA;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_HEADERS;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_RST_STREAM;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_SETTINGS;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PUSH_PROMISE;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PING;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_GOAWAY;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_WINDOW_UPDATE;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_CONTINUATION;
public class Http2Connection {
- private final Http2FrameDecoder decoder = new Http2FrameDecoder();
+ private static enum DecoderState {
+ HEADER,
+ FRAME
+ }
+
+ private final Http2FrameHeadePartialDecoder headerDecoder = new Http2FrameHeadePartialDecoder();
+ private Http2FrameDecoder frameDecoder;
+ private DecoderState decoderState = DecoderState.HEADER;
/**
* Decode the incoming message and if all frame data has been received,
@@ -17,9 +36,59 @@ public class Http2Connection {
*/
public Http2Frame decode(ByteBuffer input) {
Http2Frame frame = null;
- if (decoder.consume(input)) {
- frame = decoder.getValue();
- decoder.reset();
+ switch (decoderState) {
+ case HEADER:
+ if (headerDecoder.consume(input)) {
+ Http2FrameHeader header = headerDecoder.getValue();
+ headerDecoder.reset();
+ decoderState = DecoderState.FRAME;
+ switch (header.getType()) {
+ case FRAME_TYPE_DATA:
+ frameDecoder = new Http2DataFrameDecoder(header);
+ break;
+ case FRAME_TYPE_HEADERS:
+ frameDecoder = new Http2HeadersFrameDecoder(header);
+ break;
+ case FRAME_TYPE_PRIORITY:
+ frameDecoder = new Http2PriorityFrameDecoder(header);
+ break;
+ case FRAME_TYPE_RST_STREAM:
+ frameDecoder = new Http2RstStreamFrameDecoder(header);
+ break;
+ case FRAME_TYPE_SETTINGS:
+ frameDecoder =new Http2SettingsFrameDecoder(header);
+ break;
+ case FRAME_TYPE_PUSH_PROMISE:
+ frameDecoder = new Http2PushPromiseFrameDecoder(header);
+ break;
+ case FRAME_TYPE_PING:
+ frameDecoder = new Http2PingFrameDecoder(header);
+ break;
+ case FRAME_TYPE_GOAWAY:
+ frameDecoder = new Http2GoAwayFrameDecoder(header);
+ break;
+ case FRAME_TYPE_WINDOW_UPDATE:
+ frameDecoder = new Http2WindowUpdateFrameDecoder(header);
+ break;
+ case FRAME_TYPE_CONTINUATION:
+ frameDecoder = new Http2ContinuationFrameDecoder(header);
+ break;
+ default:
+ frameDecoder = new Http2UnknownFrameDecoder(header);
+ break;
+ }
+ if (frameDecoder.consume(input)) {
+ frame = frameDecoder.getValue();
+ decoderState = DecoderState.HEADER;
+ }
+ }
+ break;
+ case FRAME:
+ if (frameDecoder.consume(input)) {
+ frame = frameDecoder.getValue();
+ decoderState = DecoderState.HEADER;
+ }
+ break;
}
return frame;
}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
new file mode 100644
index 0000000..39f6706
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
@@ -0,0 +1,51 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2ContinuationFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2ContinuationFrameDecoder extends Http2FrameDecoder {
+
+ private BytePartialDecoder decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2ContinuationFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ initBuilder(builder);
+ if (header.getLength() > 0) {
+ decoder = new BytePartialDecoder(header.getLength());
+ } else {
+ setValue(builder.build());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ if ((decoder != null) && decoder.consume(buffer)) {
+ builder.headerBlockFragment(decoder.getValue());
+ setValue(builder.build());
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
new file mode 100644
index 0000000..7a07812
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
@@ -0,0 +1,96 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2DataFrame.Builder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2DataFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ PAD_LENGTH,
+ DATA,
+ PADDING
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private int padLength;
+
+ private Builder builder = new Builder();
+
+ public Http2DataFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ initBuilder(builder);
+ if (isFlagSet(FLAGS_PADDING)) {
+ state = State.PAD_LENGTH;
+ } else if (header.getLength() > 0) {
+ state = State.DATA;
+ decoder = new BytePartialDecoder(header.getLength());
+ } else {
+ setValue(builder.build());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case PAD_LENGTH:
+ padLength = buffer.get();
+ if ((getHeader().getLength() - 1 - padLength) > 0) {
+ state = State.DATA;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 1 - padLength);
+ } else if (padLength > 0) {
+ state = State.PADDING;
+ decoder = new BytePartialDecoder(padLength);
+ } else {
+ setValue(builder.build());
+ }
+ break;
+ case DATA:
+ if (decoder.consume(buffer)) {
+ builder.data(((BytePartialDecoder)decoder).getValue());
+ if (isFlagSet(FLAGS_PADDING) && (padLength > 0)) {
+ state = State.PADDING;
+ decoder = new BytePartialDecoder(padLength);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case PADDING:
+ if (decoder.consume(buffer)) {
+ builder.padding(((BytePartialDecoder)decoder).getValue());
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
index ba32afc..e59c41e 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
@@ -3,86 +3,50 @@
*/
package org.apache.mina.http2.impl;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.api.BytePartialDecoder;
import org.apache.mina.http2.api.Http2Frame;
-import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.Http2Frame.AbstractHttp2FrameBuilder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
import org.apache.mina.http2.api.PartialDecoder;
-import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
-
/**
* @author jeffmaury
*
*/
-public class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
+public abstract class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
+ private Http2FrameHeader header;
+
+ private Http2Frame frame;
- private static enum State {
- LENGTH_TYPE_FLAGS,
- STREAMID,
- PAYLOAD
+ public Http2FrameDecoder(Http2FrameHeader header) {
+ this.header = header;
}
- private State state;
-
- private PartialDecoder<?> decoder;
-
- private Http2Frame frame;
+ protected boolean isFlagSet(short mask) {
+ return (header.getFlags() & mask) == mask;
+ }
- private boolean frameComplete;
-
- public Http2FrameDecoder() {
- reset();
+ protected void initBuilder(AbstractHttp2FrameBuilder builder) {
+ builder.length(header.getLength());
+ builder.type(header.getType());
+ builder.flags(header.getFlags());
+ builder.streamID(header.getStreamID());
}
- @Override
- public boolean consume(ByteBuffer buffer) {
- while (!frameComplete && buffer.remaining() > 0) {
- switch (state) {
- case LENGTH_TYPE_FLAGS:
- if (decoder.consume(buffer)) {
- long val = ((LongPartialDecoder)decoder).getValue();
- frame.setLength((int) ((val >> 16) & 0xFFFFFFL));
- frame.setType((short) ((val >> 8) & 0xFF));
- frame.setFlags((short) (val & 0xFF));
- state = State.STREAMID;
- decoder = new LongPartialDecoder(4);
- }
- break;
- case STREAMID:
- if (decoder.consume(buffer)) {
- frame.setStreamID((int) (((LongPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK));
- if (frame.getLength() > 0) {
- decoder = new BytePartialDecoder(frame.getLength());
- state = State.PAYLOAD;
- } else {
- frameComplete = true;
- }
- }
- break;
- case PAYLOAD:
- if (decoder.consume(buffer)) {
- frame.setPayload(((BytePartialDecoder)decoder).getValue());
- frameComplete = true;
- }
- break;
- }
- }
- return frameComplete;
+ protected Http2FrameHeader getHeader() {
+ return header;
}
-
+
@Override
public Http2Frame getValue() {
return frame;
}
+
+ protected void setValue(Http2Frame frame) {
+ this.frame = frame;
+ }
@Override
public void reset() {
- state = State.LENGTH_TYPE_FLAGS;
- decoder = new LongPartialDecoder(5);
- frame = new Http2Frame();
- frameComplete = false;
}
}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
new file mode 100644
index 0000000..86187b2
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
@@ -0,0 +1,82 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2GoAwayFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2GoAwayFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ LAST_STREAM_ID,
+ CODE,
+ EXTRA
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2GoAwayFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ state = State.LAST_STREAM_ID;
+ decoder = new IntPartialDecoder(4);
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case LAST_STREAM_ID:
+ if (decoder.consume(buffer)) {
+ builder.lastStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+ state = State.CODE;
+ decoder.reset();
+ }
+ case CODE:
+ if (decoder.consume(buffer)) {
+ builder.errorCode(((IntPartialDecoder)decoder).getValue());
+ if (getHeader().getLength() > 8) {
+ state = State.EXTRA;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 8);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case EXTRA:
+ if (decoder.consume(buffer)) {
+ builder.data(((BytePartialDecoder)decoder).getValue());
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
new file mode 100644
index 0000000..72a89c3
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
@@ -0,0 +1,117 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2HeadersFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2HeadersFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ PAD_LENGTH,
+ STREAM_DEPENDENCY,
+ WEIGHT,
+ HEADER,
+ PADDING
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private int padLength;
+
+ private Builder builder = new Builder();
+
+ public Http2HeadersFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ if (isFlagSet(FLAGS_PADDING)) {
+ state = State.PAD_LENGTH;
+ } else if (isFlagSet(FLAGS_PRIORITY)) {
+ state = State.STREAM_DEPENDENCY;
+ decoder = new IntPartialDecoder(4);
+ } else {
+ state = State.HEADER;
+ decoder = new BytePartialDecoder(header.getLength());
+ }
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case PAD_LENGTH:
+ padLength = buffer.get();
+ if (isFlagSet(FLAGS_PRIORITY)) {
+ decoder = new IntPartialDecoder(4);
+ state = State.STREAM_DEPENDENCY;
+ } else {
+ state = State.HEADER;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 1 - padLength);
+ }
+ break;
+ case STREAM_DEPENDENCY:
+ if (decoder.consume(buffer)) {
+ builder.streamDependencyID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+ builder.exclusiveMode((((IntPartialDecoder)decoder).getValue() & HTTP2_EXCLUSIVE_MASK) == HTTP2_EXCLUSIVE_MASK);
+ state = State.WEIGHT;
+ }
+ break;
+ case WEIGHT:
+ builder.weight((byte) (buffer.get()+1));
+ state = State.HEADER;
+ int headerLength = getHeader().getLength() - 5;
+ if (isFlagSet(FLAGS_PADDING)) {
+ headerLength -= (padLength + 1);
+ }
+ decoder = new BytePartialDecoder(headerLength);
+ break;
+ case HEADER:
+ if (decoder.consume(buffer)) {
+ builder.headerBlockFragment(((BytePartialDecoder)decoder).getValue());
+ if (isFlagSet(FLAGS_PADDING)) {
+ state = State.PADDING;
+ decoder = new BytePartialDecoder(padLength);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case PADDING:
+ if (decoder.consume(buffer)) {
+ builder.padding(((BytePartialDecoder)decoder).getValue());
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
new file mode 100644
index 0000000..4098d49
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
@@ -0,0 +1,70 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PingFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PingFrameDecoder extends Http2FrameDecoder {
+
+ private static enum State {
+ DATA,
+ EXTRA
+ }
+
+ private State state;
+
+ private BytePartialDecoder decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2PingFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ decoder = new BytePartialDecoder(8);
+ state = State.DATA;
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case DATA:
+ if (decoder.consume(buffer)) {
+ builder.data(decoder.getValue());
+ if (getHeader().getLength() > 8) {
+ state = State.EXTRA;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 8);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case EXTRA:
+ if (decoder.consume(buffer)) {
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
new file mode 100644
index 0000000..8fd1036
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
@@ -0,0 +1,83 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PriorityFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PriorityFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ STREAM_DEPENDENCY,
+ WEIGHT,
+ EXTRA
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2PriorityFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ state = State.STREAM_DEPENDENCY;
+ decoder = new IntPartialDecoder(4);
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case STREAM_DEPENDENCY:
+ if (decoder.consume(buffer)) {
+ builder.streamDependencyID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+ builder.exclusiveMode((((IntPartialDecoder)decoder).getValue() & HTTP2_EXCLUSIVE_MASK) == HTTP2_EXCLUSIVE_MASK);
+ state = State.WEIGHT;
+ }
+ break;
+ case WEIGHT:
+ builder.weight((short) ((buffer.get() & 0x00FF) + 1));
+ int extraLength = getHeader().getLength() - 5;
+ if (extraLength > 0) {
+ decoder = new BytePartialDecoder(extraLength);
+ state = State.EXTRA;
+ } else {
+ setValue(builder.build());
+ }
+ break;
+ case EXTRA:
+ if (decoder.consume(buffer)) {
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
new file mode 100644
index 0000000..34863ce
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
@@ -0,0 +1,101 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PushPromiseFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PushPromiseFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ PAD_LENGTH,
+ PROMISED_STREAM,
+ HEADER,
+ PADDING
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private int padLength;
+
+ private Builder builder = new Builder();
+
+ public Http2PushPromiseFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ if (isFlagSet(FLAGS_PADDING)) {
+ state = State.PAD_LENGTH;
+ } else {
+ state = State.PROMISED_STREAM;
+ decoder = new IntPartialDecoder(4);
+ }
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case PAD_LENGTH:
+ padLength = buffer.get();
+ state = State.PROMISED_STREAM;
+ decoder = new IntPartialDecoder(4);
+ break;
+ case PROMISED_STREAM:
+ if (decoder.consume(buffer)) {
+ builder.promisedStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+ state = State.HEADER;
+ int headerLength = getHeader().getLength() - 4;
+ if (isFlagSet(FLAGS_PADDING)) {
+ headerLength -= (padLength + 1);
+ }
+ decoder = new BytePartialDecoder(headerLength);
+ }
+ break;
+ case HEADER:
+ if (decoder.consume(buffer)) {
+ builder.headerBlockFragment(((BytePartialDecoder)decoder).getValue());
+ if (isFlagSet(FLAGS_PADDING)) {
+ state = State.PADDING;
+ decoder = new BytePartialDecoder(padLength);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case PADDING:
+ if (decoder.consume(buffer)) {
+ builder.padding(((BytePartialDecoder)decoder).getValue());
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
new file mode 100644
index 0000000..e16b0bc
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
@@ -0,0 +1,75 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2RstStreamFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2RstStreamFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ ERROR_CODE,
+ EXTRA
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2RstStreamFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ state = State.ERROR_CODE;
+ decoder = new LongPartialDecoder(4);
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case ERROR_CODE:
+ if (decoder.consume(buffer)) {
+ builder.errorCode(((LongPartialDecoder)decoder).getValue());
+ if (getHeader().getLength() > 4) {
+ state = State.EXTRA;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 4);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case EXTRA:
+ if (decoder.consume(buffer)) {
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
new file mode 100644
index 0000000..6213c66
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
@@ -0,0 +1,64 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2SettingsFrame.Builder;
+import org.apache.mina.http2.api.Http2Setting;
+import org.apache.mina.http2.api.LongPartialDecoder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2SettingsFrameDecoder extends Http2FrameDecoder {
+
+ private int remaining;
+
+ private LongPartialDecoder decoder = new LongPartialDecoder(6);
+
+ private Builder builder = new Builder();
+
+ private Collection<Http2Setting> settings = new ArrayList<Http2Setting>();
+
+ public Http2SettingsFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ remaining = header.getLength() / 6;
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ if (decoder.consume(buffer)) {
+ remaining--;
+ Http2Setting setting = new Http2Setting();
+ setting.setID((int) ((decoder.getValue() & 0x00FFFF00000000L) >> 32));
+ setting.setValue(decoder.getValue() & 0x00FFFFFFFFL);
+ settings.add(setting);
+ decoder.reset();
+ if (remaining == 0) {
+ builder.settings(settings);
+ setValue(builder.build());
+ }
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
new file mode 100644
index 0000000..f19e55f
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
@@ -0,0 +1,52 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2UnknownFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2UnknownFrameDecoder extends Http2FrameDecoder {
+
+ private BytePartialDecoder decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2UnknownFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ initBuilder(builder);
+ if (header.getLength() > 0) {
+ decoder = new BytePartialDecoder(header.getLength());
+ } else {
+ setValue(builder.build());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ if (decoder.consume(buffer)) {
+ builder.payload(decoder.getValue());
+ setValue(builder.build());
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
new file mode 100644
index 0000000..6d96327
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
@@ -0,0 +1,73 @@
+/**
+ *
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2WindowUpdateFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2WindowUpdateFrameDecoder extends Http2FrameDecoder {
+
+ private enum State {
+ INCREMENT,
+ EXTRA
+ }
+
+ private State state;
+
+ private PartialDecoder<?> decoder;
+
+ private Builder builder = new Builder();
+
+ public Http2WindowUpdateFrameDecoder(Http2FrameHeader header) {
+ super(header);
+ state = State.INCREMENT;
+ decoder = new IntPartialDecoder(4);
+ initBuilder(builder);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+ */
+ @Override
+ public boolean consume(ByteBuffer buffer) {
+ while ((getValue() == null) && buffer.remaining() > 0) {
+ switch (state) {
+ case INCREMENT:
+ if (decoder.consume(buffer)) {
+ builder.windowUpdateIncrement(((IntPartialDecoder)decoder).getValue());
+ if (getHeader().getLength() > 4) {
+ state = State.EXTRA;
+ decoder = new BytePartialDecoder(getHeader().getLength() - 4);
+ } else {
+ setValue(builder.build());
+ }
+ }
+ break;
+ case EXTRA:
+ if (decoder.consume(buffer)) {
+ setValue(builder.build());
+ }
+ break;
+ }
+ }
+ return getValue() != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.mina.http2.api.PartialDecoder#reset()
+ */
+ @Override
+ public void reset() {
+ }
+
+}