Reorganized HTTP2 modules.

This commit is contained in:
Simone Bordet 2014-06-09 13:08:54 +02:00
parent 36081dbcbf
commit c1247ff677
64 changed files with 1228 additions and 177 deletions

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>http2-common</artifactId>
<name>Jetty :: HTTP2 :: Common</name>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>http2-hpack</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",javax.net.*,*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,103 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.Executor;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class HTTP2Connection extends AbstractConnection
{
private static final Logger LOG = Log.getLogger(HTTP2Connection.class);
private final ByteBufferPool byteBufferPool;
private final Parser parser;
private final int bufferSize;
public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, int bufferSize)
{
super(endPoint, executor);
this.byteBufferPool = byteBufferPool;
this.parser = parser;
this.bufferSize = bufferSize;
}
@Override
public void onOpen()
{
super.onOpen();
fillInterested();
}
@Override
public void onFillable()
{
ByteBuffer buffer = byteBufferPool.acquire(bufferSize, false);
boolean readMore = read(buffer) == 0;
byteBufferPool.release(buffer);
if (readMore)
fillInterested();
}
protected int read(ByteBuffer buffer)
{
EndPoint endPoint = getEndPoint();
while (true)
{
int filled = fill(endPoint, buffer);
if (LOG.isDebugEnabled()) // Avoid boxing of variable 'filled'
LOG.debug("Read {} bytes", filled);
if (filled == 0)
{
return 0;
}
else if (filled < 0)
{
close();
return -1;
}
else
{
parser.parse(buffer);
}
}
}
private int fill(EndPoint endPoint, ByteBuffer buffer)
{
try
{
if (endPoint.isInputShutdown())
return -1;
return endPoint.fill(buffer);
}
catch (IOException x)
{
LOG.debug("Could not read from " + endPoint, x);
return -1;
}
}
}

View File

@ -0,0 +1,141 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public abstract class HTTP2Session implements Session, Parser.Listener
{
private static final Logger LOG = Log.getLogger(HTTP2Session.class);
private final Listener listener;
public HTTP2Session(Session.Listener listener)
{
this.listener = listener;
}
@Override
public boolean onData(DataFrame frame)
{
return false;
}
@Override
public abstract boolean onHeaders(HeadersFrame frame);
@Override
public boolean onPriority(PriorityFrame frame)
{
return false;
}
@Override
public boolean onReset(ResetFrame frame)
{
return false;
}
@Override
public boolean onSettings(SettingsFrame frame)
{
return false;
}
@Override
public boolean onPing(PingFrame frame)
{
return false;
}
@Override
public boolean onGoAway(GoAwayFrame frame)
{
return false;
}
@Override
public boolean onWindowUpdate(WindowUpdateFrame frame)
{
return false;
}
@Override
public void onConnectionFailure(int error, String reason)
{
}
@Override
public void newStream(HeadersFrame frame, Stream.Listener listener, Promise<Stream> promise)
{
}
@Override
public void settings(SettingsFrame frame, Callback callback)
{
}
@Override
public void ping(PingFrame frame, Callback callback)
{
}
@Override
public void reset(ResetFrame frame, Callback callback)
{
}
@Override
public void close(GoAwayFrame frame, Callback callback)
{
}
protected Stream.Listener notifyNewStream(Stream stream, HeadersFrame frame)
{
try
{
return listener.onNewStream(stream, frame);
}
catch (Throwable x)
{
LOG.info("Failure while notifying listener " + listener, x);
return null;
}
}
}

View File

@ -0,0 +1,57 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.util.Callback;
public class HTTP2Stream implements IStream
{
@Override
public int getId()
{
return 0;
}
@Override
public Session getSession()
{
return null;
}
@Override
public void headers(HeadersFrame frame, Callback callback)
{
}
@Override
public void data(DataFrame frame, Callback callback)
{
}
@Override
public void setListener(Listener listener)
{
}
}

View File

@ -0,0 +1,26 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2;
import org.eclipse.jetty.http2.api.Stream;
public interface IStream extends Stream
{
public void setListener(Listener listener);
}

View File

