Skip to content

Instantly share code, notes, and snippets.

@decebals
Last active March 7, 2020 15:28
Show Gist options
  • Save decebals/643a95d9979c1b55ec93ba46caf106ab to your computer and use it in GitHub Desktop.
Save decebals/643a95d9979c1b55ec93ba46caf106ab to your computer and use it in GitHub Desktop.
A POC for HTTP/2 with Pippo
/*
* Copyright (C) 2014 the original author or authors.
*
* 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.
*/
package ro.pippo.demo.http2;
import org.eclipse.jetty.server.PushBuilder;
import org.eclipse.jetty.server.Request;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import ro.pippo.core.Application;
import ro.pippo.core.route.PublicResourceHandler;
import ro.pippo.core.route.RouteContext;
import ro.pippo.core.route.WebjarsResourceHandler;
import ro.pippo.demo.common.ContactService;
import ro.pippo.demo.common.InMemoryContactService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Decebal Suiu
*/
public class Http2Application extends Application {
private ContactService contactService;
@Override
protected void onInit() {
contactService = new InMemoryContactService();
// add routes for static content
// addPublicResourceRoute();
addResourceRoute(new PublicResourceHandler().setVersioned(false)); // disable versioning
// addWebjarsResourceRoute();
addResourceRoute(new WebjarsResourceHandler().setVersioned(false)); // disable versioning
getRouter().ignorePaths("/favicon.ico");
// send 'Hello World' as response
GET("/", routeContext -> routeContext.send("Hello World"));
// send a page created from a template
// GET("/contacts", this::sendContactsPage);
GET("/contacts", this::sendContactsPage2);
}
/*
* The "contacts.html" page contains below resources/assets:
*
* - in "head" section
* <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
* <link href="/webjars/font-awesome/css/font-awesome.min.css" rel="stylesheet">
* <link href="/public/css/style.css" rel="stylesheet">
*
* - in "body" section
* <script src="/webjars/jquery/jquery.min.js"></script>
* <script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
*/
private void sendContactsPage(RouteContext routeContext) {
// Jetty specific APIs (Jetty 9 is based on Servlet 3.1)
PushBuilder pushBuilder = Request.getBaseRequest(routeContext.getRequest().getHttpServletRequest()).getPushBuilder();
getPushResourcePaths().forEach(path -> pushBuilder.path(path).push());
Map<String, Object> model = new HashMap<>();
model.put("contacts", contactService.getContacts());
routeContext.render("contacts", model);
}
private void sendContactsPage2(RouteContext routeContext) {
Map<String, Object> model = new HashMap<>();
model.put("contacts", contactService.getContacts());
String html = routeContext.renderToString("contacts", model);
// Jetty specific APIs (Jetty 9 is based on Servlet 3.1)
PushBuilder pushBuilder = Request.getBaseRequest(routeContext.getRequest().getHttpServletRequest()).getPushBuilder();
getPushResourcePaths(html).forEach(path -> pushBuilder.path(path).push());
routeContext.send(html);
}
/*
* Retrieve manually the resources paths that will be pushed.
* In this case, the developer must supply this information, for each page.
*/
private List<String> getPushResourcePaths() {
List<String> paths = new ArrayList<>();
paths.add("/webjars/bootstrap/css/bootstrap.min.css");
paths.add("/webjars/font-awesome/css/font-awesome.min.css");
paths.add("/public/css/style.css");
paths.add("/webjars/jquery/jquery.min.js");
paths.add("/webjars/bootstrap/js/bootstrap.min.js");
return paths;
}
/*
* Retrieve automatically (parsing the HTML page) the resources paths that will be pushed.
*/
private List<String> getPushResourcePaths(String html) {
List<String> paths = new ArrayList<>();
Document doc = Jsoup.parse(html);
Elements elements = doc.head().select("link[href]");
for (Element element : elements) {
paths.add(element.attr("href"));
}
elements = doc.body().select("script[src]");
for (Element element : elements) {
paths.add(element.attr("src"));
}
return paths;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment