1 module hunt.http.codec.http.encode.Http2Generator; 2 3 import hunt.http.codec.http.frame.DataFrame; 4 import hunt.http.codec.http.frame.Frame; 5 import hunt.http.codec.http.frame.FrameType; 6 import hunt.http.codec.http.hpack.HpackEncoder; 7 8 import hunt.http.codec.http.encode.DataGenerator; 9 import hunt.http.codec.http.encode.DisconnectGenerator; 10 import hunt.http.codec.http.encode.FrameGenerator; 11 import hunt.http.codec.http.encode.HeaderGenerator; 12 import hunt.http.codec.http.encode.HeadersGenerator; 13 import hunt.http.codec.http.encode.GoAwayGenerator; 14 import hunt.http.codec.http.encode.PingGenerator; 15 import hunt.http.codec.http.encode.PriorityGenerator; 16 import hunt.http.codec.http.encode.PrefaceGenerator; 17 import hunt.http.codec.http.encode.PushPromiseGenerator; 18 import hunt.http.codec.http.encode.ResetGenerator; 19 import hunt.http.codec.http.encode.SettingsGenerator; 20 import hunt.http.codec.http.encode.WindowUpdateGenerator; 21 22 import hunt.io.ByteBuffer; 23 import hunt.collection.List; 24 import hunt.logging; 25 26 import std.typecons; 27 28 /** 29 */ 30 class Http2Generator { 31 private HeaderGenerator headerGenerator; 32 private HpackEncoder hpackEncoder; 33 private FrameGenerator[FrameType] generators; 34 private DataGenerator dataGenerator; 35 36 this() { 37 this(4096, 0); 38 } 39 40 this(int maxDynamicTableSize, int maxHeaderBlockFragment) { 41 42 version (HUNT_DEBUG) trace("Initializing Http2Generator"); 43 44 headerGenerator = new HeaderGenerator(); 45 hpackEncoder = new HpackEncoder(maxDynamicTableSize); 46 47 // this.generators = new FrameGenerator[FrameType.values().length]; 48 this.generators[FrameType.HEADERS] = new HeadersGenerator(headerGenerator, hpackEncoder, maxHeaderBlockFragment); 49 this.generators[FrameType.PRIORITY] = new PriorityGenerator(headerGenerator); 50 this.generators[FrameType.RST_STREAM] = new ResetGenerator(headerGenerator); 51 this.generators[FrameType.SETTINGS] = new SettingsGenerator(headerGenerator); 52 this.generators[FrameType.PUSH_PROMISE] = new PushPromiseGenerator(headerGenerator, hpackEncoder); 53 this.generators[FrameType.PING] = new PingGenerator(headerGenerator); 54 this.generators[FrameType.GO_AWAY] = new GoAwayGenerator(headerGenerator); 55 this.generators[FrameType.WINDOW_UPDATE] = new WindowUpdateGenerator(headerGenerator); 56 this.generators[FrameType.CONTINUATION] = null; // Never generated explicitly. 57 this.generators[FrameType.PREFACE] = new PrefaceGenerator(); 58 this.generators[FrameType.DISCONNECT] = new DisconnectGenerator(); 59 60 this.dataGenerator = new DataGenerator(headerGenerator); 61 } 62 63 void setHeaderTableSize(int headerTableSize) { 64 hpackEncoder.setRemoteMaxDynamicTableSize(headerTableSize); 65 } 66 67 void setMaxFrameSize(int maxFrameSize) { 68 headerGenerator.setMaxFrameSize(maxFrameSize); 69 } 70 71 // 72 T getControlGenerator(T)(FrameType type) if(is(T : FrameGenerator)) { 73 return cast(T) this.generators[type]; 74 } 75 76 List!(ByteBuffer) control(Frame frame) { 77 return generators[frame.getType()].generate(frame); 78 } 79 80 /** 81 * Encode data frame to binary codes 82 * @param frame DataFrame 83 * @param maxLength The max length of DataFrame 84 * @return A pair of encoding result. The first field is frame length which contains header frame and data frame. 85 * The second field is binary codes. 86 */ 87 Tuple!(int, List!(ByteBuffer)) data(DataFrame frame, int maxLength) { 88 return dataGenerator.generate(frame, maxLength); 89 } 90 91 void setMaxHeaderListSize(int value) { 92 hpackEncoder.setMaxHeaderListSize(value); 93 } 94 }