@ -0,0 +1,91 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.api;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
public interface Session
{
public void newStream(HeadersFrame frame, Stream.Listener listener, Promise<Stream> promise);
public void settings(SettingsFrame frame, Callback callback);
public void ping(PingFrame frame, Callback callback);
public void reset(ResetFrame frame, Callback callback);
public void close(GoAwayFrame frame, Callback callback);
// TODO: getStreams(), remote and local address, etc. see SPDY's Session
public interface Listener
{
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame);
public void onSettings(Session session, SettingsFrame frame);
public void onPing(Session session, PingFrame frame);
public void onReset(Session session, ResetFrame frame);
public void onClose(Session session, GoAwayFrame frame);
public void onFailure(Session session, Throwable failure);
public static class Adapter implements Session.Listener
{
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
return null;
}
@Override
public void onSettings(Session session, SettingsFrame frame)
{
}
@Override
public void onPing(Session session, PingFrame frame)
{
}
@Override
public void onReset(Session session, ResetFrame frame)
{
}
@Override
public void onClose(Session session, GoAwayFrame frame)
{
}
@Override
public void onFailure(Session session, Throwable failure)
{
}
}
}
}

View File

@ -0,0 +1,60 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.api;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.util.Callback;
public interface Stream
{
public int getId();
public Session getSession();
public void headers(HeadersFrame frame, Callback callback);
public void data(DataFrame frame, Callback callback);
// TODO: see SPDY's Stream
public interface Listener
{
public void onData(Stream stream, DataFrame frame);
public void onFailure(Stream stream, Throwable x);
// TODO: See SPDY's StreamFrameListener
public static class Adapter implements Listener
{
@Override
public void onData(Stream stream, DataFrame frame)
{
}
@Override
public void onFailure(Stream stream, Throwable x)
{
}
}
}
}

View File

@ -0,0 +1,34 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.api.server;
import org.eclipse.jetty.http2.api.Session;
public interface ServerSessionListener extends Session.Listener
{
public void onConnect(Session session);
public static class Adapter extends Session.Listener.Adapter implements ServerSessionListener
{
@Override
public void onConnect(Session session)
{
}
}
}

View File

@ -18,20 +18,40 @@
package org.eclipse.jetty.http2.frames;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http2.hpack.MetaData;
public class HeadersFrame
{
private final int streamId;
private final HttpFields fields;
private final MetaData metaData;
private final PriorityFrame priority;
private final boolean endStream;
public HeadersFrame(int streamId, HttpFields fields, PriorityFrame priority, boolean endStream)
public HeadersFrame(int streamId, MetaData metaData, PriorityFrame priority, boolean endStream)
{
this.streamId = streamId;
this.fields = fields;
this.metaData = metaData;
this.priority = priority;
this.endStream = endStream;
}
public int getStreamId()
{
return streamId;
}
public MetaData getMetaData()
{
return metaData;
}
public PriorityFrame getPriority()
{
return priority;
}
public boolean isEndStream()
{
return endStream;
}
}

View File

