示例#1
0
        private void CloseChunkGzip()
        {
            var crlfBuffer = this.Encoding.GetBytes("\r\n");
            var buffers    = new ArraySegment <byte> [4];

            //
            //gzip
            this.chunkGzipStream.Close();
            var contentLength = (int)this.chunkStream.Length;

            this.chunkStream.Position = 0;
            contentBuffer             = StreamHelper.Receive(this.chunkStream, contentLength);
            this.chunkStream.SetLength(0);
            //len
            var lenBuffer = this.Encoding.GetBytes(contentLength.ToString("x"));

            buffers[0] = new ArraySegment <byte>(lenBuffer);
            buffers[1] = new ArraySegment <byte>(crlfBuffer);
            //content
            buffers[2] = new ArraySegment <byte>(contentBuffer);
            buffers[3] = new ArraySegment <byte>(crlfBuffer);
            //
            try
            {
                this.socket.Send(buffers);
            }
            catch
            {
                SocketHelper.TryClose(this.socket);
                StreamHelper.TryClose(this.chunkGzipStream);
                StreamHelper.TryClose(this.chunkStream);
                this.chunkWriteEvent.Set();
                throw;
            }
        }
示例#2
0
        private void NewAccept(IAsyncResult ar)
        {
            Socket socket = null;

            try
            {
                socket = this.listenSocket.EndAccept(ar);
            }
            catch { }

            //new accept
            try
            {
                this.listenSocket.BeginAccept(this.NewAccept, null);
            }
            catch (ObjectDisposedException) { }

            //
            if (socket != null)
            {
                try
                {
                    ConnectionState connectionState;
                    //keep alive
                    while (true)
                    {
                        connectionState = this.NewConnection(socket);
                        if (connectionState == ConnectionState.KeepAlive)
                        {
                            //next request
                        }
                        else if (connectionState == ConnectionState.Closed)
                        {
                            //close and exit
                            SocketHelper.TryClose(socket);
                            break;
                        }
                        else if (connectionState == ConnectionState.KeepConnection)
                        {
                            //keep connection & exit
                            break;
                        }
                    }
                }
                catch (SocketException)
                {
                    SocketHelper.TryClose(socket);
                }
                catch (Exception exception)
                {
                    SocketHelper.TryClose(socket);
                    this.OnError(exception);
                }
            }
        }
示例#3
0
 /// <summary>
 /// Write Chunk Content
 /// </summary>
 /// <param name="contentBuffer"></param>
 private void Chunk(byte[] contentBuffer)
 {
     lock (this.chunkWriteEvent)
     {
         var crlfBuffer = this.Encoding.GetBytes("\r\n");
         var buffers    = new ArraySegment <byte> [4];
         //
         int contentLength = contentBuffer.Length;
         //gzip
         if (this.acceptGzip && this.gzipThreshold != 0)
         {
             this.chunkGzipStream.Write(contentBuffer, 0, contentBuffer.Length);
             contentLength = (int)this.chunkStream.Length;
             if (contentLength < 256)
             {
                 //小字节退出,待下次压缩或关闭压缩
                 return;
             }
             this.chunkStream.Position = 0;
             contentBuffer             = StreamHelper.Receive(this.chunkStream, contentLength);
             this.chunkStream.SetLength(0);
         }
         //len
         var lenBuffer = this.Encoding.GetBytes(contentLength.ToString("x"));
         buffers[0] = new ArraySegment <byte>(lenBuffer);
         buffers[1] = new ArraySegment <byte>(crlfBuffer);
         //content
         buffers[2] = new ArraySegment <byte>(contentBuffer);
         buffers[3] = new ArraySegment <byte>(crlfBuffer);
         //
         try
         {
             this.socket.Send(buffers);
         }
         catch
         {
             SocketHelper.TryClose(this.socket);
             StreamHelper.TryClose(this.chunkGzipStream);
             StreamHelper.TryClose(this.chunkStream);
             this.chunkWriteEvent.Set();
             throw;
         }
     }
 }
