1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.spdy;
17
18 import org.jboss.netty.buffer.ChannelBuffer;
19 import org.jboss.netty.buffer.ChannelBuffers;
20
21 import java.nio.ByteOrder;
22 import java.util.Set;
23
24 import static org.jboss.netty.handler.codec.spdy.SpdyCodecUtil.*;
25
26 public class SpdyHeaderBlockRawEncoder extends SpdyHeaderBlockEncoder {
27
28 private final int version;
29
30 public SpdyHeaderBlockRawEncoder(SpdyVersion spdyVersion) {
31 if (spdyVersion == null) {
32 throw new NullPointerException("spdyVersion");
33 }
34 version = spdyVersion.getVersion();
35 }
36
37 private static void setLengthField(ChannelBuffer buffer, int writerIndex, int length) {
38 buffer.setInt(writerIndex, length);
39 }
40
41 private static void writeLengthField(ChannelBuffer buffer, int length) {
42 buffer.writeInt(length);
43 }
44
45 @Override
46 public ChannelBuffer encode(SpdyHeadersFrame headerFrame) throws Exception {
47 Set<String> names = headerFrame.headers().names();
48 int numHeaders = names.size();
49 if (numHeaders == 0) {
50 return ChannelBuffers.EMPTY_BUFFER;
51 }
52 if (numHeaders > SPDY_MAX_NV_LENGTH) {
53 throw new IllegalArgumentException(
54 "header block contains too many headers");
55 }
56 ChannelBuffer headerBlock = ChannelBuffers.dynamicBuffer(
57 ByteOrder.BIG_ENDIAN, 256);
58 writeLengthField(headerBlock, numHeaders);
59 for (String name: names) {
60 byte[] nameBytes = name.getBytes("UTF-8");
61 writeLengthField(headerBlock, nameBytes.length);
62 headerBlock.writeBytes(nameBytes);
63 int savedIndex = headerBlock.writerIndex();
64 int valueLength = 0;
65 writeLengthField(headerBlock, valueLength);
66 for (String value: headerFrame.headers().getAll(name)) {
67 byte[] valueBytes = value.getBytes("UTF-8");
68 if (valueBytes.length > 0) {
69 headerBlock.writeBytes(valueBytes);
70 headerBlock.writeByte(0);
71 valueLength += valueBytes.length + 1;
72 }
73 }
74 if (valueLength != 0) {
75 valueLength --;
76 }
77 if (valueLength > SPDY_MAX_NV_LENGTH) {
78 throw new IllegalArgumentException(
79 "header exceeds allowable length: " + name);
80 }
81 if (valueLength > 0) {
82 setLengthField(headerBlock, savedIndex, valueLength);
83 headerBlock.writerIndex(headerBlock.writerIndex() - 1);
84 }
85 }
86 return headerBlock;
87 }
88
89 @Override
90 void end() {
91 }
92 }