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