@ -21,11 +21,11 @@ package org.eclipse.jetty.http2.generator;
import java.nio.ByteBuffer;
import java.util.Map;
import org.eclipse.jetty.hpack.HpackEncoder;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http2.frames.Flag;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
@ -37,7 +37,7 @@ public class Generator
public Generator(ByteBufferPool byteBufferPool)
{
this.byteBufferPool = byteBufferPool;
this.encoder = new HpackEncoder(byteBufferPool);
this.encoder = new HpackEncoder();
}
public ByteBufferPool.Lease generateData(int streamId, ByteBuffer data, boolean last, boolean compress, byte[] paddingBytes)
@ -82,7 +82,7 @@ public class Generator
return lease;
}
public ByteBufferPool.Lease generateHeaders(int streamId, HttpFields headers, boolean contentFollows, byte[] paddingBytes)
public ByteBufferPool.Lease generateHeaders(int streamId, MetaData metaData, boolean contentFollows, byte[] paddingBytes)
{
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
@ -93,9 +93,11 @@ public class Generator
int extraPaddingBytes = paddingLength > 0xFF ? 2 : paddingLength > 0 ? 1 : 0;
ByteBufferPool.Lease hpackBuffers = encoder.encode(headers);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
long hpackLength = hpackBuffers.getTotalLength();
encoder.encode(metaData, lease);
long hpackLength = lease.getTotalLength();
long length = extraPaddingBytes + hpackLength + paddingLength;
if (length > Frame.MAX_LENGTH)
@ -116,16 +118,12 @@ public class Generator
else if (extraPaddingBytes == 1)
header.put((byte)paddingLength);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.merge(hpackBuffers);
lease.prepend(header, true);
if (paddingBytes != null)
{
lease.add(ByteBuffer.wrap(paddingBytes), false);
lease.append(ByteBuffer.wrap(paddingBytes), false);
}
return lease;
@ -150,7 +148,7 @@ public class Generator
header.put((byte)weight);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -167,7 +165,7 @@ public class Generator
header.putInt(error);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -185,7 +183,7 @@ public class Generator
}
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -202,7 +200,7 @@ public class Generator
header.put(payload);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -226,7 +224,7 @@ public class Generator
}
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -245,7 +243,7 @@ public class Generator
header.putInt(windowUpdate);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
return lease;
}
@ -273,13 +271,13 @@ public class Generator
header.put((byte)paddingLength);
BufferUtil.flipToFlush(header, 0);
lease.add(header, true);
lease.append(header, true);
lease.add(data, false);
lease.append(data, false);
if (paddingBytes != null)
{
lease.add(ByteBuffer.wrap(paddingBytes), false);
lease.append(ByteBuffer.wrap(paddingBytes), false);
}
}

View File

@ -0,0 +1,83 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.http2.hpack.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class HeaderBlockParser
{
private final ByteBufferPool byteBufferPool;
private final HpackDecoder hpackDecoder;
private ByteBuffer blockBuffer;
public HeaderBlockParser(ByteBufferPool byteBufferPool, HpackDecoder hpackDecoder)
{
this.byteBufferPool = byteBufferPool;
this.hpackDecoder = hpackDecoder;
}
public MetaData parse(ByteBuffer buffer, int blockLength)
{
// We must wait for the all the bytes of the header block to arrive.
// If they are not all available, accumulate them.
// When all are available, decode them.
int accumulated = blockBuffer == null ? 0 : blockBuffer.position();
int remaining = blockLength - accumulated;
if (buffer.remaining() < remaining)
{
if (blockBuffer == null)
{
blockBuffer = byteBufferPool.acquire(blockLength, false);
BufferUtil.clearToFill(blockBuffer);
}
blockBuffer.put(buffer);
return null;
}
else
{
int limit = buffer.limit();
buffer.limit(buffer.position() + remaining);
ByteBuffer toDecode;
if (blockBuffer != null)
{
blockBuffer.put(buffer);
BufferUtil.flipToFlush(blockBuffer, 0);
toDecode = blockBuffer;
}
else
{
toDecode = buffer;
}
MetaData result = hpackDecoder.decode(toDecode);
buffer.limit(limit);
byteBufferPool.release(blockBuffer);
return result;
}
}
}

View File

