Permalink
Browse files

[pegasus] Add HTTP protocol version to request context

RB=785576
G=si-core-reviewers
R=bfeng,dmessink
A=dhoa
  • Loading branch information...
1 parent 02df4e8 commit e4eb8863ec60b9a81b486dfcb72423fe0d300e87 @ssheng ssheng committed Aug 20, 2016
Showing with 252 additions and 66 deletions.
  1. +3 −0 CHANGELOG
  2. +5 −0 r2-core/src/main/java/com/linkedin/r2/filter/R2Constants.java
  3. +73 −0 r2-core/src/main/java/com/linkedin/r2/transport/http/common/HttpProtocolVersion.java
  4. +5 −0 r2-core/src/main/java/com/linkedin/r2/transport/http/server/AbstractR2Servlet.java
  5. +5 −0 r2-core/src/main/java/com/linkedin/r2/transport/http/server/ServletHelper.java
  6. +72 −0 r2-core/src/test/java/test/r2/transport/http/common/TestHttpProtocolVersion.java
  7. +3 −2 r2-int-test/src/test/java/test/r2/integ/AbstractStreamTest.java
  8. +0 −14 r2-int-test/src/test/java/test/r2/integ/HttpProtocolVersion.java
  9. +9 −8 r2-int-test/src/test/java/test/r2/integ/TestClientShutdown.java
  10. +3 −2 r2-int-test/src/test/java/test/r2/integ/TestHttpClient.java
  11. +1 −0 r2-int-test/src/test/java/test/r2/integ/TestJetty404.java
  12. +17 −16 r2-int-test/src/test/java/test/r2/integ/TestQueryTunnel.java
  13. +5 −4 r2-int-test/src/test/java/test/r2/integ/TestRequestCompression.java
  14. +3 −2 r2-int-test/src/test/java/test/r2/integ/TestRestCompressionEcho.java
  15. +4 −3 r2-netty/src/main/java/com/linkedin/r2/transport/http/client/AbstractNettyStreamClient.java
  16. +6 −1 r2-netty/src/main/java/com/linkedin/r2/transport/http/client/Http2NettyStreamClient.java
  17. +1 −6 r2-netty/src/main/java/com/linkedin/r2/transport/http/client/HttpClientFactory.java
  18. +3 −0 r2-netty/src/main/java/com/linkedin/r2/transport/http/client/HttpNettyClient.java
  19. +6 −1 r2-netty/src/main/java/com/linkedin/r2/transport/http/client/HttpNettyStreamClient.java
  20. +3 −2 r2-netty/src/test/java/com/linkedin/r2/transport/http/client/TestHttpClientFactory.java
  21. +5 −1 r2-netty/src/test/java/com/linkedin/r2/transport/http/client/TestHttpNettyClient.java
  22. +17 −2 r2-netty/src/test/java/com/linkedin/r2/transport/http/client/TestHttpNettyStreamClient.java
  23. +3 −2 r2-sample/src/main/java/com/linkedin/r2/sample/Bootstrap.java
