1 module hunt.http.codec.http.encode.PriorityGenerator; 2 3 import hunt.http.codec.http.frame.Flags; 4 import hunt.http.codec.http.frame.Frame; 5 import hunt.http.codec.http.frame.FrameType; 6 import hunt.http.codec.http.frame.PriorityFrame; 7 8 import hunt.http.codec.http.encode.FrameGenerator; 9 import hunt.http.codec.http.encode.HeaderGenerator; 10 11 import hunt.collection; 12 import hunt.Exceptions; 13 14 import std.conv; 15 16 17 /** 18 */ 19 class PriorityGenerator :FrameGenerator { 20 this(HeaderGenerator headerGenerator) { 21 super(headerGenerator); 22 } 23 24 override 25 List!(ByteBuffer) generate(Frame frame) { 26 PriorityFrame priorityFrame = cast(PriorityFrame) frame; 27 return Collections.singletonList(generatePriority( 28 priorityFrame.getStreamId(), 29 priorityFrame.getParentStreamId(), 30 priorityFrame.getWeight(), 31 priorityFrame.isExclusive())); 32 } 33 34 ByteBuffer generatePriority(int streamId, int parentStreamId, int weight, bool exclusive) { 35 ByteBuffer header = generateHeader(FrameType.PRIORITY, PriorityFrame.PRIORITY_LENGTH, Flags.NONE, streamId); 36 generatePriorityBody(header, streamId, parentStreamId, weight, exclusive); 37 BufferUtils.flipToFlush(header, 0); 38 return header; 39 } 40 41 void generatePriorityBody(ByteBuffer header, int streamId, int parentStreamId, int weight, 42 bool exclusive) { 43 if (streamId < 0) 44 throw new IllegalArgumentException("Invalid stream id: " ~ streamId.to!string()); 45 if (parentStreamId < 0) 46 throw new IllegalArgumentException("Invalid parent stream id: " ~ parentStreamId.to!string()); 47 if (parentStreamId == streamId) 48 throw new IllegalArgumentException("Stream " ~ streamId.to!string() ~ " cannot depend on stream " ~ parentStreamId.to!string()); 49 if (weight < 1 || weight > 256) 50 throw new IllegalArgumentException("Invalid weight: " ~ weight.to!string()); 51 52 if (exclusive) 53 parentStreamId |= 0x80_00_00_00; 54 header.put!int(parentStreamId); 55 header.put(cast(byte) (weight - 1)); 56 } 57 }