@ -20,13 +20,14 @@ package org.eclipse.jetty.http2.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http2.frames.Flag;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.hpack.MetaData;
public class HeadersBodyParser extends BodyParser
{
private final HeaderBlockParser headerBlockParser;
private State state = State.PREPARE;
private int cursor;
private int length;
@ -34,11 +35,11 @@ public class HeadersBodyParser extends BodyParser
private boolean exclusive;
private int streamId;
private int weight;
private HttpFields fields;
public HeadersBodyParser(HeaderParser headerParser, Parser.Listener listener)
public HeadersBodyParser(HeaderParser headerParser, Parser.Listener listener, HeaderBlockParser headerBlockParser)
{
super(headerParser, listener);
this.headerBlockParser = headerBlockParser;
}
private void reset()
@ -50,7 +51,6 @@ public class HeadersBodyParser extends BodyParser
exclusive = false;
streamId = 0;
weight = 0;
fields = null;
}
@Override
@ -63,7 +63,6 @@ public class HeadersBodyParser extends BodyParser
case PREPARE:
{
length = getBodyLength();
fields = new HttpFields();
if (isPaddingHigh())
{
state = State.PADDING_HIGH;
@ -168,12 +167,20 @@ public class HeadersBodyParser extends BodyParser
}
case HEADERS:
{
// TODO: use HpackDecoder
state = State.PADDING;
if (onHeaders(streamId, weight, exclusive, fields))
int blockLength = length - paddingLength;
if (blockLength < 0)
{
return Result.ASYNC;
return notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR, "invalid_headers_frame");
}
MetaData metaData = headerBlockParser.parse(buffer, blockLength);
if (metaData != null)
{
length -= blockLength;
state = State.PADDING;
if (onHeaders(streamId, weight, exclusive, metaData))
{
return Result.ASYNC;
}
}
break;
}
@ -198,14 +205,14 @@ public class HeadersBodyParser extends BodyParser
return Result.PENDING;
}
private boolean onHeaders(int streamId, int weight, boolean exclusive, HttpFields fields)
private boolean onHeaders(int streamId, int weight, boolean exclusive, MetaData metaData)
{
PriorityFrame priorityFrame = null;
if (hasFlag(Flag.PRIORITY))
{
priorityFrame = new PriorityFrame(streamId, getStreamId(), weight, exclusive);
}
HeadersFrame frame = new HeadersFrame(getStreamId(), fields, priorityFrame, isEndStream());
HeadersFrame frame = new HeadersFrame(getStreamId(), metaData, priorityFrame, isEndStream());
return notifyHeaders(frame);
}

View File

@ -29,6 +29,8 @@ import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -41,11 +43,14 @@ public class Parser
private final Listener listener;
private State state = State.HEADER;
public Parser(Listener listener)
public Parser(ByteBufferPool byteBufferPool, Listener listener)
{
this.listener = listener;
HeaderBlockParser headerBlockParser = new HeaderBlockParser(byteBufferPool, new HpackDecoder());
bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener);
bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener);
bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser);
bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener);
bodyParsers[FrameType.RST_STREAM.getType()] = new ResetBodyParser(headerParser, listener);
bodyParsers[FrameType.SETTINGS.getType()] = new SettingsBodyParser(headerParser, listener);

View File

@ -0,0 +1,60 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.api;
import org.junit.Ignore;
import org.junit.Test;
public class UsageTest
{
@Ignore
@Test
public void test() throws Exception
{
// HTTP2Client client = new HTTP2Client();
// client.connect("localhost", 8080, new Promise.Adapter<Session>()
// {
// @Override
// public void succeeded(Session session)
// {
// session.newStream(new HeadersFrame(0, info, null, true), new Stream.Listener.Adapter()
// {
// @Override
// public void onData(Stream stream, DataFrame frame)
// {
// System.out.println("received frame = " + frame);
// }
// }, new Adapter<Stream>()
// {
// @Override
// public void succeeded(Stream stream)
// {
// DataFrame frame = new DataFrame(stream.getId(), ByteBuffer.wrap("HELLO".getBytes(StandardCharsets.UTF_8)), true);
// stream.data(frame, new Callback.Adapter());
// }
// });
// }
// });
// KINDA CALLBACK HELL ABOVE.
// BELOW USING COMPLETABLES:
// client.connect("localhost", 8080).then(session -> session.newStream(...)).then(stream -> stream.data(...));
}
}

View File

@ -144,7 +144,7 @@ public class DataGenerateParseTest
lease = lease.merge(generator.generateData(13, data[j - 1].slice(), j == data.length, false, new byte[paddingLength]));
}
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onData(DataFrame frame)
@ -172,7 +172,7 @@ public class DataGenerateParseTest
ByteBufferPool.Lease lease = generator.generateData(13, ByteBuffer.wrap(largeContent).slice(), true, false, new byte[1024]);
final List<DataFrame> frames = new ArrayList<>();
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onData(DataFrame frame)

View File