View
@@ -5,6 +5,9 @@
context factory name and refactored RestLiCallback to be instantiated
from within Filterchain.
+(RB=785576)
+Add HTTP protocol version to request context
+
7.0.1
-----
(RB=793402)
@@ -37,6 +37,11 @@
* client side code after the request is sent
* */
public static final String REMOTE_SERVER_ADDR = "REMOTE_SERVER_ADDR";
+
+ /**
+ * The HTTP protocol that the client and server are communicated under.
+ */
+ public static final String HTTP_PROTOCOL_VERSION = "HTTP_PROTOCOL_VERSION";
public static final String IS_SECURE = "IS_SECURE";
public static final String CLIENT_CERT = "CLIENT_CERT";
public static final String REQUEST_COMPRESSION_OVERRIDE = "REQUEST_COMPRESSION_OVERRIDE";
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2016 LinkedIn Corp.
+
+ Licensed 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.
+*/
+
+/* $Id$ */
+package com.linkedin.r2.transport.http.common;
+
+/**
+ * Enumerates supported HTTP protocols
+ */
+public enum HttpProtocolVersion
+{
+ /**
+ * HTTP/1.1
+ */
+ HTTP_1_1,
+
+ /**
+ * HTTP/2
+ */
+ HTTP_2;
+
+ private static final String HTTP_1_1_LITERALS = "HTTP/1.1";
+ private static final String HTTP_2_LITERALS = "HTTP/2";
+ private static final String HTTP_2_LITERALS_ALTERNATIVE = "HTTP/2.0";
+
+ static
+ {
+ HTTP_1_1._literals = HTTP_1_1_LITERALS;
+ HTTP_2._literals = HTTP_2_LITERALS;
+ }
+
+ private String _literals;
+
+ public String literals()
+ {
+ return _literals;
+ }
+
+ /**
+ * Parses a given string representation of HTTP protocol to an {@link HttpProtocolVersion} enumeration.
+ * @param version a string representation of HTTP protocol version
+ * @return the corresponding enumeration or {@code null} is nothing matches
+ */
+ public static HttpProtocolVersion parse(String version)
+ {
+ if (version.equalsIgnoreCase(HTTP_1_1_LITERALS))
+ {
+ return HTTP_1_1;
+ }
+ else if (version.equalsIgnoreCase(HTTP_2_LITERALS))
+ {
+ return HTTP_2;
+ }
+ else if (version.equalsIgnoreCase(HTTP_2_LITERALS_ALTERNATIVE))
+ {
+ return HTTP_2;
+ }
+ return null;
+ }
+}
@@ -31,6 +31,7 @@
import com.linkedin.r2.transport.common.bridge.common.TransportResponse;
import com.linkedin.r2.transport.common.bridge.common.TransportResponseImpl;
import com.linkedin.r2.transport.http.common.HttpConstants;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -238,6 +239,10 @@ protected RequestContext readRequestContext(HttpServletRequest req)
{
RequestContext context = new RequestContext();
context.putLocalAttr(R2Constants.REMOTE_ADDR, req.getRemoteAddr());
+
+ HttpProtocolVersion protocol = HttpProtocolVersion.parse(req.getProtocol());
+ context.putLocalAttr(R2Constants.HTTP_PROTOCOL_VERSION, protocol);
+
if (req.isSecure())
{
// attribute name documented in ServletRequest API:
@@ -32,6 +32,7 @@
import com.linkedin.r2.transport.common.bridge.common.TransportResponse;
import com.linkedin.r2.transport.common.bridge.common.TransportResponseImpl;
import com.linkedin.r2.transport.http.common.HttpConstants;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -163,6 +164,10 @@ static RequestContext readRequestContext(HttpServletRequest req)
{
RequestContext context = new RequestContext();
context.putLocalAttr(R2Constants.REMOTE_ADDR, req.getRemoteAddr());
+
+ HttpProtocolVersion protocol = HttpProtocolVersion.parse(req.getProtocol());
+ context.putLocalAttr(R2Constants.HTTP_PROTOCOL_VERSION, protocol);
+
if (req.isSecure())
{
// attribute name documented in ServletRequest API:
@@ -0,0 +1,72 @@
+/*
+ Copyright (c) 2016 LinkedIn Corp.
+
+ Licensed 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.
+*/
+
+/**
+ * $Id: $
+ */
+
+package test.r2.transport.http.common;
+
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+public class TestHttpProtocolVersion
+{
+ private static final String HTTP_1_1_LITERALS = "HTTP/1.1";
+ private static final String HTTP_2_LITERALS = "HTTP/2";
+ private static final String HTTP_2_LITERALS_ALTERNATIVE = "HTTP/2.0";
+ private static final String INVALID_HTTP_PROTOCOL = "HTTP/INVALID";
+
+ @DataProvider(name = "versionLiterals")
+ public Object[][] versionLiteralsProvider()
+ {
+ return new Object[][] {
+ { HttpProtocolVersion.HTTP_1_1, HTTP_1_1_LITERALS },
+ { HttpProtocolVersion.HTTP_2, HTTP_2_LITERALS },
+ };
+ }
+
+ @Test(dataProvider = "versionLiterals")
+ public void testLiterals(HttpProtocolVersion version, String literals)
+ {
+ Assert.assertEquals(version.literals(), literals);
+ }
+
+ @DataProvider(name = "literalVersions")
+ public Object[][] literalVersionsProvider()
+ {
+ return new Object[][] {
+ { HTTP_1_1_LITERALS, HttpProtocolVersion.HTTP_1_1 },
+ { HTTP_2_LITERALS, HttpProtocolVersion.HTTP_2 },
+ { HTTP_2_LITERALS_ALTERNATIVE, HttpProtocolVersion.HTTP_2 },
+ };
+ }
+
+ @Test(dataProvider = "literalVersions")
+ public void testParse(String literals, HttpProtocolVersion version)
+ {
+ Assert.assertEquals(HttpProtocolVersion.parse(literals), version);
+ }
+
+ @Test
+ public void testParseInvalid()
+ {
+ Assert.assertNull(HttpProtocolVersion.parse(INVALID_HTTP_PROTOCOL));
+ }
+}
@@ -7,6 +7,7 @@
import com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.http.client.HttpClientFactory;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpServer;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
import java.util.Arrays;
@@ -86,14 +87,14 @@ protected TransportClientFactory getClientFactory()
protected Map<String, String> getHttp1ClientProperties()
{
HashMap<String, String> properties = new HashMap<>();
- properties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_1_1);
+ properties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_1_1.name());
return properties;
}
protected Map<String, String> getHttp2ClientProperties()
{
HashMap<String, String> properties = new HashMap<>();
- properties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_2);
+ properties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_2.name());
return properties;
}
@@ -1,14 +0,0 @@
-package test.r2.integ;
-
-import com.linkedin.r2.transport.http.client.HttpClientFactory;
-
-
-/**
- * @author Sean Sheng
- * @version $Revision: $
- */
-public class HttpProtocolVersion
-{
- public static final String HTTP_1_1 = HttpClientFactory.HttpProtocolVersion.HTTP_1_1.name();
- public static final String HTTP_2 = HttpClientFactory.HttpProtocolVersion.HTTP_2.name();
-}
@@ -10,6 +10,7 @@
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder;
import com.linkedin.r2.transport.http.client.HttpClientFactory;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpJettyServer;
import com.linkedin.r2.transport.http.server.HttpServer;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
@@ -40,14 +41,14 @@
public static Object[][] configs()
{
return new Object[][]{
- { true, true, HttpProtocolVersion.HTTP_1_1},
- { true, true, HttpProtocolVersion.HTTP_2 },
- { true, false, HttpProtocolVersion.HTTP_1_1},
- { true, false, HttpProtocolVersion.HTTP_2 },
- { false, true, HttpProtocolVersion.HTTP_1_1},
- { false, true, HttpProtocolVersion.HTTP_2 },
- { false, false, HttpProtocolVersion.HTTP_1_1},
- { false, false, HttpProtocolVersion.HTTP_2 },
+ { true, true, HttpProtocolVersion.HTTP_1_1.name() },
+ { true, true, HttpProtocolVersion.HTTP_2.name() },
+ { true, false, HttpProtocolVersion.HTTP_1_1.name() },
+ { true, false, HttpProtocolVersion.HTTP_2.name() },
+ { false, true, HttpProtocolVersion.HTTP_1_1.name() },
+ { false, true, HttpProtocolVersion.HTTP_2.name() },
+ { false, false, HttpProtocolVersion.HTTP_1_1.name() },
+ { false, false, HttpProtocolVersion.HTTP_2.name() },
};
}
@@ -25,6 +25,7 @@
import com.linkedin.r2.transport.common.Server;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
import java.net.URI;
import java.util.HashMap;
@@ -70,11 +71,11 @@
public Object[][] configs()
{
Map<String, String> http1ClientProperties = new HashMap<>();
- http1ClientProperties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_1_1);
+ http1ClientProperties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_1_1.name());
http1ClientProperties.put(HttpClientFactory.HTTP_REQUEST_TIMEOUT, Integer.toString(REQUEST_TIMEOUT));
Map<String, String> http2ClientProperties = new HashMap<>();
- http2ClientProperties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_2);
+ http2ClientProperties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, HttpProtocolVersion.HTTP_2.name());
http2ClientProperties.put(HttpClientFactory.HTTP_REQUEST_TIMEOUT, Integer.toString(REQUEST_TIMEOUT));
TransportDispatcher dispatcher = new TransportDispatcherBuilder()
@@ -23,6 +23,7 @@
import com.linkedin.r2.transport.common.bridge.common.TransportResponseImpl;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.http.client.HttpClientFactory;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpServer;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
import junit.framework.Assert;
@@ -23,6 +23,7 @@
import com.linkedin.r2.transport.common.bridge.server.TransportCallbackAdapter;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.http.client.HttpClientFactory;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpJettyServer;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
import org.testng.Assert;
@@ -70,22 +71,22 @@ public TestQueryTunnel(boolean clientROS, boolean serverROS, String httpProtocol
public static Object[][] configs()
{
return new Object[][] {
- {true, true, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.RAP, PORT},
- {true, false, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.RAP, PORT},
- {false, true, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.RAP, PORT},
- {false, false, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.RAP, PORT},
- {true, true, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {true, false, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {false, true, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {false, false, HttpProtocolVersion.HTTP_1_1, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {true, true, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.RAP, PORT},
- {true, false, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.RAP, PORT},
- {false, true, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.RAP, PORT},
- {false, false, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.RAP, PORT},
- {true, true, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {true, false, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {false, true, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
- {false, false, HttpProtocolVersion.HTTP_2, HttpJettyServer.ServletType.ASYNC_EVENT, PORT}
+ {true, true, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {true, false, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {false, true, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {false, false, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {true, true, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {true, false, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {false, true, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {false, false, HttpProtocolVersion.HTTP_1_1.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {true, true, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {true, false, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {false, true, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {false, false, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.RAP, PORT},
+ {true, true, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {true, false, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {false, true, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT},
+ {false, false, HttpProtocolVersion.HTTP_2.name(), HttpJettyServer.ServletType.ASYNC_EVENT, PORT}
};
}
@@ -33,6 +33,7 @@
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcher;
import com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder;
import com.linkedin.r2.transport.http.client.HttpClientFactory;
+import com.linkedin.r2.transport.http.common.HttpProtocolVersion;
import com.linkedin.r2.transport.http.server.HttpJettyServer;
import com.linkedin.r2.transport.http.server.HttpServer;
import com.linkedin.r2.transport.http.server.HttpServerFactory;
@@ -109,8 +110,8 @@ protected TransportDispatcher getTransportDispatcher()
StreamEncodingType.BZIP2,
};
String[] protocols = new String[] {
- HttpProtocolVersion.HTTP_1_1,
- HttpProtocolVersion.HTTP_2,
+ HttpProtocolVersion.HTTP_1_1.name(),
+ HttpProtocolVersion.HTTP_2.name(),
};
Object[][] args = new Object[encodings.length * protocols.length][2];
@@ -151,8 +152,8 @@ protected TransportDispatcher getTransportDispatcher()
StreamEncodingType.IDENTITY
};
String[] protocols = new String[] {
- HttpProtocolVersion.HTTP_1_1,
- HttpProtocolVersion.HTTP_2,
+ HttpProtocolVersion.HTTP_1_1.name(),
+ HttpProtocolVersion.HTTP_2.name(),
};
Object[][] args = new Object[encodings.length * protocols.length][1];
Oops, something went wrong.

0 comments on commit e4eb886

Please sign in to comment.