Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First cut of frame encoding/decoding and session management for HTTP2
Motivation: Needed a rough performance comparison between SPDY and HTTP 2.0 framing. Expected performance gains were seen in HTTP 2.0 due to header compression. Modifications: Added a new codec-http2 module containing all of the new source and unit tests. Updated the top-level pom.xml to add this as a child module. Result: Netty will have basic support for HTTP2.
- Loading branch information
Showing
81 changed files
with
8,602 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ Copyright 2014 The Netty Project | ||
~ | ||
~ The Netty Project 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. | ||
--> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>io.netty</groupId> | ||
<artifactId>netty-parent</artifactId> | ||
<version>5.0.0.Alpha2-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>netty-codec-http2</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<name>Netty/Codec/HTTP2</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>netty-codec-http</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>${project.groupId}</groupId> | ||
<artifactId>netty-handler</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.twitter</groupId> | ||
<artifactId>hpack</artifactId> | ||
<version>0.6.0</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
<version>16.0.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-all</artifactId> | ||
<version>1.9.5</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> | ||
|
45 changes: 45 additions & 0 deletions
45
codec-http2/src/main/java/io/netty/handler/codec/http2/draft10/Http2Error.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright 2014 The Netty Project | ||
* | ||
* The Netty Project 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 io.netty.handler.codec.http2.draft10; | ||
|
||
/** | ||
* All error codes identified by the HTTP2 spec. | ||
*/ | ||
public enum Http2Error { | ||
NO_ERROR(0), | ||
PROTOCOL_ERROR(1), | ||
INTERNAL_ERROR(2), | ||
FLOW_CONTROL_ERROR(3), | ||
SETTINGS_TIMEOUT(4), | ||
STREAM_CLOSED(5), | ||
FRAME_SIZE_ERROR(6), | ||
REFUSED_STREAM(7), | ||
CANCEL(8), | ||
COMPRESSION_ERROR(9), | ||
CONNECT_ERROR(10), | ||
ENHANCE_YOUR_CALM(11), | ||
INADEQUATE_SECURITY(12); | ||
|
||
private final int code; | ||
|
||
private Http2Error(int code) { | ||
this.code = code; | ||
} | ||
|
||
public int getCode() { | ||
return this.code; | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
codec-http2/src/main/java/io/netty/handler/codec/http2/draft10/Http2Exception.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright 2014 The Netty Project | ||
* | ||
* The Netty Project 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 io.netty.handler.codec.http2.draft10; | ||
|
||
/** | ||
* Exception thrown when an HTTP2 error was encountered. | ||
*/ | ||
public class Http2Exception extends Exception { | ||
private static final long serialVersionUID = -2292608019080068769L; | ||
|
||
private final Http2Error error; | ||
|
||
public Http2Exception(Http2Error error) { | ||
this.error = error; | ||
} | ||
|
||
public Http2Exception(Http2Error error, String message) { | ||
super(message); | ||
this.error = error; | ||
} | ||
|
||
public Http2Error getError() { | ||
return error; | ||
} | ||
|
||
public static Http2Exception format(Http2Error error, String fmt, Object... args) { | ||
return new Http2Exception(error, String.format(fmt, args)); | ||
} | ||
|
||
public static Http2Exception protocolError(String fmt, Object... args) { | ||
return format(Http2Error.PROTOCOL_ERROR, fmt, args); | ||
} | ||
|
||
public static Http2Exception flowControlError(String fmt, Object... args) { | ||
return format(Http2Error.FLOW_CONTROL_ERROR, fmt, args); | ||
} | ||
} |
193 changes: 193 additions & 0 deletions
193
codec-http2/src/main/java/io/netty/handler/codec/http2/draft10/Http2Headers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Copyright 2014 The Netty Project | ||
* | ||
* The Netty Project 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 io.netty.handler.codec.http2.draft10; | ||
|
||
import java.util.Iterator; | ||
import java.util.Map.Entry; | ||
|
||
import com.google.common.base.Charsets; | ||
import com.google.common.collect.ImmutableCollection; | ||
import com.google.common.collect.ImmutableMultimap; | ||
|
||
public final class Http2Headers implements Iterable<Entry<String, String>> { | ||
|
||
/** | ||
* HTTP2 header names. | ||
*/ | ||
public enum HttpName { | ||
/** | ||
* {@code :method}. | ||
*/ | ||
METHOD(":method"), | ||
|
||
/** | ||
* {@code :scheme}. | ||
*/ | ||
SCHEME(":scheme"), | ||
|
||
/** | ||
* {@code :authority}. | ||
*/ | ||
AUTHORITY(":authority"), | ||
|
||
/** | ||
* {@code :path}. | ||
*/ | ||
PATH(":path"), | ||
|
||
/** | ||
* {@code :status}. | ||
*/ | ||
STATUS(":status"); | ||
|
||
private final String value; | ||
|
||
private HttpName(String value) { | ||
this.value = value; | ||
} | ||
|
||
public String value() { | ||
return this.value; | ||
} | ||
} | ||
|
||
private final ImmutableMultimap<String, String> headers; | ||
|
||
private Http2Headers(Builder builder) { | ||
this.headers = builder.map.build(); | ||
} | ||
|
||
public String getHeader(String name) { | ||
ImmutableCollection<String> col = getHeaders(name); | ||
return col.isEmpty() ? null : col.iterator().next(); | ||
} | ||
|
||
public ImmutableCollection<String> getHeaders(String name) { | ||
return headers.get(name); | ||
} | ||
|
||
public String getMethod() { | ||
return getHeader(HttpName.METHOD.value()); | ||
} | ||
|
||
public String getScheme() { | ||
return getHeader(HttpName.SCHEME.value()); | ||
} | ||
|
||
public String getAuthority() { | ||
return getHeader(HttpName.AUTHORITY.value()); | ||
} | ||
|
||
public String getPath() { | ||
return getHeader(HttpName.PATH.value()); | ||
} | ||
|
||
public String getStatus() { | ||
return getHeader(HttpName.STATUS.value()); | ||
} | ||
|
||
@Override | ||
public Iterator<Entry<String, String>> iterator() { | ||
return headers.entries().iterator(); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
final int prime = 31; | ||
int result = 1; | ||
result = prime * result + ((headers == null) ? 0 : headers.hashCode()); | ||
return result; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
Http2Headers other = (Http2Headers) obj; | ||
if (headers == null) { | ||
if (other.headers != null) { | ||
return false; | ||
} | ||
} else if (!headers.equals(other.headers)) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return headers.toString(); | ||
} | ||
|
||
public static class Builder { | ||
private ImmutableMultimap.Builder<String, String> map = ImmutableMultimap.builder(); | ||
|
||
public Builder clear() { | ||
map = ImmutableMultimap.builder(); | ||
return this; | ||
} | ||
|
||
public Builder addHeaders(Http2Headers headers) { | ||
if (headers == null) { | ||
throw new IllegalArgumentException("headers must not be null."); | ||
} | ||
map.putAll(headers.headers); | ||
return this; | ||
} | ||
|
||
public Builder addHeader(String name, String value) { | ||
// Use interning on the header name to save space. | ||
map.put(name.intern(), value); | ||
return this; | ||
} | ||
|
||
public Builder addHeader(byte[] name, byte[] value) { | ||
addHeader(new String(name, Charsets.UTF_8), new String(value, Charsets.UTF_8)); | ||
return this; | ||
} | ||
|
||
public Builder setMethod(String value) { | ||
return addHeader(HttpName.METHOD.value(), value); | ||
} | ||
|
||
public Builder setScheme(String value) { | ||
return addHeader(HttpName.SCHEME.value(), value); | ||
} | ||
|
||
public Builder setAuthority(String value) { | ||
return addHeader(HttpName.AUTHORITY.value(), value); | ||
} | ||
|
||
public Builder setPath(String value) { | ||
return addHeader(HttpName.PATH.value(), value); | ||
} | ||
|
||
public Builder setStatus(String value) { | ||
return addHeader(HttpName.STATUS.value(), value); | ||
} | ||
|
||
public Http2Headers build() { | ||
return new Http2Headers(this); | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
codec-http2/src/main/java/io/netty/handler/codec/http2/draft10/Http2StreamException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright 2014 The Netty Project | ||
* | ||
* The Netty Project 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 io.netty.handler.codec.http2.draft10; | ||
|
||
public class Http2StreamException extends Http2Exception { | ||
|
||
private static final long serialVersionUID = -7658235659648480024L; | ||
private final int streamId; | ||
|
||
public Http2StreamException(int streamId, Http2Error error, String message) { | ||
super(error, message); | ||
this.streamId = streamId; | ||
} | ||
|
||
public Http2StreamException(int streamId, Http2Error error) { | ||
super(error); | ||
this.streamId = streamId; | ||
} | ||
|
||
public int getStreamId() { | ||
return streamId; | ||
} | ||
} |
Oops, something went wrong.