Merge branch 'master' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project

This commit is contained in:
Jan Bartel 2012-06-01 20:00:46 +02:00
commit 40014a93d0
32 changed files with 936 additions and 227 deletions

View File

@ -20,7 +20,6 @@ import org.eclipse.jetty.spdy.api.SessionStatus;
public class SessionException extends RuntimeException public class SessionException extends RuntimeException
{ {
private final SessionStatus sessionStatus; private final SessionStatus sessionStatus;
public SessionException(SessionStatus sessionStatus) public SessionException(SessionStatus sessionStatus)

View File

@ -52,6 +52,7 @@ import org.eclipse.jetty.spdy.api.StreamStatus;
import org.eclipse.jetty.spdy.api.SynInfo; import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.frames.ControlFrame; import org.eclipse.jetty.spdy.frames.ControlFrame;
import org.eclipse.jetty.spdy.frames.ControlFrameType; import org.eclipse.jetty.spdy.frames.ControlFrameType;
import org.eclipse.jetty.spdy.frames.CredentialFrame;
import org.eclipse.jetty.spdy.frames.DataFrame; import org.eclipse.jetty.spdy.frames.DataFrame;
import org.eclipse.jetty.spdy.frames.GoAwayFrame; import org.eclipse.jetty.spdy.frames.GoAwayFrame;
import org.eclipse.jetty.spdy.frames.HeadersFrame; import org.eclipse.jetty.spdy.frames.HeadersFrame;
@ -157,7 +158,8 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
synchronized (this) synchronized (this)
{ {
int streamId = streamIds.getAndAdd(2); int streamId = streamIds.getAndAdd(2);
SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), synInfo.getHeaders()); // TODO: for SPDYv3 we need to support the "slot" argument
SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders());
IStream stream = createStream(synStream, listener, true); IStream stream = createStream(synStream, listener, true);
generateAndEnqueueControlFrame(stream, synStream, timeout, unit, handler, stream); generateAndEnqueueControlFrame(stream, synStream, timeout, unit, handler, stream);
} }
@ -328,6 +330,11 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
onWindowUpdate((WindowUpdateFrame)frame); onWindowUpdate((WindowUpdateFrame)frame);
break; break;
} }
case CREDENTIAL:
{
onCredential((CredentialFrame)frame);
break;
}
default: default:
{ {
throw new IllegalStateException(); throw new IllegalStateException();
@ -633,6 +640,12 @@ public class StandardSession implements ISession, Parser.Listener, Handler<Stand
flush(); flush();
} }
private void onCredential(CredentialFrame frame)
{
logger.warn("{} frame not yet supported", ControlFrameType.CREDENTIAL);
flush();
}
protected void close() protected void close()
{ {
// Check for null to support tests // Check for null to support tests

View File

@ -29,7 +29,8 @@ public enum ControlFrameType
PING((short)6), PING((short)6),
GO_AWAY((short)7), GO_AWAY((short)7),
HEADERS((short)8), HEADERS((short)8),
WINDOW_UPDATE((short)9); WINDOW_UPDATE((short)9),
CREDENTIAL((short)10);
public static ControlFrameType from(short code) public static ControlFrameType from(short code)
{ {

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.frames;
import java.security.cert.Certificate;
public class CredentialFrame extends ControlFrame
{
private final short slot;
private final byte[] proof;
private final Certificate[] certificateChain;
public CredentialFrame(short version, short slot, byte[] proof, Certificate[] certificateChain)
{
super(version, ControlFrameType.CREDENTIAL, (byte)0);
this.slot = slot;
this.proof = proof;
this.certificateChain = certificateChain;
}
public short getSlot()
{
return slot;
}
public byte[] getProof()
{
return proof;
}
public Certificate[] getCertificateChain()
{
return certificateChain;
}
}

View File

@ -25,14 +25,16 @@ public class SynStreamFrame extends ControlFrame
private final int streamId; private final int streamId;
private final int associatedStreamId; private final int associatedStreamId;
private final byte priority; private final byte priority;
private final short slot;
private final Headers headers; private final Headers headers;
public SynStreamFrame(short version, byte flags, int streamId, int associatedStreamId, byte priority, Headers headers) public SynStreamFrame(short version, byte flags, int streamId, int associatedStreamId, byte priority, short slot, Headers headers)
{ {
super(version, ControlFrameType.SYN_STREAM, flags); super(version, ControlFrameType.SYN_STREAM, flags);
this.streamId = streamId; this.streamId = streamId;
this.associatedStreamId = associatedStreamId; this.associatedStreamId = associatedStreamId;
this.priority = priority; this.priority = priority;
this.slot = slot;
this.headers = headers; this.headers = headers;
} }
@ -51,6 +53,11 @@ public class SynStreamFrame extends ControlFrame
return priority; return priority;
} }
public short getSlot()
{
return slot;
}
public Headers getHeaders() public Headers getHeaders()
{ {
return headers; return headers;

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.generator;
import java.nio.ByteBuffer;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.spdy.ByteBufferPool;
import org.eclipse.jetty.spdy.SessionException;
import org.eclipse.jetty.spdy.api.SessionStatus;
import org.eclipse.jetty.spdy.frames.ControlFrame;
import org.eclipse.jetty.spdy.frames.CredentialFrame;
public class CredentialGenerator extends ControlFrameGenerator
{
public CredentialGenerator(ByteBufferPool bufferPool)
{
super(bufferPool);
}
@Override
public ByteBuffer generate(ControlFrame frame)
{
CredentialFrame credential = (CredentialFrame)frame;
byte[] proof = credential.getProof();
List<byte[]> certificates = serializeCertificates(credential.getCertificateChain());
int certificatesLength = 0;
for (byte[] certificate : certificates)
certificatesLength += certificate.length;
int frameBodyLength = 2 + 4 + proof.length + certificates.size() * 4 + certificatesLength;
int totalLength = ControlFrame.HEADER_LENGTH + frameBodyLength;
ByteBuffer buffer = getByteBufferPool().acquire(totalLength, true);
generateControlFrameHeader(credential, frameBodyLength, buffer);
buffer.putShort(credential.getSlot());
buffer.putInt(proof.length);
buffer.put(proof);
for (byte[] certificate : certificates)
{
buffer.putInt(certificate.length);
buffer.put(certificate);
}
buffer.flip();
return buffer;
}
private List<byte[]> serializeCertificates(Certificate[] certificates)
{
try
{
List<byte[]> result = new ArrayList<>(certificates.length);
for (Certificate certificate : certificates)
result.add(certificate.getEncoded());
return result;
}
catch (CertificateEncodingException x)
{
throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
}
}
}

View File

@ -42,6 +42,7 @@ public class Generator
generators.put(ControlFrameType.GO_AWAY, new GoAwayGenerator(bufferPool)); generators.put(ControlFrameType.GO_AWAY, new GoAwayGenerator(bufferPool));
generators.put(ControlFrameType.HEADERS, new HeadersGenerator(bufferPool, headersBlockGenerator)); generators.put(ControlFrameType.HEADERS, new HeadersGenerator(bufferPool, headersBlockGenerator));
generators.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateGenerator(bufferPool)); generators.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateGenerator(bufferPool));
generators.put(ControlFrameType.CREDENTIAL, new CredentialGenerator(bufferPool));
dataFrameGenerator = new DataFrameGenerator(bufferPool); dataFrameGenerator = new DataFrameGenerator(bufferPool);
} }

View File

