1 module hunt.http.codec.http.decode.PrefaceParser; 2 3 4 import hunt.http.codec.http.decode.Parser; 5 import hunt.http.codec.http.frame.ErrorCode; 6 import hunt.http.codec.http.frame.PrefaceFrame; 7 8 import hunt.io.BufferUtils; 9 import hunt.logging; 10 11 import hunt.Exceptions; 12 import hunt.io.ByteBuffer; 13 14 /** 15 */ 16 class PrefaceParser { 17 18 19 private Parser.Listener listener; 20 private int cursor; 21 22 this(Parser.Listener listener) { 23 this.listener = listener; 24 } 25 26 /** 27 * <p> 28 * Advances this parser after the 29 * {@link PrefaceFrame#PREFACE_PREAMBLE_BYTES}. 30 * </p> 31 * <p> 32 * This allows the HTTP/1.1 parser to parse the preamble of the preface, 33 * which is a legal HTTP/1.1 request, and this parser will parse the 34 * remaining bytes, that are not parseable by a HTTP/1.1 parser. 35 * </p> 36 */ 37 package void directUpgrade() { 38 if (cursor != 0) 39 throw new IllegalStateException(""); 40 cursor = PrefaceFrame.PREFACE_PREAMBLE_BYTES.length; 41 } 42 43 bool parse(ByteBuffer buffer) { 44 while (buffer.hasRemaining()) { 45 int currByte = buffer.get(); 46 if (currByte != PrefaceFrame.PREFACE_BYTES[cursor]) { // SM 47 BufferUtils.clear(buffer); 48 notifyConnectionFailure(cast(int)ErrorCode.PROTOCOL_ERROR, "invalid_preface"); 49 return false; 50 } 51 ++cursor; 52 if (cursor == PrefaceFrame.PREFACE_BYTES.length) { 53 cursor = 0; 54 version(HUNT_DEBUG) 55 tracef("Parsed preface bytes"); 56 return true; 57 } 58 } 59 return false; 60 } 61 62 protected void notifyConnectionFailure(int error, string reason) { 63 try { 64 listener.onConnectionFailure(error, reason); 65 } catch (Exception x) { 66 errorf("Failure while notifying listener %s", x, listener); 67 } 68 } 69 }