示例#4
0
        /// <summary>
        /// connect to host
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="timeout"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <exception cref="System.TimeoutException">connect timeout</exception>
        public static void Connect(Socket socket, string host, int port, int timeout)
        {
            using (var eventHandle = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset))
            {
                socket.BeginConnect(host, port, ar2 =>
                {
                    try
                    {
                        socket.EndConnect(ar2);
                        //
                        eventHandle.Set();
                    }
                    catch { }
                }, null);
                //
                if (eventHandle.WaitOne(timeout) == false)
                {
                    SocketHelper.TryClose(socket);

                    throw new TimeoutException("Connect to " + host + ":" + port + " timeout.");
                }
            }
        }
示例#5
0
        /// <summary>
        /// 响应客户端
        /// </summary>
        /// <param name="build"></param>
        /// <param name="status"></param>
        protected override void Response(StringBuilder build, HttpStatusCode status)
        {
            byte[] contentBuffer = null;
            byte[] headerBuffer  = null;

            //header
            if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin)
            {
                if (this.contentBuffer != null)
                {
                    contentBuffer = this.contentBuffer;
                }
                else if (!string.IsNullOrEmpty(this.content))
                {
                    contentBuffer = this.Encoding.GetBytes(this.content);
                }
                else
                {
                    contentBuffer = new byte[0];
                }

                //gzip
                if (this.acceptGzip && this.gzipThreshold != 0 && contentBuffer.Length > this.gzipThreshold)
                {
                    build.AppendLine("Content-Encoding: gzip");

                    using (var m = new MemoryStream())
                        using (var stream = new GZipStream(m, CompressionMode.Compress, true))
                        {
                            stream.Write(contentBuffer, 0, contentBuffer.Length);
                            stream.Close();
                            //content
                            contentBuffer = m.ToArray();
                        }
                }

                build.AppendLine(string.Concat("Content-Length: ", contentBuffer.Length));
                build.AppendLine();
            }
            else
            {
                if (this.acceptGzip && this.gzipThreshold != 0)
                {
                    build.AppendLine("Content-Encoding: gzip");
                }
                build.AppendLine("Transfer-Encoding: chunked");
                build.AppendLine();
            }
            headerBuffer = Encoding.ASCII.GetBytes(build.ToString());

            //
            if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin)
            {
                if (this.isRequestHead == false && contentBuffer != null && contentBuffer.Length > 0)
                {
                    var buffers = new ArraySegment <byte> [2];
                    //header
                    buffers[0] = new ArraySegment <byte>(headerBuffer);
                    //content
                    buffers[1] = new ArraySegment <byte>(contentBuffer);
                    //send
                    this.socket.Send(buffers);
                }
                else
                {
                    this.socket.Send(headerBuffer);
                }
            }
            else
            {
                try
                {
                    this.socket.Send(headerBuffer);
                }
                catch
                {
                    SocketHelper.TryClose(this.socket);
                    StreamHelper.TryClose(this.chunkGzipStream);
                    StreamHelper.TryClose(this.chunkStream);
                    throw;
                }
            }
        }