@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.spdy.ByteBufferPool; import org.eclipse.jetty.spdy.ByteBufferPool;
import org.eclipse.jetty.spdy.SessionException; import org.eclipse.jetty.spdy.SessionException;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.SessionStatus; import org.eclipse.jetty.spdy.api.SessionStatus;
import org.eclipse.jetty.spdy.frames.ControlFrame; import org.eclipse.jetty.spdy.frames.ControlFrame;
import org.eclipse.jetty.spdy.frames.HeadersFrame; import org.eclipse.jetty.spdy.frames.HeadersFrame;
@ -43,6 +44,8 @@ public class HeadersGenerator extends ControlFrameGenerator
ByteBuffer headersBuffer = headersBlockGenerator.generate(version, headers.getHeaders()); ByteBuffer headersBuffer = headersBlockGenerator.generate(version, headers.getHeaders());
int frameBodyLength = 4; int frameBodyLength = 4;
if (frame.getVersion() == SPDY.V2)
frameBodyLength += 2;
int frameLength = frameBodyLength + headersBuffer.remaining(); int frameLength = frameBodyLength + headersBuffer.remaining();
if (frameLength > 0xFF_FF_FF) if (frameLength > 0xFF_FF_FF)
@ -58,6 +61,8 @@ public class HeadersGenerator extends ControlFrameGenerator
generateControlFrameHeader(headers, frameLength, buffer); generateControlFrameHeader(headers, frameLength, buffer);
buffer.putInt(headers.getStreamId() & 0x7F_FF_FF_FF); buffer.putInt(headers.getStreamId() & 0x7F_FF_FF_FF);
if (frame.getVersion() == SPDY.V2)
buffer.putShort((short)0);
buffer.put(headersBuffer); buffer.put(headersBuffer);

View File

@ -64,6 +64,7 @@ public class SynStreamGenerator extends ControlFrameGenerator
buffer.putInt(streamId & 0x7F_FF_FF_FF); buffer.putInt(streamId & 0x7F_FF_FF_FF);
buffer.putInt(synStream.getAssociatedStreamId() & 0x7F_FF_FF_FF); buffer.putInt(synStream.getAssociatedStreamId() & 0x7F_FF_FF_FF);
writePriority(streamId, version, synStream.getPriority(), buffer); writePriority(streamId, version, synStream.getPriority(), buffer);
buffer.put((byte)synStream.getSlot());
buffer.put(headersBuffer); buffer.put(headersBuffer);
@ -85,6 +86,5 @@ public class SynStreamGenerator extends ControlFrameGenerator
throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION); throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION);
} }
buffer.put(priority); buffer.put(priority);
buffer.put((byte)0);
} }
} }

View File

@ -46,6 +46,7 @@ public abstract class ControlFrameParser
parsers.put(ControlFrameType.GO_AWAY, new GoAwayBodyParser(this)); parsers.put(ControlFrameType.GO_AWAY, new GoAwayBodyParser(this));
parsers.put(ControlFrameType.HEADERS, new HeadersBodyParser(decompressor, this)); parsers.put(ControlFrameType.HEADERS, new HeadersBodyParser(decompressor, this));
parsers.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateBodyParser(this)); parsers.put(ControlFrameType.WINDOW_UPDATE, new WindowUpdateBodyParser(this));
parsers.put(ControlFrameType.CREDENTIAL, new CredentialBodyParser(this));
} }
public short getVersion() public short getVersion()

View File

@ -0,0 +1,272 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.parser;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jetty.spdy.SessionException;
import org.eclipse.jetty.spdy.api.SessionStatus;
import org.eclipse.jetty.spdy.frames.ControlFrameType;
import org.eclipse.jetty.spdy.frames.CredentialFrame;
public class CredentialBodyParser extends ControlFrameBodyParser
{
private final List<Certificate> certificates = new ArrayList<>();
private final ControlFrameParser controlFrameParser;
private State state = State.SLOT;
private int totalLength;
private int cursor;
private short slot;
private int proofLength;
private byte[] proof;
private int certificateLength;
private byte[] certificate;
public CredentialBodyParser(ControlFrameParser controlFrameParser)
{
this.controlFrameParser = controlFrameParser;
}
@Override
public boolean parse(ByteBuffer buffer)
{
while (buffer.hasRemaining())
{
switch (state)
{
case SLOT:
{
if (buffer.remaining() >= 2)
{
slot = buffer.getShort();
checkSlotValid();
state = State.PROOF_LENGTH;
}
else
{
state = State.SLOT_BYTES;
cursor = 2;
}
break;
}
case SLOT_BYTES:
{
byte currByte = buffer.get();
--cursor;
slot += (currByte & 0xFF) << 8 * cursor;
if (cursor == 0)
{
checkSlotValid();
state = State.PROOF_LENGTH;
}
break;
}
case PROOF_LENGTH:
{
if (buffer.remaining() >= 4)
{
proofLength = buffer.getInt() & 0x7F_FF_FF_FF;
state = State.PROOF;
}
else
{
state = State.PROOF_LENGTH_BYTES;
cursor = 4;
}
break;
}
case PROOF_LENGTH_BYTES:
{
byte currByte = buffer.get();
--cursor;
proofLength += (currByte & 0xFF) << 8 * cursor;
if (cursor == 0)
{
proofLength &= 0x7F_FF_FF_FF;
state = State.PROOF;
}
break;
}
case PROOF:
{
totalLength = controlFrameParser.getLength() - 2 - 4 - proofLength;
proof = new byte[proofLength];
if (buffer.remaining() >= proofLength)
{
buffer.get(proof);
state = State.CERTIFICATE_LENGTH;
if (totalLength == 0)
{
onCredential();
return true;
}
}
else
{
state = State.PROOF_BYTES;
cursor = proofLength;
}
break;
}
case PROOF_BYTES:
{
proof[proofLength - cursor] = buffer.get();
--cursor;
if (cursor == 0)
{
state = State.CERTIFICATE_LENGTH;
if (totalLength == 0)
{
onCredential();
return true;
}
}
break;
}
case CERTIFICATE_LENGTH:
{
if (buffer.remaining() >= 4)
{
certificateLength = buffer.getInt() & 0x7F_FF_FF_FF;
state = State.CERTIFICATE;
}
else
{
state = State.CERTIFICATE_LENGTH_BYTES;
cursor = 4;
}
break;
}
case CERTIFICATE_LENGTH_BYTES:
{
byte currByte = buffer.get();
--cursor;
certificateLength += (currByte & 0xFF) << 8 * cursor;
if (cursor == 0)
{
certificateLength &= 0x7F_FF_FF_FF;
state = State.CERTIFICATE;
}
break;
}
case CERTIFICATE:
{
totalLength -= 4 + certificateLength;
certificate = new byte[certificateLength];
if (buffer.remaining() >= certificateLength)
{
buffer.get(certificate);
if (onCertificate())
return true;
}
else
{
state = State.CERTIFICATE_BYTES;
cursor = certificateLength;
}
break;
}
case CERTIFICATE_BYTES:
{
certificate[certificateLength - cursor] = buffer.get();
--cursor;
if (cursor == 0)
{
if (onCertificate())
return true;
}
break;
}
default:
{
throw new IllegalStateException();
}
}
}
return false;
}
private void checkSlotValid()
{
if (slot <= 0)
throw new SessionException(SessionStatus.PROTOCOL_ERROR,
"Invalid slot " + slot + " for " + ControlFrameType.CREDENTIAL + " frame");
}
private boolean onCertificate()
{
certificates.add(deserializeCertificate(certificate));
if (totalLength == 0)
{
onCredential();
return true;
}
else
{
certificateLength = 0;
state = State.CERTIFICATE_LENGTH;
}
return false;
}
private Certificate deserializeCertificate(byte[] bytes)
{
try
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
return certificateFactory.generateCertificate(new ByteArrayInputStream(bytes));
}
catch (CertificateException x)
{
throw new SessionException(SessionStatus.PROTOCOL_ERROR, x);
}
}
private void onCredential()
{
CredentialFrame frame = new CredentialFrame(controlFrameParser.getVersion(), slot,
Arrays.copyOf(proof, proof.length), certificates.toArray(new Certificate[certificates.size()]));
controlFrameParser.onControlFrame(frame);
reset();
}
private void reset()
{
state = State.SLOT;
totalLength = 0;
cursor = 0;
slot = 0;
proofLength = 0;
proof = null;
certificateLength = 0;
certificate = null;
certificates.clear();
}
public enum State
{
SLOT, SLOT_BYTES, PROOF_LENGTH, PROOF_LENGTH_BYTES, PROOF, PROOF_BYTES,
CERTIFICATE_LENGTH, CERTIFICATE_LENGTH_BYTES, CERTIFICATE, CERTIFICATE_BYTES
}
}

