1 /* 2 * MsgTrans - Message Transport Framework for DLang. Based on TCP, WebSocket, UDP transmission protocol. 3 * 4 * Copyright (C) 2019 HuntLabs 5 * 6 * Website: https://www.msgtrans.org 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module msgtrans.channel.tcp.TcpDecoder; 13 14 import msgtrans.PacketParser; 15 import msgtrans.MessageBuffer; 16 17 import hunt.io.ByteBuffer; 18 import hunt.io.BufferUtils; 19 import hunt.Exceptions; 20 import hunt.logging.ConsoleLogger; 21 import hunt.net; 22 23 import std.algorithm; 24 import std.conv; 25 26 27 class TcpDecoder : DecoderChain { 28 private enum string PARSER = "PacketParser"; 29 30 /** The default maximum buffer length. Default to 128 chars. */ 31 private int bufferLength = 128; 32 33 /** The default maximum Line length. Default to 1024. */ 34 private int maxLineLength = 8*1024; 35 36 37 this() { 38 super(null); 39 } 40 41 42 /** 43 * @return the allowed maximum size of the line to be decoded. 44 * If the size of the line to be decoded exceeds this value, the 45 * decoder will throw a {@link BufferDataException}. The default 46 * value is <tt>1024</tt> (1KB). 47 */ 48 int getMaxLineLength() { 49 return maxLineLength; 50 } 51 52 /** 53 * Sets the allowed maximum size of the line to be decoded. 54 * If the size of the line to be decoded exceeds this value, the 55 * decoder will throw a {@link BufferDataException}. The default 56 * value is <tt>1024</tt> (1KB). 57 * 58 * @param maxLineLength The maximum line length 59 */ 60 void setMaxLineLength(int maxLineLength) { 61 if (maxLineLength <= 0) { 62 throw new IllegalArgumentException("maxLineLength (" ~ 63 maxLineLength.to!string() ~ ") should be a positive value"); 64 } 65 66 this.maxLineLength = maxLineLength; 67 } 68 69 /** 70 * Sets the default buffer size. This buffer is used in the Context 71 * to store the decoded line. 72 * 73 * @param bufferLength The default bufer size 74 */ 75 void setBufferLength(int bufferLength) { 76 if (bufferLength <= 0) { 77 throw new IllegalArgumentException("bufferLength (" ~ 78 maxLineLength.to!string() ~ ") should be a positive value"); 79 80 } 81 82 this.bufferLength = bufferLength; 83 } 84 85 /** 86 * @return the allowed buffer size used to store the decoded line 87 * in the Context instance. 88 */ 89 int getBufferLength() { 90 return bufferLength; 91 } 92 93 override 94 void decode(ByteBuffer buf, Connection connection) { 95 version(HUNT_MESSAGE_DEBUG) tracef("connection %d: %s", connection.getId(), buf.toString()); 96 PacketParser parser = getParser(connection); 97 98 MessageBuffer[] msgBuffers = parser.parse(buf); 99 if(msgBuffers is null) { 100 warning("No frame parsed."); 101 return; 102 } 103 104 NetConnectionHandler handler = connection.getHandler(); 105 if(handler is null) { 106 warning("No handler found."); 107 return; 108 } 109 110 foreach(MessageBuffer msg; msgBuffers) { 111 handler.messageReceived(connection, msg); 112 } 113 114 } 115 116 private PacketParser getParser(Connection connection) { 117 PacketParser ctx; 118 ctx = cast(PacketParser) connection.getAttribute(PARSER); 119 120 if (ctx is null) { 121 ctx = new PacketParser(bufferLength); 122 connection.setAttribute(PARSER, ctx); 123 } 124 125 return ctx; 126 } 127 128 129 void dispose(Connection connection) { 130 PacketParser ctx = cast(PacketParser) connection.getAttribute(PARSER); 131 132 if (ctx !is null) { 133 connection.removeAttribute(PARSER); 134 } 135 } 136 137 } 138