示例#6
0
        /// <summary>
        /// End Write
        /// </summary>
        /// <exception cref="InvalidOperationException">No Invoke BeginWrite / Has Been Invoked EndWrite</exception>
        public void EndWrite()
        {
            lock (this.chunkWriteEvent)
            {
                if (this.chunkWriteStatus == HttpServerChunkStatus.NoBegin)
                {
                    throw new InvalidOperationException("No Invoke BeginWrite");
                }

                if (this.chunkWriteStatus == HttpServerChunkStatus.End)
                {
                    throw new InvalidOperationException("Has Been Invoked EndWrite");
                }

                if (this.chunkWriteStatus == HttpServerChunkStatus.Writing)
                {
                    this.chunkWriteStatus = HttpServerChunkStatus.End;

                    try
                    {
                        //gzip
                        if (this.acceptGzip && this.gzipThreshold != 0)
                        {
                            this.CloseChunkGzip();
                        }

                        if (this.isRequestHead == false)
                        {
                            var crlfBuffer = this.Encoding.GetBytes("\r\n");

                            var buffers = new ArraySegment <byte> [3];
                            using (var m = new MemoryStream(512))
                            {
                                //len
                                var lenBuffer = this.Encoding.GetBytes("0");
                                buffers[0] = new ArraySegment <byte>(lenBuffer);
                                buffers[1] = new ArraySegment <byte>(crlfBuffer);
                                //content
                                buffers[2] = new ArraySegment <byte>(crlfBuffer);
                            }
                            //
                            try
                            {
                                this.socket.Send(buffers);
                            }
                            catch
                            {
                                SocketHelper.TryClose(this.socket);
                                throw;
                            }
                            finally
                            {
                                StreamHelper.TryClose(this.chunkGzipStream);
                                StreamHelper.TryClose(this.chunkStream);
                                this.chunkWriteEvent.Set();
                            }
                        }
                        else
                        {
                            this.chunkWriteEvent.Set();
                        }
                    }
                    catch (Exception exception)
                    {
                        throw new InvalidOperationException("End check write failure", exception);
                    }
                }
            }
        }
示例#7
0
        ///// <summary>
        ///// 初始化内容帧
        ///// </summary>
        ///// <param name="buffer"></param>
        //public WebSocketDataFrame(byte[] buffer)
        //{
        //    //帧头
        //    _header = new WebSocketDataFrameHeader(buffer);

        //    //扩展长度
        //    if (_header.Length == 126)
        //    {
        //        _extend = new byte[2];
        //        Buffer.BlockCopy(buffer, 2, _extend, 0, 2);
        //    }
        //    else if (_header.Length == 127)
        //    {
        //        _extend = new byte[8];
        //        Buffer.BlockCopy(buffer, 2, _extend, 0, 8);
        //    }

        //    //是否有掩码
        //    if (_header.HasMask)
        //    {
        //        _mask = new byte[4];
        //        Buffer.BlockCopy(buffer, _extend.Length + 2, _mask, 0, 4);
        //    }

        //    //消息体
        //    if (_extend.Length == 0)
        //    {
        //        _content = new byte[_header.Length];
        //        Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, _content.Length);
        //    }
        //    else if (_extend.Length == 2)
        //    {
        //        int contentLength = (int)_extend[0] * 256 + (int)_extend[1];
        //        _content = new byte[contentLength];
        //        Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, contentLength > 1024 * 100 ? 1024 * 100 : contentLength);
        //    }
        //    else
        //    {
        //        long len = 0;
        //        int n = 1;
        //        for (int i = 7; i >= 0; i--)
        //        {
        //            len += (int)_extend[i] * n;
        //            n *= 256;
        //        }
        //        _content = new byte[len];
        //        Buffer.BlockCopy(buffer, _extend.Length + _mask.Length + 2, _content, 0, _content.Length);
        //    }

        //    if (_header.HasMask) _content = Mask(_content, _mask);

        //}

        /// <summary>
        /// 初始化一个Socket数据帧
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="headerBuffer"></param>
        public WebSocketDataFrame(Socket socket, byte[] headerBuffer)
        {
            //var header = new WebSocketDataFrameHeader(this.headerBuffer);
            //byte[] extend = new byte[0];

            ////扩展长度
            //if (header.Length == 126)
            //{
            //    extend = SocketHelper.Receive(this.Socket, 2);
            //}
            //else if (header.Length == 127)
            //{
            //    extend = SocketHelper.Receive(this.Socket, 8);
            //}

            ////是否有掩码
            //byte[] _mask = null;
            //if (header.HasMask)
            //{
            //    _mask = SocketHelper.Receive(this.Socket, 4);
            //}

            ////content length
            //var content_length = 0L;
            //if (extend.Length == 0)
            //    content_length = header.Length;
            //else if (extend.Length == 2)
            //    content_length = (int)extend[0] * 256 + (int)extend[1];
            //else
            //{
            //    int n = 1;
            //    for (int i = 7; i >= 0; i--)
            //    {
            //        content_length += (int)extend[i] * n;
            //        n *= 256;
            //    }

            //    if (content_length > int.MaxValue)
            //        throw new WebException("Data length transfinite");
            //}

            //var contentBuffer = SocketHelper.Receive(this.Socket, (int)content_length);
            //if (header.HasMask)
            //{
            //    WebSocketDataFrame.Mask(contentBuffer, _mask);
            //}

            _header = new WebSocketDataFrameHeader(headerBuffer);

            //扩展长度
            if (_header.Length == 126)
            {
                _extend = SocketHelper.Receive(socket, 2);
            }
            else if (_header.Length == 127)
            {
                _extend = SocketHelper.Receive(socket, 8);
            }

            //是否有掩码
            if (_header.HasMask)
            {
                _mask = SocketHelper.Receive(socket, 4);
            }

            //content length
            var content_length = 0L;

            if (_extend.Length == 0)
            {
                content_length = _header.Length;
            }
            else if (_extend.Length == 2)
            {
                content_length = (int)_extend[0] * 256 + (int)_extend[1];
            }
            else
            {
                int n = 1;
                for (int i = 7; i >= 0; i--)
                {
                    content_length += (int)_extend[i] * n;
                    n *= 256;
                }

                if (content_length > int.MaxValue)
                {
                    throw new WebException("Data length transfinite");
                }
            }

            this.Content = SocketHelper.Receive(socket, (int)content_length);
            if (_header.HasMask)
            {
                Mask(this.Content, _mask);
            }
        }