View File

@ -24,7 +24,7 @@ import org.eclipse.jetty.spdy.frames.GoAwayFrame;
public class GoAwayBodyParser extends ControlFrameBodyParser public class GoAwayBodyParser extends ControlFrameBodyParser
{ {
private final ControlFrameParser controlFrameParser; private final ControlFrameParser controlFrameParser;
private State state = State.LAST_STREAM_ID; private State state = State.LAST_GOOD_STREAM_ID;
private int cursor; private int cursor;
private int lastStreamId; private int lastStreamId;
private int statusCode; private int statusCode;
@ -41,7 +41,7 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
{ {
switch (state) switch (state)
{ {
case LAST_STREAM_ID: case LAST_GOOD_STREAM_ID:
{ {
if (buffer.remaining() >= 4) if (buffer.remaining() >= 4)
{ {
@ -66,12 +66,12 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
} }
else else
{ {
state = State.LAST_STREAM_ID_BYTES; state = State.LAST_GOOD_STREAM_ID_BYTES;
cursor = 4; cursor = 4;
} }
break; break;
} }
case LAST_STREAM_ID_BYTES: case LAST_GOOD_STREAM_ID_BYTES:
{ {
byte currByte = buffer.get(); byte currByte = buffer.get();
--cursor; --cursor;
@ -144,7 +144,7 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
private void reset() private void reset()
{ {
state = State.LAST_STREAM_ID; state = State.LAST_GOOD_STREAM_ID;
cursor = 0; cursor = 0;
lastStreamId = 0; lastStreamId = 0;
statusCode = 0; statusCode = 0;
@ -152,6 +152,6 @@ public class GoAwayBodyParser extends ControlFrameBodyParser
private enum State private enum State
{ {
LAST_STREAM_ID, LAST_STREAM_ID_BYTES, STATUS_CODE, STATUS_CODE_BYTES LAST_GOOD_STREAM_ID, LAST_GOOD_STREAM_ID_BYTES, STATUS_CODE, STATUS_CODE_BYTES
} }
} }

View File

@ -21,6 +21,7 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.spdy.CompressionFactory; import org.eclipse.jetty.spdy.CompressionFactory;
import org.eclipse.jetty.spdy.api.Headers; import org.eclipse.jetty.spdy.api.Headers;
import org.eclipse.jetty.spdy.api.HeadersInfo; import org.eclipse.jetty.spdy.api.HeadersInfo;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.frames.ControlFrameType; import org.eclipse.jetty.spdy.frames.ControlFrameType;
import org.eclipse.jetty.spdy.frames.HeadersFrame; import org.eclipse.jetty.spdy.frames.HeadersFrame;
@ -51,7 +52,7 @@ public class HeadersBodyParser extends ControlFrameBodyParser
if (buffer.remaining() >= 4) if (buffer.remaining() >= 4)
{ {
streamId = buffer.getInt() & 0x7F_FF_FF_FF; streamId = buffer.getInt() & 0x7F_FF_FF_FF;
state = State.HEADERS; state = State.ADDITIONAL;
} }
else else
{ {
@ -68,14 +69,55 @@ public class HeadersBodyParser extends ControlFrameBodyParser
if (cursor == 0) if (cursor == 0)
{ {
streamId &= 0x7F_FF_FF_FF; streamId &= 0x7F_FF_FF_FF;
state = State.HEADERS; state = State.ADDITIONAL;
} }
break; break;
} }
case ADDITIONAL:
{
switch (controlFrameParser.getVersion())
{
case SPDY.V2:
{
if (buffer.remaining() >= 2)
{
buffer.getShort();
state = State.HEADERS;
}
else
{
state = State.ADDITIONAL_BYTES;
cursor = 2;
}
break;
}
case SPDY.V3:
{
state = State.HEADERS;
break;
}
default:
{
throw new IllegalStateException();
}
}
break;
}
case ADDITIONAL_BYTES:
{
assert controlFrameParser.getVersion() == SPDY.V2;
buffer.get();
--cursor;
if (cursor == 0)
state = State.HEADERS;
break;
}
case HEADERS: case HEADERS:
{ {
short version = controlFrameParser.getVersion(); short version = controlFrameParser.getVersion();
int length = controlFrameParser.getLength() - 4; int length = controlFrameParser.getLength() - 4;
if (version == SPDY.V2)
length -= 2;
if (headersBlockParser.parse(streamId, version, length, buffer)) if (headersBlockParser.parse(streamId, version, length, buffer))
{ {
byte flags = controlFrameParser.getFlags(); byte flags = controlFrameParser.getFlags();
@ -109,7 +151,7 @@ public class HeadersBodyParser extends ControlFrameBodyParser
private enum State private enum State
{ {
STREAM_ID, STREAM_ID_BYTES, HEADERS STREAM_ID, STREAM_ID_BYTES, ADDITIONAL, ADDITIONAL_BYTES, HEADERS
} }
private class HeadersHeadersBlockParser extends HeadersBlockParser private class HeadersHeadersBlockParser extends HeadersBlockParser

View File

@ -38,6 +38,7 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
private int streamId; private int streamId;
private int associatedStreamId; private int associatedStreamId;
private byte priority; private byte priority;
private short slot;
public SynStreamBodyParser(CompressionFactory.Decompressor decompressor, ControlFrameParser controlFrameParser) public SynStreamBodyParser(CompressionFactory.Decompressor decompressor, ControlFrameParser controlFrameParser)
{ {
@ -118,7 +119,9 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
} }
else else
{ {
// Unused byte after priority, skip it slot = (short)(currByte & 0xFF);
if (slot < 0)
throw new StreamException(streamId, StreamStatus.INVALID_CREDENTIALS);
cursor = 0; cursor = 0;
state = State.HEADERS; state = State.HEADERS;
} }
@ -134,7 +137,7 @@ public class SynStreamBodyParser extends ControlFrameBodyParser
if (flags > (SynInfo.FLAG_CLOSE | PushSynInfo.FLAG_UNIDIRECTIONAL)) if (flags > (SynInfo.FLAG_CLOSE | PushSynInfo.FLAG_UNIDIRECTIONAL))
throw new IllegalArgumentException("Invalid flag " + flags + " for frame " + ControlFrameType.SYN_STREAM); throw new IllegalArgumentException("Invalid flag " + flags + " for frame " + ControlFrameType.SYN_STREAM);
SynStreamFrame frame = new SynStreamFrame(version, flags, streamId, associatedStreamId, priority, new Headers(headers, true)); SynStreamFrame frame = new SynStreamFrame(version, flags, streamId, associatedStreamId, priority, slot, new Headers(headers, true));
controlFrameParser.onControlFrame(frame); controlFrameParser.onControlFrame(frame);
reset(); reset();

View File

@ -404,8 +404,8 @@ public class StandardSessionTest
setControllerWriteExpectationToFail(true); setControllerWriteExpectationToFail(true);
final CountDownLatch failedCalledLatch = new CountDownLatch(2); final CountDownLatch failedCalledLatch = new CountDownLatch(2);
SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2,SynInfo.FLAG_CLOSE,1,0,(byte)0,null); SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
IStream stream = new StandardStream(synStreamFrame,session,null); IStream stream = new StandardStream(synStreamFrame, session, null);
stream.updateWindowSize(8192); stream.updateWindowSize(8192);
Handler.Adapter<Void> handler = new Handler.Adapter<Void>() Handler.Adapter<Void> handler = new Handler.Adapter<Void>()
{ {
@ -417,13 +417,12 @@ public class StandardSessionTest
}; };
// first data frame should fail on controller.write() // first data frame should fail on controller.write()
stream.data(new StringDataInfo("data",false),5,TimeUnit.SECONDS,handler); stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, handler);
// second data frame should fail without controller.writer() as the connection is expected to be broken after first controller.write() call failed. // second data frame should fail without controller.writer() as the connection is expected to be broken after first controller.write() call failed.
stream.data(new StringDataInfo("data",false),5,TimeUnit.SECONDS,handler); stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, handler);
verify(controller,times(1)).write(any(ByteBuffer.class),any(Handler.class),any(FrameBytes.class));
assertThat("Handler.failed has been called twice",failedCalledLatch.await(5,TimeUnit.SECONDS),is(true));
verify(controller, times(1)).write(any(ByteBuffer.class), any(Handler.class), any(FrameBytes.class));
assertThat("Handler.failed has been called twice", failedCalledLatch.await(5, TimeUnit.SECONDS), is(true));
} }
private IStream createStream() throws InterruptedException, ExecutionException, TimeoutException private IStream createStream() throws InterruptedException, ExecutionException, TimeoutException

View File

@ -120,12 +120,12 @@ public class StandardStreamTest
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void testSendDataOnHalfClosedStream() throws InterruptedException, ExecutionException, TimeoutException public void testSendDataOnHalfClosedStream() throws InterruptedException, ExecutionException, TimeoutException
{ {
SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2,SynInfo.FLAG_CLOSE,1,0,(byte)0,null); SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
IStream stream = new StandardStream(synStreamFrame,session,null); IStream stream = new StandardStream(synStreamFrame, session, null);
stream.updateWindowSize(8192); stream.updateWindowSize(8192);
stream.updateCloseState(synStreamFrame.isClose(),true); stream.updateCloseState(synStreamFrame.isClose(), true);
assertThat("stream is half closed",stream.isHalfClosed(),is(true)); assertThat("stream is half closed", stream.isHalfClosed(), is(true));
stream.data(new StringDataInfo("data on half closed stream",true)); stream.data(new StringDataInfo("data on half closed stream", true));
verify(session,never()).data(any(IStream.class),any(DataInfo.class),anyInt(),any(TimeUnit.class),any(Handler.class),any(void.class)); verify(session, never()).data(any(IStream.class), any(DataInfo.class), anyInt(), any(TimeUnit.class), any(Handler.class), any(void.class));
} }
} }

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.frames;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.KeyStore;
import java.security.cert.Certificate;
import org.eclipse.jetty.spdy.StandardByteBufferPool;
import org.eclipse.jetty.spdy.StandardCompressionFactory;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.generator.Generator;
import org.eclipse.jetty.spdy.parser.Parser;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.Assert;
import org.junit.Test;
public class CredentialGenerateParseTest
{
@Test
public void testGenerateParse() throws Exception
{
short slot = 1;
byte[] proof = new byte[]{0, 1, 2};
Certificate[] temp = loadCertificates();
Certificate[] certificates = new Certificate[temp.length * 2];
System.arraycopy(temp, 0, certificates, 0, temp.length);
System.arraycopy(temp, 0, certificates, temp.length, temp.length);
CredentialFrame frame1 = new CredentialFrame(SPDY.V3, slot, proof, certificates);
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor());
ByteBuffer buffer = generator.control(frame1);
Assert.assertNotNull(buffer);
TestSPDYParserListener listener = new TestSPDYParserListener();
Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
parser.addListener(listener);
parser.parse(buffer);
ControlFrame frame2 = listener.getControlFrame();
Assert.assertNotNull(frame2);
Assert.assertEquals(ControlFrameType.CREDENTIAL, frame2.getType());
CredentialFrame credential = (CredentialFrame)frame2;
Assert.assertEquals(SPDY.V3, credential.getVersion());
Assert.assertEquals(0, credential.getFlags());
Assert.assertEquals(slot, credential.getSlot());
Assert.assertArrayEquals(proof, credential.getProof());
Assert.assertArrayEquals(certificates, credential.getCertificateChain());
}
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
short slot = 1;
byte[] proof = new byte[]{0, 1, 2};
Certificate[] certificates = loadCertificates();
CredentialFrame frame1 = new CredentialFrame(SPDY.V3, slot, proof, certificates);
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor());
ByteBuffer buffer = generator.control(frame1);
Assert.assertNotNull(buffer);
TestSPDYParserListener listener = new TestSPDYParserListener();
Parser parser = new Parser(new StandardCompressionFactory().newDecompressor());
parser.addListener(listener);
while (buffer.hasRemaining())
parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
ControlFrame frame2 = listener.getControlFrame();
Assert.assertNotNull(frame2);
Assert.assertEquals(ControlFrameType.CREDENTIAL, frame2.getType());
CredentialFrame credential = (CredentialFrame)frame2;
Assert.assertEquals(SPDY.V3, credential.getVersion());
Assert.assertEquals(0, credential.getFlags());
Assert.assertEquals(slot, credential.getSlot());
Assert.assertArrayEquals(proof, credential.getProof());
Assert.assertArrayEquals(certificates, credential.getCertificateChain());
}
private Certificate[] loadCertificates() throws Exception
{
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyStoreStream = Resource.newResource("src/test/resources/keystore.jks").getInputStream();
keyStore.load(keyStoreStream, "storepwd".toCharArray());
return keyStore.getCertificateChain("mykey");
}
}

View File

@ -37,10 +37,11 @@ public class SynStreamGenerateParseTest
int streamId = 13; int streamId = 13;
int associatedStreamId = 11; int associatedStreamId = 11;
byte priority = 3; byte priority = 3;
short slot = 5;
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("a", "b"); headers.put("a", "b");
headers.put("c", "d"); headers.put("c", "d");
SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, headers); SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, slot, headers);
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor()); Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor());
ByteBuffer buffer = generator.control(frame1); ByteBuffer buffer = generator.control(frame1);
@ -60,6 +61,7 @@ public class SynStreamGenerateParseTest
Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId()); Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId());
Assert.assertEquals(flags, synStream.getFlags()); Assert.assertEquals(flags, synStream.getFlags());
Assert.assertEquals(priority, synStream.getPriority()); Assert.assertEquals(priority, synStream.getPriority());
Assert.assertEquals(slot, synStream.getSlot());
Assert.assertEquals(headers, synStream.getHeaders()); Assert.assertEquals(headers, synStream.getHeaders());
} }
@ -70,10 +72,11 @@ public class SynStreamGenerateParseTest
int streamId = 13; int streamId = 13;
int associatedStreamId = 11; int associatedStreamId = 11;
byte priority = 3; byte priority = 3;
short slot = 5;
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("a", "b"); headers.put("a", "b");
headers.put("c", "d"); headers.put("c", "d");
SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, headers); SynStreamFrame frame1 = new SynStreamFrame(SPDY.V2, flags, streamId, associatedStreamId, priority, slot, headers);
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor()); Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory().newCompressor());
ByteBuffer buffer = generator.control(frame1); ByteBuffer buffer = generator.control(frame1);
@ -94,6 +97,7 @@ public class SynStreamGenerateParseTest
Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId()); Assert.assertEquals(associatedStreamId, synStream.getAssociatedStreamId());
Assert.assertEquals(flags, synStream.getFlags()); Assert.assertEquals(flags, synStream.getFlags());
Assert.assertEquals(priority, synStream.getPriority()); Assert.assertEquals(priority, synStream.getPriority());
Assert.assertEquals(slot, synStream.getSlot());
Assert.assertEquals(headers, synStream.getHeaders()); Assert.assertEquals(headers, synStream.getHeaders());
} }
} }

