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.io.ByteBufferPool;
24 import org.eclipse.jetty.spdy.SessionException;
25 import org.eclipse.jetty.spdy.api.SPDY;
26 import org.eclipse.jetty.spdy.api.SessionStatus;
27 import org.eclipse.jetty.spdy.frames.ControlFrame;
28 import org.eclipse.jetty.spdy.frames.HeadersFrame;
29 import org.eclipse.jetty.util.BufferUtil;
30
31 public class HeadersGenerator extends ControlFrameGenerator
32 {
33 private final HeadersBlockGenerator headersBlockGenerator;
34
35 public HeadersGenerator(ByteBufferPool bufferPool, HeadersBlockGenerator headersBlockGenerator)
36 {
37 super(bufferPool);
38 this.headersBlockGenerator = headersBlockGenerator;
39 }
40
41 @Override
42 public ByteBuffer generate(ControlFrame frame)
43 {
44 HeadersFrame headers = (HeadersFrame)frame;
45 short version = headers.getVersion();
46
47 ByteBuffer headersBuffer = headersBlockGenerator.generate(version, headers.getHeaders());
48
49 int frameBodyLength = 4;
50 if (frame.getVersion() == SPDY.V2)
51 frameBodyLength += 2;
52
53 int frameLength = frameBodyLength + headersBuffer.remaining();
54 if (frameLength > 0xFF_FF_FF)
55 {
56
57
58 throw new SessionException(SessionStatus.PROTOCOL_ERROR, "Too many headers");
59 }
60
61 int totalLength = ControlFrame.HEADER_LENGTH + frameLength;
62
63 ByteBuffer buffer = getByteBufferPool().acquire(totalLength, Generator.useDirectBuffers);
64 BufferUtil.clearToFill(buffer);
65 generateControlFrameHeader(headers, frameLength, buffer);
66
67 buffer.putInt(headers.getStreamId() & 0x7F_FF_FF_FF);
68 if (frame.getVersion() == SPDY.V2)
69 buffer.putShort((short)0);
70
71 buffer.put(headersBuffer);
72
73 buffer.flip();
74 return buffer;
75 }
76 }