You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ts...@apache.org on 2016/07/01 23:26:33 UTC

wicket git commit: WICKET-6194

Repository: wicket
Updated Branches:
  refs/heads/WICKET-6194 [created] eb730f297


WICKET-6194

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

Branch: refs/heads/WICKET-6194
Commit: eb730f2979dab6c937e87cefbbe84167cc5546e1
Parents: a6673f1
Author: Tobias Soloschenko <ts...@apache.org>
Authored: Sat Jul 2 01:25:22 2016 +0200
Committer: Tobias Soloschenko <ts...@apache.org>
Committed: Sat Jul 2 01:25:22 2016 +0200

----------------------------------------------------------------------
 wicket-experimental/wicket-http2/pom.xml        |  37 ++++
 .../wicket-http2/wicket-http2-core/pom.xml      |  45 +++++
 .../http2/markup/head/PushHeaderItem.java       | 190 +++++++++++++++++++
 .../wicket/http2/markup/head/PushItem.java      |  95 ++++++++++
 .../wicket-http2/wicket-http2-jetty/pom.xml     |  38 ++++
 5 files changed, 405 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/eb730f29/wicket-experimental/wicket-http2/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-http2/pom.xml b/wicket-experimental/wicket-http2/pom.xml
new file mode 100644
index 0000000..065b940
--- /dev/null
+++ b/wicket-experimental/wicket-http2/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<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>org.apache.wicket.experimental.wicket8</groupId>
+		<artifactId>wicket-experimental</artifactId>
+		<version>8.0.0-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>wicket-http2</artifactId>
+	<version>0.1-SNAPSHOT</version>
+	<packaging>pom</packaging>
+	<name>Wicket Http/2</name>
+	<description>
+		Wicket\u2019s implementation to use the PushBuilder API
+		to serve resource via http/2 with less requests
+	</description>
+	<modules>
+		<module>wicket-http2-core</module>
+	</modules>
+</project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/eb730f29/wicket-experimental/wicket-http2/wicket-http2-core/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-http2/wicket-http2-core/pom.xml b/wicket-experimental/wicket-http2/wicket-http2-core/pom.xml
new file mode 100644
index 0000000..d5e6d4b
--- /dev/null
+++ b/wicket-experimental/wicket-http2/wicket-http2-core/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<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>org.apache.wicket.experimental.wicket8</groupId>
+		<artifactId>wicket-http2</artifactId>
+		<version>0.1-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>wicket-http2-core</artifactId>
+	<packaging>jar</packaging>
+	<name>Wicket Http/2 Core</name>
+	<description>
+		Wicket\u2019s implementation to use the PushBuilder API
+		to serve resource via http/2 with less requests. This
+		is the core implementation which provides the header item
+		that uses the API.
+	</description>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.wicket</groupId>
+			<artifactId>wicket-core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.wicket</groupId>
+			<artifactId>wicket-request</artifactId>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/eb730f29/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushHeaderItem.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushHeaderItem.java b/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushHeaderItem.java
new file mode 100644
index 0000000..a56b8bd
--- /dev/null
+++ b/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushHeaderItem.java
@@ -0,0 +1,190 @@
+package org.apache.wicket.http2.markup.head;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.head.HeaderItem;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.Request;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.collections.ConcurrentHashSet;
+
+/**
+ * A push header item to be used in the http/2 context and to reduce the latency of the web
+ * application
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+public class PushHeaderItem extends HeaderItem
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The http2 protocol string
+	 */
+	public static final String HTTP2_PROTOCOL = "http/2";
+
+	/**
+	 * The token suffix to be used in this header item
+	 */
+	private static final String TOKEN_SUFFIX = HTTP2_PROTOCOL + "_pushed";
+
+	/**
+	 * The URLs of resources to be pushed to the client
+	 */
+	private Set<String> urls = new ConcurrentHashSet<String>(new TreeSet<String>());
+
+	/**
+	 * Uses the URLs that has already been pushed to the client to ensure not to push them again
+	 */
+	@Override
+	public Iterable<?> getRenderTokens()
+	{
+		Set<String> tokens = new TreeSet<String>();
+		for (String url : urls)
+		{
+			tokens.add(url + TOKEN_SUFFIX);
+		}
+		return tokens;
+	}
+
+	/**
+	 * Pushes the previously created URLs to the client
+	 */
+	@Override
+	public void render(Response response)
+	{
+		HttpServletRequest request = getContainerRequest(RequestCycle.get().getRequest());
+		// Check if the protocol is http/2 or http/2.0 to only push the resources in this case
+		if (isHttp2(request))
+		{
+			for (String url : urls)
+			{
+				// TODO Jetty has to switch to the javax.servlet-api classes and handle
+				// SETTINGS_ENABLE_PUSH settings frame value and implement the default API against
+				// it.
+				org.eclipse.jetty.server.Request.getBaseRequest(request).getPushBuilder()
+				    .path(url.toString()).push();
+			}
+		}
+	}
+
+	/**
+	 * Creates a URL and pushes the resource to the client - this is only supported if http2 is
+	 * enabled
+	 * 
+	 * @param pushItems
+	 *            a list of items to be pushed to the client
+	 * @return the current push header item
+	 */
+	@SuppressWarnings("unchecked")
+	public PushHeaderItem push(List<PushItem> pushItems)
+	{
+		RequestCycle requestCycle = RequestCycle.get();
+		if (isHttp2(getContainerRequest(requestCycle.getRequest())))
+			for (PushItem pushItem : pushItems)
+			{
+				Object object = pushItem.getObject();
+				PageParameters parameters = pushItem.getPageParameters();
+
+				if (object == null)
+				{
+					throw new WicketRuntimeException(
+					    "Please provide an object to the items to be pushed, so that the url can be created for the given resource.");
+				}
+
+				CharSequence url = null;
+				if (object instanceof ResourceReference)
+				{
+					url = requestCycle.urlFor((ResourceReference)object, parameters);
+				}
+				else if (object instanceof Class)
+				{
+					url = requestCycle.urlFor((Class<? extends Page>)object, parameters);
+				}
+				else if (object instanceof IRequestHandler)
+				{
+					url = requestCycle.urlFor((IRequestHandler)object);
+				}
+				else
+				{
+					Url encoded = new PageParametersEncoder().encodePageParameters(parameters);
+					String queryString = encoded.getQueryString();
+					url = object.toString() + (queryString != null ? "?" + queryString : "");
+				}
+
+				if (url.toString().equals("."))
+				{
+					url = "/";
+				}
+				else if (url.toString().startsWith("."))
+				{
+					url = url.toString().substring(1);
+				}
+
+				urls.add(url.toString());
+			}
+		return this;
+	}
+
+	/**
+	 * Gets the container request
+	 * 
+	 * @param request
+	 *            the wicket request to get the container request from
+	 * @return the container request
+	 */
+	public HttpServletRequest getContainerRequest(Request request)
+	{
+
+		return checkHttpServletRequest(request);
+	}
+
+	/**
+	 * Checks if the given request is a http/2 request
+	 * 
+	 * @param request
+	 *            the request to check if it is a http/2 request
+	 * @return if the request is a http/2 request
+	 */
+	public boolean isHttp2(HttpServletRequest request)
+	{
+		// detects http/2 and http/2.0
+		return request.getProtocol().toLowerCase().contains(HTTP2_PROTOCOL);
+	}
+
+	/**
+	 * Checks if the container request from the given request is instance of
+	 * {@link HttpServletRequest} if not the API of the PushHeaderItem can't be used and a
+	 * {@link WicketRuntimeException} is thrown.
+	 * 
+	 * @param request
+	 *            the request to get the container request from. The container request is checked if it
+	 *            is instance of {@link HttpServletRequest}
+	 * @return the container request get from the given request casted to {@link HttpServletRequest}
+	 * @throw {@link WicketRuntimeException} if the container request is not a
+	 *        {@link HttpServletRequest}
+	 */
+	public HttpServletRequest checkHttpServletRequest(Request request)
+	{
+		Object assumedHttpServletRequest = request.getContainerRequest();
+		if (!(assumedHttpServletRequest instanceof HttpServletRequest))
+		{
+			throw new WicketRuntimeException(
+			    "The request is not a HttpServletRequest - the usage of PushHeaderItem is not support in the current environment: "
+			        + request.getClass().getName());
+		}
+		return (HttpServletRequest)assumedHttpServletRequest;
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/eb730f29/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushItem.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushItem.java b/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushItem.java
new file mode 100644
index 0000000..402ecb4
--- /dev/null
+++ b/wicket-experimental/wicket-http2/wicket-http2-core/src/main/java/org/apache/wicket/http2/markup/head/PushItem.java
@@ -0,0 +1,95 @@
+package org.apache.wicket.http2.markup.head;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * The object to be pushed. See the urlFor methods of {@link Component} to know what can be used in
+ * addition to {@link String}.
+ * 
+ * @author Tobias Soloschenko
+ */
+public class PushItem
+{
+	private Object object;
+
+	private PageParameters pageParameters;
+
+	/**
+	 * Creates a push item
+	 * 
+	 * @param object
+	 *            the object
+	 * @param pageParameters
+	 *            the page parameters
+	 */
+	public PushItem(Object object, PageParameters pageParameters)
+	{
+		this.object = object;
+		this.pageParameters = pageParameters;
+	}
+
+	/**
+	 * Creates a push item
+	 * 
+	 * @param object
+	 *            the object
+	 */
+	public PushItem(Object object)
+	{
+		this.object = object;
+	}
+
+	/**
+	 * Creates a push item
+	 */
+	public PushItem()
+	{
+	}
+
+	/**
+	 * Gets the object
+	 * 
+	 * @return the object
+	 */
+	public Object getObject()
+	{
+		return object;
+	}
+
+	/**
+	 * Sets the object
+	 * 
+	 * @param object
+	 *            the object
+	 * @return the push item
+	 */
+	public PushItem setObject(Object object)
+	{
+		this.object = object;
+		return this;
+	}
+
+	/**
+	 * Gets the page parameters
+	 * 
+	 * @return the page parameters
+	 */
+	public PageParameters getPageParameters()
+	{
+		return pageParameters;
+	}
+
+	/**
+	 * Sets the page parameters
+	 * 
+	 * @param pageParameters
+	 *            the page parameters
+	 * @return the push item
+	 */
+	public PushItem setPageParameters(PageParameters pageParameters)
+	{
+		this.pageParameters = pageParameters;
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/eb730f29/wicket-experimental/wicket-http2/wicket-http2-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-http2/wicket-http2-jetty/pom.xml b/wicket-experimental/wicket-http2/wicket-http2-jetty/pom.xml
new file mode 100644
index 0000000..8dfb469
--- /dev/null
+++ b/wicket-experimental/wicket-http2/wicket-http2-jetty/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<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>org.apache.wicket.experimental.wicket7</groupId>
+		<artifactId>wicket-http2</artifactId>
+		<version>0.1-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>wicket-http2-core</artifactId>
+	<packaging>jar</packaging>
+	<name>Wicket Http/2 Jetty</name>
+	<description>
+		Wicket\u2019s implementation to use the PushBuilder API
+		to serve resource via http/2 with less requests. This
+		is the jetty implementation to resolve the PushBuilder API and
+		provide the IInitializer.
+	</description>
+	<dependencies>
+		<!-- TODO -->
+	</dependencies>
+</project>