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 <[email protected]>
Authored: Sat Jul 2 01:25:22 2016 +0200
Committer: Tobias Soloschenko <[email protected]>
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’s 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’s 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’s 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>

Reply via email to