/// <summary> /// 解析连接请求信息 /// </summary> /// <param name="context">上下文</param> /// <returns></returns> public static HttpRequestParseResult Parse(IContext context, IByteStream stream, bool isSSL) { HttpRequestParseResult result = ParseInternal(context, stream, isSSL); stream.SetReaderIndex(0); return(result); }
/// <summary> /// SSL解包 /// </summary> /// <param name="context"></param> /// <param name="input"></param> /// <param name="len"></param> /// <returns></returns> IByteStream Unwrap(IContext context, IByteStream input) { IByteStream output = PoolBufferAllocator.Default.AllocStream(); _agent.ReadFromSslStream(output); return(output); }
public static void ClassInitialize(TestContext ctx) { byteStream = A.Fake<IByteStream>(); A.CallTo(() => byteStream.Connected).Returns(true); sut = new Client(byteStream, default(CancellationToken), new TimeSpan(0, 0, 0, 0, 1)); }
public void Read(IByteStream stream, IContext context, bool isssl) { List <FrameRequest> list = new List <FrameRequest>(); while (true) { try { FrameRequest request = FrameRequest.Parse(stream); if (request == null) { break; } list.Add(request); if (request.Fin) { break; } } catch (NotSupportedException ex) { Common.AgentLogger.Instance.Err(string.Format("WebSocketState错误:{0}", ex.Message)); break; } } foreach (FrameRequest request in list) { context.FireNextRead(request); } }
/// <summary> /// Initialises a new instance of the <see cref="BaseClient"/> class. /// </summary> /// <param name="byteStream">The byte stream.</param> /// <param name="token">The token.</param> protected BaseClient(IByteStream byteStream, CancellationToken token) { this.ByteStream = byteStream; this.SendRateLimit = new SemaphoreSlim(1); this.InternalCancellation = new CancellationTokenSource(); token.Register(() => this.InternalCancellation.Cancel()); }
public static void ClassInitialize(TestContext ctx) { byteStream = A.Fake <IByteStream>(); A.CallTo(() => byteStream.Connected).Returns(true); sut = new Client(byteStream, default(CancellationToken), new TimeSpan(0, 0, 0, 0, 1)); }
public SerialPortMessageChannel(IByteStream byteStream, IMessageParserFactory messageParserFactoryFactory, IMessageEncoderFactory messageEncoderFactoryFactory) { _byteStream = byteStream; _messageParserFactory = messageParserFactoryFactory; _messageEncoderFactory = messageEncoderFactoryFactory; }
public void Receive(object source, IByteStream data) { if (ReceiveEvent != null) { ReceiveEvent(source, data); } }
/// <summary> /// Initialises a new instance of the <see cref="BaseClient"/> class. /// </summary> /// <param name="byteStream">The byte stream.</param> /// <param name="token">The token.</param> protected BaseClient(IByteStream byteStream, CancellationToken token) { this.byteStream = byteStream; this.sendRateLimit = new SemaphoreSlim(1); this.internalCancellation = new CancellationTokenSource(); ////token.Register(() => this.SendCancel()); // Call cancel after cancel? What? }
public void Serialize(IByteStream stream) { stream.SerializeString(ref Name, Encoding.ASCII); stream.Serialize(ref Health); stream.Serialize(ref Speed); Inventory.Serialize(stream); }
public void ShouldTimeoutOnCtor() { IByteStream byteStream = A.Fake <IByteStream>(); Client sut; Action act = () => sut = new Client(byteStream, default(CancellationToken), new TimeSpan(0, 0, 0, 0, 1)); act.ShouldThrow <InvalidOperationException>().WithMessage("Unable to connect to the host."); }
public override void GetFrom(IByteStream stream) { seed = stream.GetInt(); int count = stream.GetInt(); for (int i = 0; i < count; i++) { pid.Add(stream.GetUInt()); } }
public void Read(IByteStream stream, IContext context, bool isssl) { ChannelBase channel = context.Channel; HttpRequestParseResult result = HttpRequestParser.Parse(context, stream, isssl); if (!result.IsHttp) { context.FireNextRead(stream); return; } //清除超时定时器 ClearTimeOut(channel); //Post请求太大 if (_config.MaxPostLen > 0 && result.ContentLength > _config.MaxPostLen) { new HttpResponse().End413(context); return; } // 数据未完整 if (result.Request == null) { channel.MergeRead(); return; } //Url太长 if (result.Request.Path.Length > _config.MaxUrlLen) { new HttpResponse().End414(context); return; } if (result.Request.HttpMethod == HttpMethod.OPTIONS) { HttpResponse errreturn = new HttpResponse(); errreturn.Headers.Add("Access-Control-Allow-Origin", "*"); //支持的域名 errreturn.Headers.Add("Access-Control-Allow-Methods", "POST,GET,OPTIONS"); //支持的http动作 errreturn.Headers.Add("Access-Control-Allow-Headers", "Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With"); errreturn.End204(context); return; } // 协议升级成websocket if (result.Request.IsWebsocketRequest()) { string secValue = result.Request.Headers[WEB_SECKEY]; HandshakeResponse handshakeResponse = new HandshakeResponse(result.Request, secValue); channel.SendAsync(handshakeResponse); return; } _keepalive = result.Request.IsKeepAlive(); //开始action处理 context.FireNextRead(result.Request); }
public void ShouldTimeoutOnCtor() { IByteStream byteStream = A.Fake <IByteStream>(); A.CallTo(() => byteStream.Connected).Returns(false); Client sut = null; Action act = () => sut = new Client(byteStream, default(CancellationToken), new TimeSpan(0, 0, 0, 0, 1)); act.ShouldThrow <InvalidOperationException>().WithMessage("Unable to connect to the host."); sut.Should().BeNull(); }
public void ReadFromSslStream(IByteStream outstream) { byte[] tmpreads = new byte[this._inputLength]; int readsize = -1; do { readsize = this._sslstream.Read(tmpreads, 0, this._inputLength); outstream.WriteBytes(tmpreads, 0, readsize); } while (readsize != 0); }
public void GetFrom(IByteStream stream) { int count = stream.GetInt(); for (int i = 0; i < count; i++) { T s = new T(); s.GetFrom(stream); list.Add(s); } }
public void GetFrom(IByteStream stream) { if (!IsNull) { Dispose(); } ushort count = stream.GetUShort(); for (int i = 0; i < count; i++) { T item = new T(); item.GetFrom(stream); list.Add(item); } }
public override void ChannelRead(IContext context, object msg) { IByteStream stream = msg as IByteStream; if (stream != null) { bool isssl = false; //判断是否为SSL加密的请求 if (msg is SSLUnwrapStream) { isssl = true; } _currentState.Read(stream, context, isssl); } }
/// <summary> /// Initialises a new instance of the <see cref="Client"/> class. /// </summary> /// <param name="byteStream">The stream served by the host connected to.</param> /// <param name="token">The cancellation token.</param> /// <param name="timeout">The timeout to wait for initial successful connection to <cref>byteStream</cref>.</param> public Client(IByteStream byteStream, CancellationToken token, TimeSpan timeout) : base(byteStream, token) { Guard.AgainstNullArgument("byteStream", byteStream); DateTime timeoutEnd = DateTime.Now.Add(timeout); while (!this.ByteStream.Connected && timeoutEnd > DateTime.Now) { System.Threading.Thread.Sleep(2); } if (!this.ByteStream.Connected) { throw new InvalidOperationException("Unable to connect to the host."); } }
/// <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> /// Initialises a new instance of the <see cref="Client"/> class. /// </summary> /// <param name="byteStream">The stream served by the host connected to.</param> /// <param name="token">The cancellation token.</param> /// <param name="timeout">The timeout to wait for initial successful connection to <cref>byteStream</cref>.</param> public Client(IByteStream byteStream, CancellationToken token, TimeSpan timeout) : base(byteStream, token) { Guard.AgainstNullArgument("byteStream", byteStream); DateTime timeoutEnd = DateTime.Now.Add(timeout); AutoResetEvent are = new AutoResetEvent(false); while (!this.ByteStream.Connected && timeoutEnd > DateTime.Now) { are.WaitOne(2); } if (!this.ByteStream.Connected) { throw new InvalidOperationException("Unable to connect to the host."); } }
/// <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(); }
public void GetFrom(IByteStream stream) { if (!stream.HasMore()) { return; } ushort count = stream.GetUShort(); array = new T[count]; //if (count == 0) return; //if (array != null) //{ // Dispose(); //} //array = Take(count); for (int i = 0; i < count; i++) { T item = new T(); item.GetFrom(stream); array[i] = item; } }
/// <summary> /// Return how much bytes can be read out of the encrypted data. Be aware that this method will not increase /// the readerIndex of the given <see cref="IByteBuffer"/>. /// </summary> /// <param name="buffer"> /// The <see cref="IByteBuffer"/> to read from. Be aware that it must have at least /// <see cref="SSL_RECORD_HEADER_LENGTH"/> bytes to read, /// otherwise it will throw an <see cref="ArgumentException"/>. /// </param> /// <param name="offset">Offset to record start.</param> /// <returns> /// The length of the encrypted packet that is included in the buffer. This will /// return <c>-1</c> if the given <see cref="IByteBuffer"/> is not encrypted at all. /// </returns> public static int GetEncryptedPacketLength(IByteStream buffer, int offset) { int packetLength = 0; // SSLv3 or TLS - Check ContentType switch (buffer.GetByte(offset)) { case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC: case SSL_CONTENT_TYPE_ALERT: case SSL_CONTENT_TYPE_HANDSHAKE: case SSL_CONTENT_TYPE_APPLICATION_DATA: break; default: // SSLv2 or bad data return(-1); } // SSLv3 or TLS - Check ProtocolVersion int majorVersion = buffer.GetByte(offset + 1); if (majorVersion == 3) { // SSLv3 or TLS packetLength = (ushort)buffer.GetShort(offset + 3) + SSL_RECORD_HEADER_LENGTH; if (packetLength <= SSL_RECORD_HEADER_LENGTH) { // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) return(-1); } } else { // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) return(-1); } return(packetLength); }
IEnumerable <ByteBuffer> CopySequencer() { active = true; var reader = source.Read(OnSourceData, OnSourceError, OnSourceClose); target.PauseWriting(); yield return(new ByteBuffer(new byte[0], 0, 0)); while (active) { var buffer = currentBuffer; target.PauseWriting(); source.ResumeReading(); yield return(buffer); } reader.Dispose(); if (ownsSource) { source.Close(); } source = null; target = null; currentBuffer = null; }
/// <summary> /// Initialises a new instance of the <see cref="BaseClient"/> class. /// </summary> /// <param name="byteStream">The byte stream.</param> protected BaseClient(IByteStream byteStream) { this.ByteStream = byteStream; }
/// <summary> /// 生成Post得到的表单和文件 /// </summary> /// <param name="request">请求</param> /// <param name="streamReader">数据读取器</param> private static void GeneratePostFormAndFiles(HttpRequest request, IContext context, IByteStream stream) { string boundary = ""; if (request.IsApplicationFormRequest() == true) { HttpRequestParser.GenerateApplicationForm(request); } else if (request.IsMultipartFormRequest(out boundary) == true) { if (request.Body.Length >= boundary.Length) { HttpRequestParser.GenerateMultipartFormAndFiles(request, stream, context, boundary); } } if (request.Form == null) { request.Form = new HttpNameValueCollection(); } if (request.Files == null) { request.Files = new HttpFile[0]; } }
/// <summary> /// Initialises a new instance of the <see cref="ByteStreamHandler"/> class. /// </summary> /// <param name="byteStream">The byteStream to handle.</param> /// <param name="internalCancellation">A cancellation token.</param> public ByteStreamHandler(IByteStream byteStream, CancellationTokenSource internalCancellation) { this.byteStream = byteStream; this.internalCancellation = internalCancellation; }
/// <summary> /// Initialises a new instance of the <see cref="Client"/> class. /// </summary> /// <param name="byteStream">The stream served by the host connected to.</param> /// <param name="token">The cancellation token.</param> public Client(IByteStream byteStream, CancellationToken token) : this(byteStream, token, new TimeSpan(0, 0, 30)) { }
public HttpStream(HttpEntity entity, IByteStream stream) { HttpEntity = entity; SocketStream = stream; AddHeaders = true; }
public override void ChannelRead(IContext context, object msg) { IByteStream input = msg as IByteStream; if (input != null) { int endOffset = input.WriterIndex; // 使用该信息计算当前SSL记录的长度。 if (this._packetLength > 0) { if (endOffset < this._packetLength) { //数据未完整 context.Channel.MergeRead(); return; } else { this._packetLength = 0; } } //判断是否为SSL加密包 if (endOffset < SSLUtils.SSL_RECORD_HEADER_LENGTH) { return; } int encryptedPacketLength = SSLUtils.GetEncryptedPacketLength(input, 0); if (encryptedPacketLength == -1) { return; } if (encryptedPacketLength > endOffset) { // 数据未完整 this._packetLength = encryptedPacketLength; context.Channel.MergeRead(); return; } ArraySegment <byte> inputIoBuffer = input.GetIOBuffer(); _agent.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset, input.Length); if ((_agent.State & SSLHandlerState.Authenticating) != 0) { _agent.TriggerHandshakeRead(); } else { if (EnsureAuthenticated()) { IByteStream output = this.Unwrap(context, input); context.FireNextRead(new SSLUnwrapStream(output)); } } return; } context.FireNextRead(msg); }
/// <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 }); }
/// <summary> /// Initialises a new instance of the <see cref="ByteStreamHandler"/> class. /// </summary> /// <param name="byteStream">The byteStream to handle.</param> public ByteStreamHandler(IByteStream byteStream) { this.byteStream = byteStream; }
public override void GetFrom(IByteStream stream) { mapType = stream.GetInt(); }
/// <summary> /// 尝试当作http头解析,生成请求对象 /// 如果不是http头则返回false /// </summary> /// <param name="context">上下文</param> /// <param name="request">请求对象</param> /// <param name="headerLength">请求头长度</param> /// <param name="contentLength">请求内容长度</param> /// <returns></returns> private static bool TryGetRequest(IContext context, IByteStream stream, bool isSSL, out HttpRequest request, out int headerLength, out int contentLength) { request = null; headerLength = 0; contentLength = 0; IByteStream reader = stream; ChannelBase channel = context.Channel; if (channel == null) { return(false); } // HTTP Method reader.SetReaderIndex(0); int methodLength = reader.BytesBefore(Space); if (methodLength < 0 || methodLength > MedthodMaxLength) { return(false); } string methodName = reader.ReadString(Encoding.ASCII, methodLength); if (MethodNames.Contains(methodName) == false) { return(false); } HttpMethod httpMethod = (HttpMethod)Enum.Parse(typeof(HttpMethod), methodName, true); // HTTP Path reader.ReadSkip(1); int pathLength = reader.BytesBefore(Space); if (pathLength < 0) { return(false); } string path = reader.ReadString(Encoding.ASCII, pathLength); // HTTP Version reader.ReadSkip(1); if (reader.StartWith(HttpVersion11) == false) { return(false); } reader.ReadSkip(HttpVersion11.Length); if (reader.StartWith(CRLF) == false) { return(false); } // HTTP Second line reader.ReadSkip(CRLF.Length); int endIndex = reader.BytesBefore(DoubleCRLF); if (endIndex < 0) { return(false); } HttpNameValueCollection httpHeader = new HttpNameValueCollection(); headerLength = reader.ReaderIndex + endIndex + DoubleCRLF.Length; while (reader.ReaderIndex < headerLength - CRLF.Length) { int keyLength = reader.BytesBefore(KvSpliter); if (keyLength <= 0) { break; } string key = reader.ReadString(Encoding.ASCII, keyLength); reader.ReadSkip(KvSpliter.Length); int valueLength = reader.BytesBefore(CRLF); if (valueLength < 0) { break; } string value = reader.ReadString(Encoding.ASCII, valueLength); if (reader.StartWith(CRLF) == false) { break; } reader.ReadSkip(CRLF.Length); httpHeader.Add(key, value); } if (httpMethod != HttpMethod.GET) { contentLength = httpHeader.TryGet <int>("Content-Length"); if (reader.Length - headerLength < contentLength) { return(true);// 数据未完整 } } request = new HttpRequest { LocalEndPoint = (IPEndPoint)channel.LocalEndPoint, RemoteEndPoint = (IPEndPoint)channel.RemoteEndPoint, HttpMethod = httpMethod, Headers = httpHeader }; //获取请求cookie string reqcookies = httpHeader.TryGet <string>("Cookie"); if (reqcookies != null) { GenerateCookies(request, reqcookies); } string scheme = isSSL ? "https" : "http"; string host = httpHeader["Host"]; if (string.IsNullOrEmpty(host) == true) { host = channel.LocalEndPoint.ToString(); } request.Host = host; string referer = httpHeader.TryGet <string>("Referer"); if (!string.IsNullOrEmpty(referer)) { try { request.RefererUrl = new Uri(referer); } catch { } } request.UserAgent = httpHeader.TryGet <string>("User-Agent", ""); request.Url = new Uri(string.Format("{0}://{1}{2}", scheme, host, path)); request.Path = request.Url.AbsolutePath; request.Query = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?')); return(true); }