/// <summary> /// 生成表单和文件 /// </summary> /// <param name="request">请求</param> /// <param name="streamReader">数据读取器</param> /// <param name="boundary">边界</param> private static void GenerateMultipartFormAndFiles(HttpRequest request, IByteStream stream, IContext context, string boundary) { byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary); int maxPosition = stream.Length - Encoding.ASCII.GetBytes("--\r\n").Length; IByteStream reader = stream; List <HttpFile> files = new List <HttpFile>(); HttpNameValueCollection form = new HttpNameValueCollection(); reader.ReadSkip(boundaryBytes.Length); while (reader.ReaderIndex < maxPosition) { int headLength = reader.BytesBefore(DoubleCRLF) + DoubleCRLF.Length; if (headLength < DoubleCRLF.Length) { break; } string head = reader.ReadString(Encoding.UTF8, headLength); int bodyLength = reader.BytesBefore(boundaryBytes); if (bodyLength < 0) { break; } string fileName; MultipartHead mHead = new MultipartHead(head); if (mHead.TryGetFileName(out fileName) == true) { byte[] bytes = reader.ReadBytes(bodyLength); HttpFile file = new HttpFile(mHead.Name, fileName, bytes); files.Add(file); } else { byte[] byes = reader.ReadBytes(bodyLength); string value = byes.Length == 0 ? null : Utility.UrlDecode(byes, Encoding.UTF8); form.Add(mHead.Name, value); } reader.ReadSkip(boundaryBytes.Length); } request.Form = form; request.Files = files.ToArray(); }
/// <summary> /// 解析连接请求信息 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> private static HttpRequestParseResult ParseInternal(IContext context, IByteStream stream, bool isSSL) { HttpRequest request; int headerLength; int contentLength; HttpRequestParseResult result = new HttpRequestParseResult { IsHttp = HttpRequestParser.TryGetRequest(context, stream, isSSL, out request, out headerLength, out contentLength) }; result.ContentLength = contentLength; result.HeaderLength = headerLength; if (result.IsHttp == false) { return(result); } if (request == null) // 数据未完整 { return(result); } switch (request.HttpMethod) { case HttpMethod.GET: request.Body = new byte[0]; request.InputStream = new MemoryStream(request.Body); request.Form = new HttpNameValueCollection(); request.Files = new HttpFile[0]; break; default: stream.SetReaderIndex(headerLength); request.Body = stream.ReadBytes(contentLength); request.InputStream = new MemoryStream(request.Body); stream.SetReaderIndex(headerLength); HttpRequestParser.GeneratePostFormAndFiles(request, context, stream); break; } result.Request = request; result.PackageLength = headerLength + contentLength; return(result); }
/// <summary> /// 解析请求的数据 /// 返回请求数据包 /// </summary> /// <param name="streamReader">数据读取器</param> /// <param name="requiredMask">是否要求必须Mask</param> /// <exception cref="NotSupportedException"></exception> /// <returns></returns> public static FrameRequest Parse(IByteStream streamReader, bool requiredMask = true) { if (streamReader.Length < 2) { return(null); } ByteBits byte0 = streamReader.ReadByte(); bool fin = byte0[0]; ByteBits rsv = byte0.Take(1, 3); FrameCodes frameCode = (FrameCodes)(byte)byte0.Take(4, 4); ByteBits byte1 = streamReader.ReadByte(); bool mask = byte1[0]; if (requiredMask && mask == false) { throw new NotSupportedException("mask is required"); } if (Enum.IsDefined(typeof(FrameCodes), frameCode) == false || rsv != 0) { throw new NotSupportedException(); } int contentSize = 0; int contentLength = byte1.Take(1, 7); if (contentLength == 127) { contentSize = 8; contentLength = (int)streamReader.ReadLong(); } else if (contentLength == 126) { contentSize = 2; contentLength = (ushort)streamReader.ReadShort(); } int maskSize = mask ? 4 : 0; int packetLength = 2 + maskSize + contentSize + contentLength; if (streamReader.Length < packetLength) { return(null); } byte[] maskingKey = mask ? streamReader.ReadBytes(4) : null; byte[] content = streamReader.ReadBytes(contentLength); if (mask && contentLength > 0) { for (int i = 0; i < contentLength; i++) { content[i] = (byte)(content[i] ^ maskingKey[i % 4]); } } return(new FrameRequest { Fin = fin, Rsv = rsv, Mask = mask, Frame = frameCode, ContentLength = contentLength, MaskingKey = maskingKey, Content = content }); }
public byte[] ReadBytes(int len) { return(_stream.ReadBytes(len)); }