1 module hunt.http.codec.http.encode.PushPromiseGenerator; 2 3 import hunt.collection; 4 5 import hunt.http.codec.http.frame.Flags; 6 import hunt.http.codec.http.frame.Frame; 7 import hunt.http.codec.http.frame.FrameType; 8 import hunt.http.codec.http.frame.PushPromiseFrame; 9 import hunt.http.codec.http.hpack.HpackEncoder; 10 import hunt.http.HttpMetaData; 11 12 import hunt.http.codec.http.encode.FrameGenerator; 13 import hunt.http.codec.http.encode.HeaderGenerator; 14 15 import hunt.Exceptions; 16 17 import std.conv; 18 19 /** 20 */ 21 class PushPromiseGenerator :FrameGenerator { 22 private HpackEncoder encoder; 23 24 this(HeaderGenerator headerGenerator, HpackEncoder encoder) { 25 super(headerGenerator); 26 this.encoder = encoder; 27 } 28 29 override 30 List!(ByteBuffer) generate(Frame frame) { 31 PushPromiseFrame pushPromiseFrame = cast(PushPromiseFrame) frame; 32 return generatePushPromise(pushPromiseFrame.getStreamId(), pushPromiseFrame.getPromisedStreamId(), 33 pushPromiseFrame.getMetaData()); 34 } 35 36 List!(ByteBuffer) generatePushPromise(int streamId, int promisedStreamId, HttpMetaData metaData) { 37 if (streamId < 0) 38 throw new IllegalArgumentException("Invalid stream id: " ~ streamId.to!string); 39 if (promisedStreamId < 0) 40 throw new IllegalArgumentException("Invalid promised stream id: " ~ promisedStreamId.to!string); 41 42 List!(ByteBuffer) list = new LinkedList!(ByteBuffer)(); 43 int maxFrameSize = getMaxFrameSize(); 44 // The promised streamId space. 45 int extraSpace = 4; 46 maxFrameSize -= extraSpace; 47 48 ByteBuffer hpacked = BufferUtils.allocate(maxFrameSize); 49 BufferUtils.clearToFill(hpacked); 50 encoder.encode(hpacked, metaData); 51 int hpackedLength = hpacked.position(); 52 BufferUtils.flipToFlush(hpacked, 0); 53 54 int length = hpackedLength + extraSpace; 55 int flags = Flags.END_HEADERS; 56 57 ByteBuffer header = generateHeader(FrameType.PUSH_PROMISE, length, flags, streamId); 58 header.put!int(promisedStreamId); 59 BufferUtils.flipToFlush(header, 0); 60 61 list.add(header); 62 list.add(hpacked); 63 return list; 64 } 65 }