1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.eclipse.jetty.spdy.generator;
18
19 import java.nio.ByteBuffer;
20
21 import org.eclipse.jetty.spdy.ByteBufferPool;
22 import org.eclipse.jetty.spdy.SessionException;
23 import org.eclipse.jetty.spdy.StreamException;
24 import org.eclipse.jetty.spdy.api.SPDY;
25 import org.eclipse.jetty.spdy.api.SessionStatus;
26 import org.eclipse.jetty.spdy.api.StreamStatus;
27 import org.eclipse.jetty.spdy.frames.ControlFrame;
28 import org.eclipse.jetty.spdy.frames.SynStreamFrame;
29
30 public class SynStreamGenerator extends ControlFrameGenerator
31 {
32 private final HeadersBlockGenerator headersBlockGenerator;
33
34 public SynStreamGenerator(ByteBufferPool bufferPool, HeadersBlockGenerator headersBlockGenerator)
35 {
36 super(bufferPool);
37 this.headersBlockGenerator = headersBlockGenerator;
38 }
39
40 @Override
41 public ByteBuffer generate(ControlFrame frame)
42 {
43 SynStreamFrame synStream = (SynStreamFrame)frame;
44 short version = synStream.getVersion();
45
46 ByteBuffer headersBuffer = headersBlockGenerator.generate(version, synStream.getHeaders());
47
48 int frameBodyLength = 10;
49
50 int frameLength = frameBodyLength + headersBuffer.remaining();
51 if (frameLength > 0xFF_FF_FF)
52 {
53
54
55 throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
56 }
57
58 int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
59
60 ByteBuffer buffer = getByteBufferPool().acquire(totalLength, true);
61 generateControlFrameHeader(synStream, frameLength, buffer);
62
63 int streamId = synStream.getStreamId();
64 buffer.putInt(streamId & 0x7F_FF_FF_FF);
65 buffer.putInt(synStream.getAssociatedStreamId() & 0x7F_FF_FF_FF);
66 writePriority(streamId, version, synStream.getPriority(), buffer);
67
68 buffer.put(headersBuffer);
69
70 buffer.flip();
71 return buffer;
72 }
73
74 private void writePriority(int streamId, short version, byte priority, ByteBuffer buffer)
75 {
76 switch (version)
77 {
78 case SPDY.V2:
79 priority <<= 6;
80 break;
81 case SPDY.V3:
82 priority <<= 5;
83 break;
84 default:
85 throw new StreamException(streamId, StreamStatus.UNSUPPORTED_VERSION);
86 }
87 buffer.put(priority);
88 buffer.put((byte)0);
89 }
90 }