View File

@ -23,7 +23,7 @@ public class UnknownControlFrameTest
@Test @Test
public void testUnknownControlFrame() throws Exception public void testUnknownControlFrame() throws Exception
{ {
SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, new Headers()); SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, new Headers());
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor()); Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
ByteBuffer buffer = generator.control(frame); ByteBuffer buffer = generator.control(frame);
// Change the frame type to unknown // Change the frame type to unknown

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.http;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.spdy.api.SPDY;
public enum HTTPSPDYHeader
{
METHOD("method", ":method"),
URI("url", ":path"),
VERSION("version", ":version"),
SCHEME("scheme", ":scheme"),
HOST("host", ":host"),
STATUS("status", ":status");
public static HTTPSPDYHeader from(short version, String name)
{
switch (version)
{
case SPDY.V2:
return Names.v2Names.get(name);
case SPDY.V3:
return Names.v3Names.get(name);
default:
throw new IllegalStateException();
}
}
private final String v2Name;
private final String v3Name;
private HTTPSPDYHeader(String v2Name, String v3Name)
{
this.v2Name = v2Name;
Names.v2Names.put(v2Name, this);
this.v3Name = v3Name;
Names.v3Names.put(v3Name, this);
}
public String name(short version)
{
switch (version)
{
case SPDY.V2:
return v2Name;
case SPDY.V3:
return v3Name;
default:
throw new IllegalStateException();
}
}
private static class Names
{
private static final Map<String, HTTPSPDYHeader> v2Names = new HashMap<>();
private static final Map<String, HTTPSPDYHeader> v3Names = new HashMap<>();
}
}

