Slide 1

Slide 1 text

Fabian Stäber | ConSol* Software GmbH unRESTful Web Services with HTTP/2

Slide 2

Slide 2 text

Contents •  HTTP/2 Intro -> My First HTTP/2 Request •  HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services

Slide 3

Slide 3 text

HTTP/2 is already here! Browsers Java Servers Non-Java Servers Apache mod_h[ttp]2

Slide 4

Slide 4 text

2009 1991 1996 1999 2015 Timeline

Slide 5

Slide 5 text

HTTP/2 is all about reducing latency: •  Less protocol overhead •  Header compression •  Multiplexing •  Request Priorization •  Server Push Why HTTP/2?

Slide 6

Slide 6 text

HTTP/2 does not break the Web •  Same semantics as HTTP/1 – Request/response based communication – HTTP Sessions and cookies •  Goal: Any HTTP/1 application can be deployed on an HTTP/2 server without code change. Compatibility with HTTP/1

Slide 7

Slide 7 text

A First HTTP/2 Request Client GET / Server

Slide 8

Slide 8 text

Ilya Grigorik hpbn.co Client Server HTTP/1 Upgrade Other Protocol, e.g. WebSocket Switching Protocol with HTTP/1 TCP Connection SSL Handshake

Slide 9

Slide 9 text

Ilya Grigorik hpbn.co Client Server TCP Connection SSL Handshake + ALPN Other Protocol, e.g. HTTP/2 Switching Protocol with HTTP/2

Slide 10

Slide 10 text

•  SSL is implemented in the JRE in package sun.security.ssl •  Jetty provides ALPN version of sun.security.ssl for many OpenJDK 7 and 8 releases •  Must start Java with VM parameter -Xbootclasspath/p:alpn-boot-VERSION.jar •  ALPN will be part of Java 9 with JEP 244 Application Layer Protocol Negotiation ALPN

Slide 11

Slide 11 text

My First HTTP/2 Request: Example Servlet @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { resp.setContentType("text/plain"); resp.getWriter().write("Hello, World!"); } demo

Slide 12

Slide 12 text

My First HTTP/2 Request: Server demo git clone https://github.com/fstab/http2-examples cd http2-examples/jetty-http2-server-example mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-server-example.jar

Slide 13

Slide 13 text

My First HTTP/2 Request: Client demo •  HTTP/2 is binary – telnet won‘t help •  The curl command doesn‘t support server push messages yet. •  Wrote my own little tool: https:// github.com/fstab/h2c •  h2c start –dump •  h2c get https://localhost:8443 https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 14

Slide 14 text

HTTP/2 output vs HTTP/1 output HTTP/1.1 200 OK Server: Jetty(9.3.3v20150827) Date: Fri, 16 Oct 2015 16:30:35 GMT Content-Type: text/plain;charset=iso-8859-1 {13 bytes} GET / HTTP/1.1 Host: localhost:8443 https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 15

Slide 15 text

HTTP/2 output vs HTTP/1 output -> HEADERS(3) + END_STREAM + END_HEADERS :method: GET :scheme: https :authority: localhost:8443 :path: / <- HEADERS(3) - END_STREAM + END_HEADERS :status: 200 server: Jetty(9.3.3.v20150827) date: Fri, 16 Oct 2015 16:30:35 GMT content-type: text/plain;charset=iso-8859-1 <- DATA(3) + END_STREAM {13 bytes} https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 16

Slide 16 text

HTTP/2 output vs HTTP/1 output https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 17

Slide 17 text

Header Compression: HPACK GET /8-things-about-couchbase/ HTTP/1.1 Host: blog.arungupta.me Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) C hrome/46.0.2490.71 Safari/537.36 Referer: http://blog.arungupta.me/couchbase-javaone-2015/?utm_source=feedburner&utm_medium=feed& utm_campaign=Feed%3A+MilesToGo+%28Miles+to+go+2.0%29 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,de;q=0.6,fr;q=0.4 Cookie: PHPSESSID=trr42cnr1u2ugekervdnkb4kc2; NCS_INENTIM=1445065465; JCS_INENREF=http%3 A//t.co/UlzEpBg7wx; JCS_INENTIM=1445065466166; 1919598ddf048ef8060898ffee630b16=7bc66ae543c a8e475a2ec85a9c2e7d49; SJECT15=CKON15; __utma=202419266.948108038.1445065466.1445065466 .1445065466.1; __utmb=202419266.2.10.1445065466; __utmc=202419266; __utmz=202419266.1445065 466.1.1.utmcsr=feedburner|utmccn=Feed:%20MilesToGo%20(Miles%20to%20go%202.0)|utmcmd=feed https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 18

Slide 18 text

Contents •  HTTP/2 Intro -> My First HTTP/2 Request •  HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 19

Slide 19 text

•  Goal: Make Web Sites faster •  Demo: https:// http2.golang.org/ gophertiles Multiplexing demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 20

Slide 20 text

Multiplexing for REST: Non-Blocking Services git clone https://github.com/fstab/http2-examples.git cd http2-examples/multiplexing-examples mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar server/target/server.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar okhttp-client/target/okhttp-client.jar demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 21

Slide 21 text