@ -47,7 +47,7 @@ public class GoAwayGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generateGoAway(lastStreamId, error, null);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onGoAway(GoAwayFrame frame)
@ -86,7 +86,7 @@ public class GoAwayGenerateParseTest
final List<GoAwayFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generateGoAway(lastStreamId, error, payload);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onGoAway(GoAwayFrame frame)

View File

@ -47,7 +47,7 @@ public class PingGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generatePing(payload, true);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onPing(PingFrame frame)
@ -83,7 +83,7 @@ public class PingGenerateParseTest
final List<PingFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generatePing(payload, true);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onPing(PingFrame frame)

View File

@ -48,7 +48,7 @@ public class PriorityGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generatePriority(streamId, dependentStreamId, weight, exclusive);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onPriority(PriorityFrame frame)
@ -88,7 +88,7 @@ public class PriorityGenerateParseTest
final List<PriorityFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generatePriority(streamId, dependentStreamId, weight, exclusive);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onPriority(PriorityFrame frame)

View File

@ -46,7 +46,7 @@ public class ResetGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generateReset(streamId, error);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onReset(ResetFrame frame)
@ -82,7 +82,7 @@ public class ResetGenerateParseTest
final List<ResetFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generateReset(streamId, error);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onReset(ResetFrame frame)

View File

@ -76,7 +76,7 @@ public class SettingsGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generateSettings(settings, true);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onSettings(SettingsFrame frame)
@ -111,7 +111,7 @@ public class SettingsGenerateParseTest
bytes.putShort(0, (short)(bytes.getShort(0) - 1));
final AtomicInteger errorRef = new AtomicInteger();
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
@ -143,7 +143,7 @@ public class SettingsGenerateParseTest
final List<SettingsFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generateSettings(settings1, true);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onSettings(SettingsFrame frame)

View File

@ -46,7 +46,7 @@ public class WindowUpdateGenerateParseTest
for (int i = 0; i < 2; ++i)
{
ByteBufferPool.Lease lease = generator.generateWindowUpdate(streamId, windowUpdate);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onWindowUpdate(WindowUpdateFrame frame)
@ -82,7 +82,7 @@ public class WindowUpdateGenerateParseTest
final List<WindowUpdateFrame> frames = new ArrayList<>();
ByteBufferPool.Lease lease = generator.generateWindowUpdate(streamId, windowUpdate);
Parser parser = new Parser(new Parser.Listener.Adapter()
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public boolean onWindowUpdate(WindowUpdateFrame frame)

View File

@ -1,17 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>jetty-project</artifactId>
<groupId>org.eclipse.jetty</groupId>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-hpack</artifactId>
<name>Jetty :: HPACK Utility</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.http</bundle-symbolic-name>
</properties>
<artifactId>http2-hpack</artifactId>
<name>Jetty :: HTTP2 :: HPACK</name>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@ -34,6 +32,7 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@ -56,33 +55,13 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>artifact-jar</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>test-jar</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.eclipse.jetty.http.*</onlyAnalyze>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
import java.util.HashMap;

View File

@ -17,13 +17,13 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
import org.eclipse.jetty.hpack.HpackContext.Entry;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
/* ------------------------------------------------------------ */

View File

@ -17,17 +17,15 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import org.eclipse.jetty.hpack.HpackContext.Entry;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.io.ByteBufferPool.Lease;
public class HpackEncoder

View File

@ -16,9 +16,8 @@
// ========================================================================
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.io.IOException;
import java.nio.ByteBuffer;
public class Huffman

View File

@ -17,7 +17,7 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.util.Iterator;

View File

@ -17,7 +17,7 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.util.ArrayList;
import java.util.List;
@ -126,4 +126,4 @@ public class MetaDataBuilder
_fields.clear();
}
}
}
}

View File

@ -16,7 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;

View File

