/// <summary> /// 解析HttpHeader,得到其实例 /// </summary> /// <param name="httpHeader"></param> /// <param name="request"></param> /// <returns></returns> NameValueCollection parseRequest(ChainHeader chainHeader, String request) { NameValueCollection headparams = new NameValueCollection(); //String request = streamReadLine(inputStream); string[] tokens = request.Split(' '); if (tokens.Length != 3) { throw new Exception("invalid http request line"); } //_HttpMethod = tokens[0].ToUpper(); chainHeader.Method = tokens[0].ToUpper(); chainHeader.Url = tokens[1]; MatchCollection mc = reg.Matches(tokens[1]); // chainHeader.QueryString.Add(System.Web.HttpUtility.ParseQueryString(tokens[1], Encoding.UTF8)); foreach (Match m in mc) { string key = m.Groups["key"].Value; string value = m.Groups["value"].Value; if (!string.IsNullOrEmpty(key) && headparams.GetValue(key).IsNullOrEmpty()) { chainHeader.QueryString.Add(key, value); } } chainHeader.Protocol = tokens[2]; return(headparams); //http_protocol_versionstring = tokens[2]; }
/// <summary> /// 把byte[]解析成Chain消息包 /// </summary> /// <param name="package"></param> /// <returns></returns> public ChainPackage ResolveProtocol(byte[] package) { int headlen = package.ToList <byte>().SearchMark(0, package.ToList <byte>().Count, m_SearchState); if (headlen == -1) { headlen = package.Length; } byte[] head_data = new byte[headlen]; Buffer.BlockCopy(package, 0, head_data, 0, headlen); // NameValueCollection _Headers = GetHeader(head_data); ChainHeader httpHeader = GetChainHander(head_data); ChainPackage chainRequest = null; switch (httpHeader.Method) { case "GET": case "DELETE": { chainRequest = new ChainPackage(new byte[0], httpHeader); return(chainRequest); } case "POST": case "PUT": { int contentLen = Convert.ToInt32(httpHeader.Data[HeadKeys.ContentLen]); byte[] contentdata = new byte[contentLen]; Buffer.BlockCopy(package, headlen + m_SearchState.Mark.Length, contentdata, 0, contentLen); chainRequest = new ChainPackage(contentdata, httpHeader); return(chainRequest); } case "CHAIN": { int headlength = headlen + 4; int bodylength = Convert.ToInt32(httpHeader.Data[HeadKeys.ContentLen]); byte[] body = new byte[bodylength]; if (bodylength > 0) { Buffer.BlockCopy(package, headlength, body, 0, bodylength); } if (httpHeader.Data[HeadKeys.CmdName] != null) { chainRequest = new ChainPackage(body, httpHeader.Data[HeadKeys.CmdName], httpHeader); } else { chainRequest = new ChainPackage(body, httpHeader); } return(chainRequest); } } return(chainRequest); }
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) { int bodyLength = 0; ChainHeader chainHeader = protocol.GetChainHeader(header); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { bodyLength += 4; } else { int contentLen = Convert.ToInt32(chainHeader.Data["Content-Length"]); bodyLength = length + contentLen + 4; } return(bodyLength); }
/// <summary> /// Filters the specified session. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest.</param> /// <returns></returns> public virtual TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { //获取包头信息 ChainProtocol hp = new ChainProtocol(); result = readBuffer.SearchMark(offset, length, m_SearchState); if (result == -1) { rest = -1; } else { m_Size = result - offset; byte[] headerdata = new byte[m_Size]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, m_Size); ChainHeader chainHeader = hp.GetChainHeader(headerdata); rest = m_ParsedLength + length - m_Size; } if (rest >= 0) { var requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLength, m_Size, toBeCopied); InternalReset(); return(requestInfo); } else { m_ParsedLength += length; m_OffsetDelta = m_ParsedLength; rest = 0; var expectedOffset = offset + length; var newOffset = m_OrigOffset + m_OffsetDelta; if (newOffset < expectedOffset) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLength + length, readBuffer, m_OrigOffset, m_ParsedLength); } return(NullRequestInfo); } }
/// <summary> /// 得到头数据 /// </summary> /// <param name="packages"></param> /// <returns></returns> public ChainHeader GetChainHander(byte[] header) { ChainHeader chainHeader = new ChainHeader(); NameValueCollection headers = new NameValueCollection(); string package = Encoding.UTF8.GetString(header); string[] tokens = package.Split(' '); string[] splits = Regex.Split(package, "\r\n\r\n", RegexOptions.IgnoreCase); if (splits.Length > 0) { string[] heads = Regex.Split(splits[0], "\r\n", RegexOptions.IgnoreCase); if (heads.Length > 0) { parseRequest(chainHeader, heads[0]); chainHeader.Data.Add(readHeaders(heads)); } } return(chainHeader); }
/// <summary> /// 获得包头的信息:包的内容长度 /// </summary> /// <param name="readBuffer"></param> /// <param name="receiveLen"></param> /// <returns></returns> public byte[] GetSinglePackage(IList <byte> readBuffer, ref int offset, ref int resolveLen) { if (chainCache != null && (readBuffer.Count() + chainCache.Count()) >= cachePackageLen) { byte[] cache_single_package = new byte[cachePackageLen]; Buffer.BlockCopy(chainCache.ToArray(), 0, cache_single_package, 0, chainCache.Count()); Buffer.BlockCopy(readBuffer.ToArray(), 0, cache_single_package, chainCache.Count(), cachePackageLen - chainCache.Count()); offset += cachePackageLen - chainCache.Count(); resolveLen += offset; chainCache = null; cachePackageLen = 0; return(cache_single_package); } int headlen = readBuffer.SearchMark(offset, readBuffer.Count, m_SearchState); if (headlen == -1) { throw new Exception("Message head is Missed"); } byte[] head_data = new byte[headlen - offset]; Buffer.BlockCopy(readBuffer.ToArray(), offset, head_data, 0, headlen - offset); ChainHeader temp = GetChainHander(head_data); int packageLen = headlen - offset + Convert.ToInt32(temp.Data[HeadKeys.ContentLen]) + m_SearchState.Mark.Count(); byte[] single_package = new byte[packageLen]; if ((readBuffer.Count() - offset) < packageLen && chainCache == null) { chainCache = new byte[readBuffer.Count() - offset]; cachePackageLen = packageLen; Buffer.BlockCopy(readBuffer.ToArray(), offset, chainCache, 0, readBuffer.Count() - offset); return(null); } else { Buffer.BlockCopy(readBuffer.ToArray(), offset, single_package, 0, packageLen); offset += packageLen; resolveLen += packageLen; } return(single_package); }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; int prevMatched = m_SearchState.Matched; int result = readBuffer.SearchMark(offset, length, m_SearchState); var findLen = result - offset; var packageLen = 0; //当在收到的数据中没有找到头信息,可能情况:1头信息不完整,2可能是在上一个包中已经存在头信息 if (result <= 0) { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } rest = 0; return(NullRequestInfo); } else if (result > 0 && findLen > 0) //头信息完整,并且获得到了头信息,并得到该包的大小。当在一次获取时得到了包的信息 { byte[] headerdata = new byte[findLen]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, findLen); ChainProtocol hp = new ChainProtocol(); ChainHeader chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; packageLen = findLen; } else { int contentLen = Convert.ToInt32(chainHeader.Data.Get("Content-Length")); packageLen = contentLen + findLen; //findLen += contentLen + m_SearchState.Mark.Length; if ((readBuffer.Length - offset) >= packageLen) { findLen += contentLen + m_SearchState.Mark.Length; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; m_OffsetDelta += length; return(NullRequestInfo); } m_OffsetDelta += length; } } } rest = length - findLen - (m_SearchState.Mark.Length - prevMatched); TRequestInfo requestInfo; //当收到最后的数据时,进行组织包 if (findLen > 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer); } } else if (findLen <= 0) { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } else if (prevMatched > 0) { if (m_ParsedLengthInBuffer > 0) { if (m_ParsedLengthInBuffer < prevMatched) { BufferSegments.TrimEnd(prevMatched - m_ParsedLengthInBuffer); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer - prevMatched); } } } else { BufferSegments.TrimEnd(prevMatched); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if (rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return(requestInfo); }
/// <summary> /// Filters received data of the specific session into request info. /// </summary> /// <param name="readBuffer">The read buffer.</param> /// <param name="offset">The offset of the current received data in this read buffer.</param> /// <param name="length">The length of the current received data.</param> /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param> /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param> /// <returns>return the parsed TRequestInfo</returns> public override TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { rest = 0; TRequestInfo requestInfo; int prevMatched = m_SearchState.Matched; int result = 0; var findLen = result - offset; int remainlen = 0; //Debug.WriteLine("缓存:" + this.BufferSegments.Count); //判断缓存是否存在,如果存在说明之前数据没有取完,出现粘包 if (this.BufferSegments.Count > 0) { if (packLength == 0)//说明之前的数据只有部分包头信息,没能进行解析包头信息 { ////////// //把缓存的数据加上新收到的数据合并的总接收到的数据,进行查找 int receivedLen = length + this.LeftBufferSize; byte[] receivedData = new byte[receivedLen]; Buffer.BlockCopy(this.BufferSegments.ToArray(), 0, receivedData, 0, this.BufferSegments.Count); Buffer.BlockCopy(readBuffer, offset, receivedData, this.BufferSegments.Count, length); result = receivedData.SearchMark(0, receivedLen, m_SearchState); findLen = result - this.LeftBufferSize; if (findLen > 0)//找到包头的数据 { byte[] headerdata = new byte[findLen + this.BufferSegments.Count]; Buffer.BlockCopy(this.BufferSegments.ToArray(), 0, headerdata, 0, this.BufferSegments.Count); Buffer.BlockCopy(readBuffer, offset, headerdata, this.BufferSegments.Count, findLen); ChainProtocol hp = new ChainProtocol(); chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; } else { int contentLen = Convert.ToInt32(chainHeader.Data["Content-Length"]); packLength = headerdata.Length + contentLen + m_SearchState.Mark.Length; //包的长度大于接收的长度,则需要缓存下来等下一个包数据过来进行拼接 if (packLength > (length + this.LeftBufferSize)) { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } else if (packLength <= (length + this.LeftBufferSize))//包的长度小于接收的数据长度加上缓存长度,则生成该包,并把多余的数据缓存下来 { //包的长度刚好等于接收的数据长度,则生成该包即可 //Debug.WriteLine("packLength:{0} < length:{1}".FormatString(packLength,length)); findLen = packLength - this.LeftBufferSize; } } } else//第一个包的数据不够一个包头的长度 { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } /////////// } else { //剩余的数据包大小 remainlen = packLength - this.BufferSegments.Count; if (remainlen > 0 && remainlen <= length)//说明剩余的数据等于本次接收的数据//剩余数据小于本次接收的数据长度,则需要重新组包 { findLen = remainlen; } else if (remainlen > 0 && remainlen > length)//剩余数据大于接收得到数据长度,需要缓存下来,等下一个包过来进行拼接 { if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; ////// // m_ParsedLengthInBuffer += length; // m_ParsedLengthInBuffer = 0; // m_OffsetDelta = 0; return(NullRequestInfo); } else if (remainlen < 0)//不存在 { } } } else//没有缓存则需要直接获取数据 { result = readBuffer.SearchMark(offset, length, m_SearchState); findLen = result - offset; if (findLen > 0)//找到包头的数据 { byte[] headerdata = new byte[findLen]; Buffer.BlockCopy(readBuffer, offset, headerdata, 0, findLen); ChainProtocol hp = new ChainProtocol(); chainHeader = hp.GetChainHander(headerdata); if (chainHeader.Method == "GET" || chainHeader.Method == "DELETE") { findLen += m_SearchState.Mark.Length; } else { int contentLen = Convert.ToInt32(chainHeader.Data["Content-Length"]); packLength = headerdata.Length + contentLen + m_SearchState.Mark.Length; //包的长度大于接收的长度,则需要缓存下来等下一个包数据过来进行拼接 if (packLength > length) { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } else if (packLength <= length) //包的长度小于接收的数据长度,则生成该包,并把多余的数据缓存下来 { //包的长度刚好等于接收的数据长度,则生成该包即可 findLen = packLength; } } } else//第一个包的数据不够一个包头的长度 { //m_ParsedLengthInBuffer += length; //this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); //m_ParsedLengthInBuffer = 0; //m_OffsetDelta = 0; if (m_OffsetDelta != m_ParsedLengthInBuffer) { Buffer.BlockCopy(readBuffer, offset - m_ParsedLengthInBuffer, readBuffer, offset - m_OffsetDelta, m_ParsedLengthInBuffer + length); m_ParsedLengthInBuffer += length; m_OffsetDelta = m_ParsedLengthInBuffer; } else { m_ParsedLengthInBuffer += length; if (m_ParsedLengthInBuffer >= m_Session.Config.ReceiveBufferSize) { this.AddArraySegment(readBuffer, offset + length - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer, toBeCopied); m_ParsedLengthInBuffer = 0; m_OffsetDelta = 0; return(NullRequestInfo); } m_OffsetDelta += length; } return(NullRequestInfo); } } //计算偏移 rest = length - findLen + prevMatched; if (findLen > 0) { if (this.BufferSegments != null && this.LeftBufferSize > 0) { //Debug.WriteLine("包大小{0},缓存大小{1},接收大小{2}".FormatString(packLength,this.LeftBufferSize, length)); this.AddArraySegment(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer, toBeCopied); requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, findLen + m_ParsedLengthInBuffer); } } else { if (this.BufferSegments != null && this.BufferSegments.Count > 0) { requestInfo = ProcessMatchedRequest(BufferSegments, 0, BufferSegments.Count); } else { requestInfo = ProcessMatchedRequest(readBuffer, offset - m_ParsedLengthInBuffer, m_ParsedLengthInBuffer); } } InternalReset(); if (rest == 0) { m_OffsetDelta = 0; } else { m_OffsetDelta += (length - rest); } return(requestInfo); }