Multiplexing for REST: Non-Blocking Services @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { // ... sleep(SECONDS.toMillis(6)); // ... } demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 22

Slide 22 text

HTTP URL Connection private void sendGet() throws Exception { URL url = new URL("https://www.twitter.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); try (BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()))) { String line; while ((line = in.readLine()) != null) { System.out.println(line); } } } ... and is synchronous! Does not support HTTP/2 ... https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 23

Slide 23 text

OkHttp Request request = new Request.Builder() .url("https://localhost:8443") .build(); client.newCall(request).enqueue(new Callback() { public void onResponse(Response response) throws IOException { // do something with response.body() } }); https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 24

Slide 24 text

Netty FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, ""); request.headers().addObject(HOST, URI.create("https://localhost:8443")); channel.writeAndFlush(request); public class HttpResponseHandler extends SimpleChannelInboundHandler { @Override protected void messageReceived( ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { // Do something with msg.content() ChannelPromise promise = streamidPromiseMap.get(streamId); promise.setSuccess(); } } https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 25

Slide 25 text

Jetty MetaData.Request request = new MetaData.Request( "GET", new HttpURI("https://localhost:8443/"), HTTP_2, requestFields); HeadersFrame headersFrame = new HeadersFrame(request, null, true); session.newStream(headersFrame, new FuturePromise<>(), responseListener); Stream.Listener responseListener = new Stream.Listener.Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) { // do something with frame.getData() callback.succeeded(); } }; https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 26

Slide 26 text

•  Java SE: new HttpUrlConnection JEP 110 •  Java EE: JSR REST Client API ??? Upcoming Standard Libraries https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 27

Slide 27 text

Contents •  HTTP/2 Intro -> My First HTTP/2 Request •  HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 28

Slide 28 text

Push What it looks like: – Request sent from client to server What actually happens: – Push promise sent from server to client HTTP/2 is not a replacement for WebSockets. https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 29

Slide 29 text

Implicit Push for Web Servers How Web Servers use Push for delivering Web Pages: •  For generated content (JSF): Should be possible to know which resources need to be pushed •  For static content (HTML, Angular, ...): Learn from REFERER header (example included in Jetty as servlet filter). https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 30

Slide 30 text

Push and REST Example: How to trigger a push request in the Jetty server: Request baseRequest = Request.getBaseRequest(req); if (baseRequest.isPushSupported()) { baseRequest .getPushBuilder() .method("GET") .path("/data") .push(); } Will be standardized with Servlet 4.0 !!! https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 31

Slide 31 text

Push and REST Receive push request in client: Perform regular GET request, will be responded from the cache. HOWEVER: Client can be notified about the available response in an onPush() callback. https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 32

Slide 32 text

Push and REST Efficient Polling with HTTP/2 Server Push: •  REST interface where client polls a resource •  In case Server Push is supported, client polls not by time interval but polling is triggered by push message. •  Fully compatible with REST semantics but much more efficient than polling with HTTP/1. •  Makes workarounds like long polling, websockets, etc. obosolete. https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 33

Slide 33 text

Push and REST git clone https://github.com/fstab/http2-examples.git cd http2-examples/jetty-http2-echo-server mvn package java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-echo-server.jar h2c start --dump h2c post --data 'hello' https://localhost:8443/data h2c get https://localhost:8443/data demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 34

Slide 34 text

Push Demo <- PUSH_PROMISE(1) + END_HEADERS Promised Stream Id: 2 :scheme: https :method: GET :authority: localhost:8443 :path: /data content-length: 12 host: localhost:8443 x-http2-push: PushBuilder referer: https://localhost:8443/data demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 35

Slide 35 text

Contents •  HTTP/2 Intro -> My First HTTP/2 Request •  HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 36

Slide 36 text

Stream Priorization •  HEADERS frame may contain stream dependency •  PRIORITY frame contains Weight field •  Api planned in Servlet 4.0 A B C https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 37

Slide 37 text

Flow Control •  Based on WINDOW_UPDATE frames •  Send up to n Bytes, then wait for WINDOW_UPDATE public interface FlowControlStrategy { public static int DEFAULT_WINDOW_SIZE = 65535; public void onDataReceived(ISession session, IStream stream, int length); public void onDataConsumed(ISession session, IStream stream, int length); public void onDataSent(IStream stream, int length); public void onSessionStalled(ISession session); public void onStreamStalled(IStream stream); // ... } https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 38

Slide 38 text

Contents •  HTTP/2 Intro -> My First HTTP/2 Request •  HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 39

Slide 39 text

Testing with Arquillian Cube https://dockerHost:2376 wildfly-docker: image: fstab/wildfly-http2:9.0.1.Final await: strategy: polling sleepPollingTime: 1000 iterations: 120 portBindings: ["8443", "9990"] https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 40

Slide 40 text

Testing with Arquillian Cube dockerServerIp 9990 admin admin https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 41

Slide 41 text

Testing with rhuss/docker-maven-plugin org.jolokia docker-maven-plugin ${project.version} https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 42

Slide 42 text

Testing with rhuss/docker-maven-plugin pre-integration-test stop post-integration-test https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 43

Slide 43 text

Testing with OkHttp MockWebServer @Test public void test() throws Exception { MockWebServer server = new MockWebServer(); SSLContext sslContext = new SslContextBuilder(getLocalHost().getHostName()).build(); server.useHttps(sslContext.getSocketFactory(), false); server.enqueue(new MockResponse().setBody("hello, world!")); server.enqueue(new MockResponse().setBody("sup, bra?")); server.enqueue(new MockResponse().setBody("yo dog")); server.start(); HttpUrl baseUrl = server.url("/v1/chat/"); // Start the client, connect to baseURL, run some tests. } https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 44

Slide 44 text

Testing with OkHttp MockWebServer org.apache.maven.plugins maven-surefire-plugin 2.18.1 -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar https://github.com/fstab/h2c https://github.com/fstab/http2-examples

Slide 45

Slide 45 text

•  Adrian Cole, JavaZone https://vimeo.com/138955225 •  Simone Bordet, Voxxed Days Belgrade https://www.youtube.com/watch? v=ve3u00pw4V4 •  Ilya Grigorik: High Performance Browser Networking, http://hpbn.co References https://github.com/fstab/h2c https://github.com/fstab/http2-examples