View File

@ -66,6 +66,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
private final Queue<Runnable> tasks = new LinkedList<>(); private final Queue<Runnable> tasks = new LinkedList<>();
private final BlockingQueue<DataInfo> dataInfos = new LinkedBlockingQueue<>(); private final BlockingQueue<DataInfo> dataInfos = new LinkedBlockingQueue<>();
private final short version;
private final SPDYAsyncConnection connection; private final SPDYAsyncConnection connection;
private final PushStrategy pushStrategy; private final PushStrategy pushStrategy;
private final Stream stream; private final Stream stream;
@ -75,9 +76,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
private volatile State state = State.INITIAL; private volatile State state = State.INITIAL;
private boolean dispatched; // Guarded by synchronization on tasks private boolean dispatched; // Guarded by synchronization on tasks
public ServerHTTPSPDYAsyncConnection(Connector connector, AsyncEndPoint endPoint, Server server, SPDYAsyncConnection connection, PushStrategy pushStrategy, Stream stream) public ServerHTTPSPDYAsyncConnection(Connector connector, AsyncEndPoint endPoint, Server server, short version, SPDYAsyncConnection connection, PushStrategy pushStrategy, Stream stream)
{ {
super(connector, endPoint, server); super(connector, endPoint, server);
this.version = version;
this.connection = connection; this.connection = connection;
this.pushStrategy = pushStrategy; this.pushStrategy = pushStrategy;
this.stream = stream; this.stream = stream;
@ -159,9 +161,9 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
} }
case REQUEST: case REQUEST:
{ {
Headers.Header method = headers.get("method"); Headers.Header method = headers.get(HTTPSPDYHeader.METHOD.name(version));
Headers.Header uri = headers.get("url"); Headers.Header uri = headers.get(HTTPSPDYHeader.URI.name(version));
Headers.Header version = headers.get("version"); Headers.Header version = headers.get(HTTPSPDYHeader.VERSION.name(this.version));
if (method == null || uri == null || version == null) if (method == null || uri == null || version == null)
throw new HttpException(HttpStatus.BAD_REQUEST_400); throw new HttpException(HttpStatus.BAD_REQUEST_400);
@ -181,15 +183,19 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
for (Headers.Header header : headers) for (Headers.Header header : headers)
{ {
String name = header.name(); String name = header.name();
// Skip special SPDY headers, unless it's the "host" header
HTTPSPDYHeader specialHeader = HTTPSPDYHeader.from(version, name);
if (specialHeader != null)
{
if (specialHeader == HTTPSPDYHeader.HOST)
name = "host";
else
continue;
}
switch (name) switch (name)
{ {
case "method":
case "version":
case "url":
{
// Skip request line headers
continue;
}
case "connection": case "connection":
case "keep-alive": case "keep-alive":
case "proxy-connection": case "proxy-connection":
@ -264,8 +270,8 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
else else
{ {
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("status", String.valueOf(status)); headers.put(HTTPSPDYHeader.STATUS.name(version), String.valueOf(status));
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
stream.reply(new ReplyInfo(headers, true)); stream.reply(new ReplyInfo(headers, true));
} }
} }
@ -393,21 +399,22 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
{ {
if (!stream.isUnidirectional()) if (!stream.isUnidirectional())
stream.reply(replyInfo); stream.reply(replyInfo);
if (replyInfo.getHeaders().get("status").value().startsWith("200") && !stream.isClosed() && !isIfModifiedSinceHeaderPresent()) if (replyInfo.getHeaders().get(HTTPSPDYHeader.STATUS.name(version)).value().startsWith("200") &&
!stream.isClosed() && !isIfModifiedSinceHeaderPresent())
{ {
// We have a 200 OK with some content to send // We have a 200 OK with some content to send
Headers.Header scheme = headers.get("scheme"); Headers.Header scheme = headers.get(HTTPSPDYHeader.SCHEME.name(version));
Headers.Header host = headers.get("host"); Headers.Header host = headers.get(HTTPSPDYHeader.HOST.name(version));
Headers.Header url = headers.get("url"); Headers.Header uri = headers.get(HTTPSPDYHeader.URI.name(version));
Set<String> pushResources = pushStrategy.apply(stream, this.headers, replyInfo.getHeaders()); Set<String> pushResources = pushStrategy.apply(stream, headers, replyInfo.getHeaders());
String referrer = new StringBuilder(scheme.value()).append("://").append(host.value()).append(url.value()).toString(); String referrer = new StringBuilder(scheme.value()).append("://").append(host.value()).append(uri.value()).toString();
for (String pushURL : pushResources) for (String pushURL : pushResources)
{ {
final Headers pushHeaders = new Headers(); final Headers pushHeaders = new Headers();
pushHeaders.put("method", "GET"); pushHeaders.put(HTTPSPDYHeader.METHOD.name(version), "GET");
pushHeaders.put("url", pushURL); pushHeaders.put(HTTPSPDYHeader.URI.name(version), pushURL);
pushHeaders.put("version", "HTTP/1.1"); pushHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
pushHeaders.put(scheme); pushHeaders.put(scheme);
pushHeaders.put(host); pushHeaders.put(host);
pushHeaders.put("referer", referrer); pushHeaders.put("referer", referrer);
@ -418,7 +425,7 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
@Override @Override
public void completed(Stream pushStream) public void completed(Stream pushStream)
{ {
Synchronous pushConnection = new Synchronous(getConnector(), getEndPoint(), getServer(), connection, pushStrategy, pushStream); Synchronous pushConnection = new Synchronous(getConnector(), getEndPoint(), getServer(), version, connection, pushStrategy, pushStream);
pushConnection.beginRequest(pushHeaders, true); pushConnection.beginRequest(pushHeaders, true);
} }
}); });
@ -427,12 +434,10 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
} }
private boolean isIfModifiedSinceHeaderPresent() private boolean isIfModifiedSinceHeaderPresent()
{ {
if (headers.get("if-modified-since") != null) return headers.get("if-modified-since") != null;
return true; }
return false;
}
private Buffer consumeContent(long maxIdleTime) throws IOException, InterruptedException private Buffer consumeContent(long maxIdleTime) throws IOException, InterruptedException
{ {
while (true) while (true)
@ -614,11 +619,11 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
{ {
Headers headers = new Headers(); Headers headers = new Headers();
String version = "HTTP/1.1"; String version = "HTTP/1.1";
headers.put("version", version); headers.put(HTTPSPDYHeader.VERSION.name(ServerHTTPSPDYAsyncConnection.this.version), version);
StringBuilder status = new StringBuilder().append(_status); StringBuilder status = new StringBuilder().append(_status);
if (_reason != null) if (_reason != null)
status.append(" ").append(_reason.toString("UTF-8")); status.append(" ").append(_reason.toString("UTF-8"));
headers.put("status", status.toString()); headers.put(HTTPSPDYHeader.STATUS.name(ServerHTTPSPDYAsyncConnection.this.version), status.toString());
logger.debug("HTTP < {} {}", version, status); logger.debug("HTTP < {} {}", version, status);
if (fields != null) if (fields != null)
@ -747,9 +752,9 @@ public class ServerHTTPSPDYAsyncConnection extends AbstractHttpConnection implem
private static class Synchronous extends ServerHTTPSPDYAsyncConnection private static class Synchronous extends ServerHTTPSPDYAsyncConnection
{ {
private Synchronous(Connector connector, AsyncEndPoint endPoint, Server server, SPDYAsyncConnection connection, PushStrategy pushStrategy, Stream stream) private Synchronous(Connector connector, AsyncEndPoint endPoint, Server server, short version, SPDYAsyncConnection connection, PushStrategy pushStrategy, Stream stream)
{ {
super(connector, endPoint, server, connection, pushStrategy, stream); super(connector, endPoint, server, version, connection, pushStrategy, stream);
} }
@Override @Override

View File

@ -78,8 +78,8 @@ public class ServerHTTPSPDYAsyncConnectionFactory extends ServerSPDYAsyncConnect
logger.debug("Received {} on {}", synInfo, stream); logger.debug("Received {} on {}", synInfo, stream);
HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(endPoint, stream); HTTPSPDYAsyncEndPoint asyncEndPoint = new HTTPSPDYAsyncEndPoint(endPoint, stream);
ServerHTTPSPDYAsyncConnection connection = new ServerHTTPSPDYAsyncConnection(connector, ServerHTTPSPDYAsyncConnection connection = new ServerHTTPSPDYAsyncConnection(connector, asyncEndPoint,
asyncEndPoint, connector.getServer(), (SPDYAsyncConnection)endPoint.getConnection(), connector.getServer(), getVersion(), (SPDYAsyncConnection)endPoint.getConnection(),
pushStrategy, stream); pushStrategy, stream);
asyncEndPoint.setConnection(connection); asyncEndPoint.setConnection(connection);
stream.setAttribute(CONNECTION_ATTRIBUTE, connection); stream.setAttribute(CONNECTION_ATTRIBUTE, connection);

View File

@ -54,9 +54,14 @@ public abstract class AbstractHTTPSPDYTest
protected SPDYServerConnector connector; protected SPDYServerConnector connector;
protected InetSocketAddress startHTTPServer(Handler handler) throws Exception protected InetSocketAddress startHTTPServer(Handler handler) throws Exception
{
return startHTTPServer(SPDY.V2, handler);
}
protected InetSocketAddress startHTTPServer(short version, Handler handler) throws Exception
{ {
server = new Server(); server = new Server();
connector = newHTTPSPDYServerConnector(); connector = newHTTPSPDYServerConnector(version);
connector.setPort(0); connector.setPort(0);
server.addConnector(connector); server.addConnector(connector);
server.setHandler(handler); server.setHandler(handler);
@ -64,16 +69,21 @@ public abstract class AbstractHTTPSPDYTest
return new InetSocketAddress("localhost", connector.getLocalPort()); return new InetSocketAddress("localhost", connector.getLocalPort());
} }
protected SPDYServerConnector newHTTPSPDYServerConnector() protected SPDYServerConnector newHTTPSPDYServerConnector(short version)
{ {
// For these tests, we need the connector to speak HTTP over SPDY even in non-SSL // For these tests, we need the connector to speak HTTP over SPDY even in non-SSL
SPDYServerConnector connector = new HTTPSPDYServerConnector(); SPDYServerConnector connector = new HTTPSPDYServerConnector();
AsyncConnectionFactory defaultFactory = new ServerHTTPSPDYAsyncConnectionFactory(SPDY.V2, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), connector, new PushStrategy.None()); AsyncConnectionFactory defaultFactory = new ServerHTTPSPDYAsyncConnectionFactory(version, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), connector, new PushStrategy.None());
connector.setDefaultAsyncConnectionFactory(defaultFactory); connector.setDefaultAsyncConnectionFactory(defaultFactory);
return connector; return connector;
} }
protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
{
return startClient(SPDY.V2, socketAddress, listener);
}
protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
{ {
if (clientFactory == null) if (clientFactory == null)
{ {
@ -82,7 +92,7 @@ public abstract class AbstractHTTPSPDYTest
clientFactory = newSPDYClientFactory(threadPool); clientFactory = newSPDYClientFactory(threadPool);
clientFactory.start(); clientFactory.start();
} }
return clientFactory.newSPDYClient(SPDY.V2).connect(socketAddress, listener).get(5, TimeUnit.SECONDS); return clientFactory.newSPDYClient(version).connect(socketAddress, listener).get(5, TimeUnit.SECONDS);
} }
protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool) protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)

View File

@ -16,7 +16,6 @@ import org.eclipse.jetty.spdy.SPDYServerConnector;
import org.eclipse.jetty.spdy.api.DataInfo; import org.eclipse.jetty.spdy.api.DataInfo;
import org.eclipse.jetty.spdy.api.Headers; import org.eclipse.jetty.spdy.api.Headers;
import org.eclipse.jetty.spdy.api.ReplyInfo; import org.eclipse.jetty.spdy.api.ReplyInfo;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.SessionFrameListener; import org.eclipse.jetty.spdy.api.SessionFrameListener;
import org.eclipse.jetty.spdy.api.Stream; import org.eclipse.jetty.spdy.api.Stream;
@ -28,10 +27,10 @@ import org.junit.Test;
public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest public class ReferrerPushStrategyTest extends AbstractHTTPSPDYTest
{ {
@Override @Override
protected SPDYServerConnector newHTTPSPDYServerConnector() protected SPDYServerConnector newHTTPSPDYServerConnector(short version)
{ {
SPDYServerConnector connector = super.newHTTPSPDYServerConnector(); SPDYServerConnector connector = super.newHTTPSPDYServerConnector(version);
AsyncConnectionFactory defaultFactory = new ServerHTTPSPDYAsyncConnectionFactory(SPDY.V2, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), connector, new ReferrerPushStrategy()); AsyncConnectionFactory defaultFactory = new ServerHTTPSPDYAsyncConnectionFactory(version, connector.getByteBufferPool(), connector.getExecutor(), connector.getScheduler(), connector, new ReferrerPushStrategy());
connector.setDefaultAsyncConnectionFactory(defaultFactory); connector.setDefaultAsyncConnectionFactory(defaultFactory);
return connector; return connector;
} }

View File

@ -40,6 +40,7 @@ import org.eclipse.jetty.spdy.api.BytesDataInfo;
import org.eclipse.jetty.spdy.api.DataInfo; import org.eclipse.jetty.spdy.api.DataInfo;
import org.eclipse.jetty.spdy.api.Headers; import org.eclipse.jetty.spdy.api.Headers;
import org.eclipse.jetty.spdy.api.ReplyInfo; import org.eclipse.jetty.spdy.api.ReplyInfo;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session; import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.Stream; import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.api.StreamFrameListener; import org.eclipse.jetty.spdy.api.StreamFrameListener;
@ -48,14 +49,19 @@ import org.eclipse.jetty.spdy.api.SynInfo;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest public class ServerHTTPSPDYv2Test extends AbstractHTTPSPDYTest
{ {
protected short version()
{
return SPDY.V2;
}
@Test @Test
public void testSimpleGET() throws Exception public void testSimpleGET() throws Exception
{ {
final String path = "/foo"; final String path = "/foo";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -71,11 +77,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", path); headers.put(HTTPSPDYHeader.URI.name(version()), path);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
{ {
@ -84,7 +90,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}); });
@ -99,7 +105,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String query = "p=1"; final String query = "p=1";
final String uri = path + "?" + query; final String uri = path + "?" + query;
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -115,11 +121,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", uri); headers.put(HTTPSPDYHeader.URI.name(version()), uri);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
{ {
@ -128,7 +134,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}); });
@ -141,7 +147,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final String path = "/foo"; final String path = "/foo";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -156,11 +162,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "HEAD"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "HEAD");
headers.put("url", path); headers.put(HTTPSPDYHeader.URI.name(version()), path);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
{ {
@ -169,7 +175,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}); });
@ -183,7 +189,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String path = "/foo"; final String path = "/foo";
final String data = "a=1&b=2"; final String data = "a=1&b=2";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -206,11 +212,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", path); headers.put(HTTPSPDYHeader.URI.name(version()), path);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
headers.put("content-type", "application/x-www-form-urlencoded"); headers.put("content-type", "application/x-www-form-urlencoded");
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
@ -220,7 +226,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}).get(5, TimeUnit.SECONDS); }).get(5, TimeUnit.SECONDS);
@ -237,7 +243,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String data1 = "a=1&"; final String data1 = "a=1&";
final String data2 = "b=2"; final String data2 = "b=2";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -252,11 +258,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", path); headers.put(HTTPSPDYHeader.URI.name(version()), path);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
headers.put("content-type", "application/x-www-form-urlencoded"); headers.put("content-type", "application/x-www-form-urlencoded");
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
@ -266,7 +272,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}).get(5, TimeUnit.SECONDS); }).get(5, TimeUnit.SECONDS);
@ -286,7 +292,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String data1 = "a=1&"; final String data1 = "a=1&";
final String data2 = "b=2"; final String data2 = "b=2";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -301,11 +307,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", path); headers.put(HTTPSPDYHeader.URI.name(version()), path);
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
headers.put("content-type", "application/x-www-form-urlencoded"); headers.put("content-type", "application/x-www-form-urlencoded");
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
@ -315,7 +321,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.toString(), replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.toString(), replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}).get(5, TimeUnit.SECONDS); }).get(5, TimeUnit.SECONDS);
@ -332,7 +338,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final String data = "0123456789ABCDEF"; final String data = "0123456789ABCDEF";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -347,11 +353,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -361,7 +367,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -383,7 +389,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final char data = 'x'; final char data = 'x';
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -398,11 +404,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -412,7 +418,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -437,7 +443,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String data1 = "0123456789ABCDEF"; final String data1 = "0123456789ABCDEF";
final String data2 = "FEDCBA9876543210"; final String data2 = "FEDCBA9876543210";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -454,11 +460,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(2); final CountDownLatch dataLatch = new CountDownLatch(2);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -472,7 +478,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replyFrames.incrementAndGet()); Assert.assertEquals(1, replyFrames.incrementAndGet());
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -499,7 +505,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final byte[] data = new byte[128 * 1024]; final byte[] data = new byte[128 * 1024];
Arrays.fill(data, (byte)'x'); Arrays.fill(data, (byte)'x');
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -514,11 +520,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -530,7 +536,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -556,7 +562,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final byte[] data = new byte[128 * 1024]; final byte[] data = new byte[128 * 1024];
Arrays.fill(data, (byte)'y'); Arrays.fill(data, (byte)'y');
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -572,11 +578,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -588,7 +594,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -613,7 +619,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final String data = "0123456789ABCDEF"; final String data = "0123456789ABCDEF";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -630,11 +636,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -646,7 +652,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -674,7 +680,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String data1 = "0123456789ABCDEF"; final String data1 = "0123456789ABCDEF";
final String data2 = "FEDCBA9876543210"; final String data2 = "FEDCBA9876543210";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -693,11 +699,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -709,7 +715,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -736,7 +742,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final String suffix = "/redirect"; final String suffix = "/redirect";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -751,11 +757,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
{ {
@ -767,7 +773,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replies.incrementAndGet()); Assert.assertEquals(1, replies.incrementAndGet());
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("302")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("302"));
Assert.assertTrue(replyHeaders.get("location").value().endsWith(suffix)); Assert.assertTrue(replyHeaders.get("location").value().endsWith(suffix));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -780,7 +786,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
public void testGETWithSendError() throws Exception public void testGETWithSendError() throws Exception
{ {
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -793,11 +799,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -810,7 +816,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replies.incrementAndGet()); Assert.assertEquals(1, replies.incrementAndGet());
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("404")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("404"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -829,7 +835,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
@Test @Test
public void testGETWithException() throws Exception public void testGETWithException() throws Exception
{ {
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -840,11 +846,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
{ {
@ -856,7 +862,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replies.incrementAndGet()); Assert.assertEquals(1, replies.incrementAndGet());
Assert.assertTrue(replyInfo.isClose()); Assert.assertTrue(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("500")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("500"));
replyLatch.countDown(); replyLatch.countDown();
} }
}); });
@ -869,7 +875,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
final String pangram1 = "the quick brown fox jumps over the lazy dog"; final String pangram1 = "the quick brown fox jumps over the lazy dog";
final String pangram2 = "qualche vago ione tipo zolfo, bromo, sodio"; final String pangram2 = "qualche vago ione tipo zolfo, bromo, sodio";
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -887,11 +893,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(2); final CountDownLatch dataLatch = new CountDownLatch(2);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -905,7 +911,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replyFrames.incrementAndGet()); Assert.assertEquals(1, replyFrames.incrementAndGet());
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
Assert.assertTrue(replyHeaders.get("extra").value().contains("X")); Assert.assertTrue(replyHeaders.get("extra").value().contains("X"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -937,7 +943,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final byte[] data = new byte[2048]; final byte[] data = new byte[2048];
final CountDownLatch handlerLatch = new CountDownLatch(1); final CountDownLatch handlerLatch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -953,11 +959,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "GET"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "GET");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
final CountDownLatch dataLatch = new CountDownLatch(1); final CountDownLatch dataLatch = new CountDownLatch(1);
session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter() session.syn(new SynInfo(headers, true), new StreamFrameListener.Adapter()
@ -971,7 +977,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
Assert.assertEquals(1, replyFrames.incrementAndGet()); Assert.assertEquals(1, replyFrames.incrementAndGet());
Assert.assertFalse(replyInfo.isClose()); Assert.assertFalse(replyInfo.isClose());
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
@ -994,7 +1000,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final byte[] data = new byte[2000]; final byte[] data = new byte[2000];
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -1030,11 +1036,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
{ {
@ -1042,7 +1048,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
public void onReply(Stream stream, ReplyInfo replyInfo) public void onReply(Stream stream, ReplyInfo replyInfo)
{ {
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}).get(5, TimeUnit.SECONDS); }).get(5, TimeUnit.SECONDS);
@ -1057,7 +1063,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final byte[] data = new byte[2000]; final byte[] data = new byte[2000];
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -1093,11 +1099,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch replyLatch = new CountDownLatch(1); final CountDownLatch replyLatch = new CountDownLatch(1);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
{ {
@ -1105,7 +1111,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
public void onReply(Stream stream, ReplyInfo replyInfo) public void onReply(Stream stream, ReplyInfo replyInfo)
{ {
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
replyLatch.countDown(); replyLatch.countDown();
} }
}).get(5, TimeUnit.SECONDS); }).get(5, TimeUnit.SECONDS);
@ -1121,7 +1127,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
{ {
final byte[] data = new byte[1000]; final byte[] data = new byte[1000];
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
Session session = startClient(startHTTPServer(new AbstractHandler() Session session = startClient(version(), startHTTPServer(version(), new AbstractHandler()
{ {
@Override @Override
public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) public void handle(String target, final Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
@ -1166,11 +1172,11 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
}), null); }), null);
Headers headers = new Headers(); Headers headers = new Headers();
headers.put("method", "POST"); headers.put(HTTPSPDYHeader.METHOD.name(version()), "POST");
headers.put("url", "/foo"); headers.put(HTTPSPDYHeader.URI.name(version()), "/foo");
headers.put("version", "HTTP/1.1"); headers.put(HTTPSPDYHeader.VERSION.name(version()), "HTTP/1.1");
headers.put("scheme", "http"); headers.put(HTTPSPDYHeader.SCHEME.name(version()), "http");
headers.put("host", "localhost:" + connector.getLocalPort()); headers.put(HTTPSPDYHeader.HOST.name(version()), "localhost:" + connector.getLocalPort());
final CountDownLatch responseLatch = new CountDownLatch(2); final CountDownLatch responseLatch = new CountDownLatch(2);
Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter() Stream stream = session.syn(new SynInfo(headers, false), new StreamFrameListener.Adapter()
{ {
@ -1178,7 +1184,7 @@ public class ServerHTTPSPDYTest extends AbstractHTTPSPDYTest
public void onReply(Stream stream, ReplyInfo replyInfo) public void onReply(Stream stream, ReplyInfo replyInfo)
{ {
Headers replyHeaders = replyInfo.getHeaders(); Headers replyHeaders = replyInfo.getHeaders();
Assert.assertTrue(replyHeaders.get("status").value().contains("200")); Assert.assertTrue(replyHeaders.get(HTTPSPDYHeader.STATUS.name(version())).value().contains("200"));
responseLatch.countDown(); responseLatch.countDown();
} }

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2012 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 org.eclipse.jetty.spdy.http;
import org.eclipse.jetty.spdy.api.SPDY;
public class ServerHTTPSPDYv3Test extends ServerHTTPSPDYv2Test
{
@Override
protected short version()
{
return SPDY.V3;
}
}

View File

@ -50,6 +50,11 @@ public class ServerSPDYAsyncConnectionFactory implements AsyncConnectionFactory
this.listener = listener; this.listener = listener;
} }
public short getVersion()
{
return version;
}
@Override @Override
public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment) public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment)
{ {

View File

@ -213,7 +213,7 @@ public class ClosedStreamTest extends AbstractTest
final Generator generator = new Generator(new StandardByteBufferPool(),new StandardCompressionFactory().newCompressor()); final Generator generator = new Generator(new StandardByteBufferPool(),new StandardCompressionFactory().newCompressor());
int streamId = 1; int streamId = 1;
ByteBuffer synData = generator.control(new SynStreamFrame(version,SynInfo.FLAG_CLOSE, streamId,0,(byte)0,new Headers())); ByteBuffer synData = generator.control(new SynStreamFrame(version,SynInfo.FLAG_CLOSE, streamId,0,(byte)0,(short)0,new Headers()));
final SocketChannel socketChannel = SocketChannel.open(startServer); final SocketChannel socketChannel = SocketChannel.open(startServer);
socketChannel.write(synData); socketChannel.write(synData);
@ -261,7 +261,7 @@ public class ClosedStreamTest extends AbstractTest
Assert.assertThat(buffer.hasRemaining(), is(false)); Assert.assertThat(buffer.hasRemaining(), is(false));
assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5,TimeUnit.SECONDS), is(true)); assertThat("GoAway frame is received by server", goAwayReceivedLatch.await(5,TimeUnit.SECONDS), is(true));
socketChannel.close(); socketChannel.close();
} }
} }