@ -17,26 +17,26 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.eclipse.jetty.hpack.HpackContext.Entry;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/* ------------------------------------------------------------ */
/**

View File

@ -17,9 +17,7 @@
//
package org.eclipse.jetty.hpack;
import static org.junit.Assert.*;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
import java.util.Iterator;
@ -30,6 +28,10 @@ import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/* ------------------------------------------------------------ */
/**
@ -49,7 +51,7 @@ public class HpackDecoderTest
MetaData.Request request = (MetaData.Request)decoder.decode(buffer);
assertEquals(HttpMethod.GET,request.getMethod());
assertEquals("GET",request.getMethodString());
assertEquals("GET", request.getMethodString());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
@ -63,7 +65,7 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals(HttpMethod.GET,request.getMethod());
assertEquals("GET",request.getMethodString());
assertEquals("GET", request.getMethodString());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
@ -104,7 +106,7 @@ public class HpackDecoderTest
MetaData.Request request = (MetaData.Request)decoder.decode(buffer);
assertEquals(HttpMethod.GET,request.getMethod());
assertEquals("GET",request.getMethodString());
assertEquals("GET", request.getMethodString());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());
@ -118,7 +120,7 @@ public class HpackDecoderTest
request = (MetaData.Request)decoder.decode(buffer);
assertEquals(HttpMethod.GET,request.getMethod());
assertEquals("GET",request.getMethodString());
assertEquals("GET", request.getMethodString());
assertEquals(HttpScheme.HTTP,request.getScheme());
assertEquals("/",request.getPath());
assertEquals("www.example.com",request.getAuthority());

View File

@ -17,22 +17,22 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import static org.junit.Assert.assertThat;
import java.nio.ByteBuffer;
import java.util.HashSet;
import org.eclipse.jetty.hpack.HpackContext.Entry;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http2.hpack.HpackContext.Entry;
import org.eclipse.jetty.util.BufferUtil;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertThat;
/* ------------------------------------------------------------ */
/**

View File

@ -17,7 +17,7 @@
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import org.eclipse.jetty.http.HttpFields;
import org.junit.Test;

View File

@ -16,13 +16,13 @@
// ========================================================================
//
package org.eclipse.jetty.hpack;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
import org.junit.Assert;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.junit.Assert;
import org.junit.Test;
public class HuffmanTest

View File

@ -16,9 +16,7 @@
// ========================================================================
//
package org.eclipse.jetty.hpack;
import static org.junit.Assert.assertEquals;
package org.eclipse.jetty.http2.hpack;
import java.nio.ByteBuffer;
@ -27,6 +25,8 @@ import org.eclipse.jetty.util.TypeUtil;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class NBitIntegerTest
{

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>http2-server</artifactId>
<name>Jetty :: HTTP2 :: Server</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",javax.net.*,*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>http2-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,109 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.server;
import org.eclipse.jetty.http2.HTTP2Connection;
import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.parser.Parser;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.AbstractConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class HTTP2ServerConnectionFactory extends AbstractConnectionFactory
{
private static final Logger LOG = Log.getLogger(HTTP2ServerConnectionFactory.class);
private final HttpConfiguration httpConfiguration;
public HTTP2ServerConnectionFactory(HttpConfiguration httpConfiguration)
{
super("h2");
this.httpConfiguration = httpConfiguration;
}
@Override
public Connection newConnection(Connector connector, EndPoint endPoint)
{
Session.Listener listener = new HTTPServerSessionListener(connector, httpConfiguration, endPoint);
HTTP2Session session = new HTTP2ServerSession(listener);
Parser parser = new Parser(connector.getByteBufferPool(), session);
HTTP2Connection connection = new HTTP2Connection(connector.getByteBufferPool(), connector.getExecutor(),
endPoint, parser, getInputBufferSize());
return configure(connection, connector, endPoint);
}
private class HTTPServerSessionListener extends ServerSessionListener.Adapter implements Stream.Listener
{
private final Connector connector;
private final HttpConfiguration httpConfiguration;
private final EndPoint endPoint;
public HTTPServerSessionListener(Connector connector, HttpConfiguration httpConfiguration, EndPoint endPoint)
{
this.connector = connector;
this.httpConfiguration = httpConfiguration;
this.endPoint = endPoint;
}
@Override
public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
{
LOG.debug("Received {} on {}", frame, stream);
HttpTransportOverHTTP2 transport = new HttpTransportOverHTTP2();
HttpInputOverHTTP2 input = new HttpInputOverHTTP2();
HttpChannelOverHTTP2 channel = new HttpChannelOverHTTP2(connector, httpConfiguration, endPoint, transport, input);
// TODO: link channel to stream.
// if (frame.getMetaData().isEmpty())
// {
// TODO: abort.
// return null;
// }
channel.requestStart(frame);
return frame.isEndStream() ? null : this;
}
@Override
public void onData(Stream stream, DataFrame frame)
{
}
@Override
public void onFailure(Stream stream, Throwable x)
{
}
}
}

View File

@ -0,0 +1,54 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.server;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.jetty.http2.HTTP2Session;
import org.eclipse.jetty.http2.HTTP2Stream;
import org.eclipse.jetty.http2.IStream;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.frames.HeadersFrame;
public class HTTP2ServerSession extends HTTP2Session
{
private final ConcurrentMap<Integer, IStream> streams = new ConcurrentHashMap<>();
public HTTP2ServerSession(Listener listener)
{
super(listener);
}
@Override
public boolean onHeaders(HeadersFrame frame)
{
// TODO: handle max concurrent streams
// TODO: handle duplicate streams
IStream stream = new HTTP2Stream();
IStream existing = streams.putIfAbsent(stream.getId(), stream);
if (existing == null)
{
Stream.Listener listener = notifyNewStream(stream, frame);
stream.setListener(listener);
}
return false;
}
}

View File

@ -0,0 +1,53 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpInput;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.util.BufferUtil;
public class HttpChannelOverHTTP2 extends HttpChannel<ByteBuffer>
{
public HttpChannelOverHTTP2(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport, HttpInput<ByteBuffer> input)
{
super(connector, configuration, endPoint, transport, input);
}
public void requestStart(HeadersFrame frame)
{
// TODO: extract method, etc.
HttpMethod httpMethod = null;
String method = null;
ByteBuffer uri = BufferUtil.toBuffer(0);
HttpVersion version = null;
startRequest(httpMethod, method, uri, version);
// TODO: See SPDY's
}
}

View File

@ -0,0 +1,48 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.server.QueuedHttpInput;
public class HttpInputOverHTTP2 extends QueuedHttpInput<ByteBuffer>
{
@Override
protected void onContentConsumed(ByteBuffer item)
{
}
@Override
protected int remaining(ByteBuffer item)
{
return 0;
}
@Override
protected int get(ByteBuffer item, byte[] buffer, int offset, int length)
{
return 0;
}
@Override
protected void consume(ByteBuffer item, int length)
{
}
}

View File

@ -0,0 +1,48 @@
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.http2.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.util.Callback;
public class HttpTransportOverHTTP2 implements HttpTransport
{
@Override
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
{
}
@Override
public void send(ByteBuffer content, boolean lastContent, Callback callback)
{
}
@Override
public void completed()
{
}
@Override
public void abort()
{
}
}

View File

@ -5,40 +5,19 @@
<groupId>org.eclipse.jetty</groupId>
<version>10.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-http2</artifactId>
<name>Jetty :: Http2 Utility</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.http</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-hpack</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-parent</artifactId>
<packaging>pom</packaging>
<name>Jetty :: HTTP2</name>
<modules>
<module>http2-hpack</module>
<module>http2-common</module>
<module>http2-server</module>
</modules>
<build>
<plugins>
<plugin>
@ -52,7 +31,9 @@
</goals>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",javax.net.*,*</Import-Package>
<Export-Package>org.eclipse.jetty.http2.*;version="9.1"</Export-Package>
<Import-Package>org.eclipse.jetty.*;version="[9.0,10.0)",*</Import-Package>
<_nouses>true</_nouses>
</instructions>
</configuration>
</execution>
@ -61,33 +42,13 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>artifact-jar</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
<execution>
<id>test-jar</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.eclipse.jetty.http.*</onlyAnalyze>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -418,7 +418,6 @@
<module>jetty-jmx</module>
<module>jetty-io</module>
<module>jetty-http</module>
<module>jetty-hpack</module>
<module>jetty-http2</module>
<module>jetty-continuation</module>
<module>jetty-server</module>