示例#8
0
        /// <summary>
        /// 解析POST数扰
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="context"></param>
        /// <returns>是否成功</returns>
        protected virtual bool ParsePostData(Socket socket, HttpServerContext context)
        {
            var success       = false;
            var contentLength = 0;

            int.TryParse(context.RequestHeader["Content-Length"], out contentLength);
            if (contentLength > context.MaxRequestContentLength)
            {
                //请求主体超过限制
                if (string.IsNullOrEmpty(context.Content) && context.ContentBuffer == null)
                {
                    context.Content = "Request Entity Too Large";
                }
                context.Response(HttpStatusCode.RequestEntityTooLarge);
            }
            else if (contentLength > 0)
            {
                string contentType = context.RequestHeader["Content-Type"];
                if (contentType == null)
                {
                    context.PostData = SocketHelper.Receive(socket, contentLength);
                    success          = true;
                }
                else if ("application/x-www-form-urlencoded".Equals(contentType, StringComparison.OrdinalIgnoreCase))
                {
                    var data     = SocketHelper.Receive(socket, contentLength);
                    var postdata = this.encoding.GetString(data);
                    UriHelper.ParseQueryString(postdata, this.encoding, context.Form);
                    success = true;
                }
                else if (contentType.IndexOf("multipart/form-data", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    //"multipart/form-data; boundary=---------------------boundary123data"
                    var boundary = contentType.Substring(contentType.IndexOf("boundary=") + 9);
                    var receiver = new HttpServerMultipartReceiver(socket, boundary, context, contentLength);
                    try
                    {
                        return(receiver.Receive());
                    }
                    catch (Exception exception)
                    {
                        //请求主体超过限制
                        if (string.IsNullOrEmpty(context.Content) && context.ContentBuffer == null)
                        {
                            context.Content = "Paser Post Data Failure " + exception.Message;
                        }
                        context.Response(HttpStatusCode.BadRequest);
                    }
                }
                else
                {
                    context.PostData = SocketHelper.Receive(socket, contentLength);
                    success          = true;
                }
            }
            else
            {
                //要求必要的 Content-Length
                if (string.IsNullOrEmpty(context.Content) && context.ContentBuffer == null)
                {
                    context.Content = "Require Content-Length";
                }
                context.Response(HttpStatusCode.LengthRequired);
            }

            return(success);
        }