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 }