View File

@ -414,7 +414,7 @@ public class PushStreamTest extends AbstractTest
final SocketChannel channel = SocketChannel.open(serverAddress); final SocketChannel channel = SocketChannel.open(serverAddress);
final Generator generator = new Generator(new StandardByteBufferPool(),new StandardCompressionFactory.StandardCompressor()); final Generator generator = new Generator(new StandardByteBufferPool(),new StandardCompressionFactory.StandardCompressor());
int streamId = 1; int streamId = 1;
ByteBuffer writeBuffer = generator.control(new SynStreamFrame(version,(byte)0,streamId,0,(byte)0,new Headers())); ByteBuffer writeBuffer = generator.control(new SynStreamFrame(version,(byte)0,streamId,0,(byte)0,(short)0,new Headers()));
channel.write(writeBuffer); channel.write(writeBuffer);
assertThat("writeBuffer is fully written",writeBuffer.hasRemaining(), is(false)); assertThat("writeBuffer is fully written",writeBuffer.hasRemaining(), is(false));

View File

@ -44,7 +44,7 @@ public class UnsupportedVersionTest extends AbstractTest
} }
}); });
SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, new Headers()); SynStreamFrame frame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, new Headers());
Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor()); Generator generator = new Generator(new StandardByteBufferPool(), new StandardCompressionFactory.StandardCompressor());
ByteBuffer buffer = generator.control(frame); ByteBuffer buffer = generator.control(frame);
// Replace the version byte with an unsupported version // Replace the version byte with an unsupported version