コード例 #1
0
ファイル: ViewServer.cs プロジェクト: AutoCSer/AutoCSer
        /// <summary>
        /// 加载 HTTP 调用[TRY]
        /// </summary>
        /// <typeparam name="callType"></typeparam>
        /// <param name="socket">HTTP套接字接口</param>
        /// <param name="call">HTTP 调用</param>
        /// <param name="callInfo">HTTP 调用函数信息</param>
        protected void loadAsynchronous <callType>(Http.SocketBase socket, callType call, AutoCSer.WebView.CallMethodInfo callInfo)
            where callType : AutoCSer.WebView.CallAsynchronous <callType>
        {
            Http.Header header = socket.HttpHeader;
            if (header.ContentLength <= callInfo.MaxPostDataSize && (header.Method == Http.MethodType.POST || !callInfo.IsOnlyPost))
            {
                call.LoadHeader(this, socket, call, callInfo);
                if (header.Method == Http.MethodType.POST && header.ContentLength != 0)
                {
                    socket.GetForm(call, Http.GetFormType.CallAsynchronous);
                    return;
                }
                long socketIdentity = socket.Identity;
                if (this.call(call))
                {
                    return;
                }
                call.PushPool();
                socket.ResponseError(socketIdentity, Http.ResponseState.ServerError500);
            }
            else
            {
                AutoCSer.WebView.CallAsynchronous <callType> .PushNotNull(call);

                socket.ResponseErrorIdentity(Http.ResponseState.ServerError500);
            }
        }
コード例 #2
0
ファイル: ViewServer.cs プロジェクト: AutoCSer/AutoCSer
 /// <summary>
 /// 加载web调用
 /// </summary>
 /// <param name="socket">HTTP套接字接口</param>
 /// <param name="call">web调用</param>
 /// <param name="callInfo">HTTP 调用函数信息</param>
 protected void load(Http.SocketBase socket, AutoCSer.WebView.Call call, AutoCSer.WebView.CallMethodInfo callInfo)
 {
     Http.Header header = socket.HttpHeader;
     if (header.ContentLength <= callInfo.MaxPostDataSize && (header.Method == Http.MethodType.POST || !callInfo.IsOnlyPost))
     {
         call.LoadHeader(this, socket, callInfo);
         if (header.Method == Http.MethodType.POST && header.ContentLength != 0)
         {
             socket.GetForm(call, Http.GetFormType.Call);
             return;
         }
         long socketIdentity = socket.Identity;
         if (this.callSynchronize(call))
         {
             return;
         }
         socket.ResponseError(socketIdentity, Http.ResponseState.ServerError500);
     }
     else
     {
         socket.ResponseErrorIdentity(Http.ResponseState.ServerError500);
     }
 }
コード例 #3
0
        /// <summary>
        /// HTTP文件请求处理
        /// </summary>
        /// <param name="header">请求头部信息</param>
        /// <param name="fileCache">文件输出信息</param>
        /// <param name="response">HTTP响应</param>
        protected unsafe void file(Http.Header header, FileCache fileCache, ref Http.Response response)
        {
            Http.HeaderFlag headerFlag = header.Flag;
            if (fileCache == null)
            {
                if (response != null)
                {
                    if (response.Type == Http.ResponseType.File)
                    {
                        if ((headerFlag & Http.HeaderFlag.IsRange) != 0 && !header.FormatRange(response.BodySize))
                        {
                            response = Http.Response.RangeNotSatisfiable416;
                            return;
                        }
                        if ((headerFlag & Http.HeaderFlag.IsVersion) != 0 || isStaticFileCacheControl(header.Path))
                        {
                            response.CacheControl = AutoCSer.Net.Http.Response.StaticFileCacheControl;
                        }
                    }
                    if ((response.Flag & Http.ResponseFlag.IsPool) != 0 && (headerFlag & Http.HeaderFlag.IsSetOrigin) != 0 && this.isOrigin(header.Origin, (headerFlag & Http.HeaderFlag.IsSsl) != 0))
                    {
                        response.SetAccessControlAllowOrigin(header.OriginIndex);
                    }
                }
                return;
            }
            if ((headerFlag & Http.HeaderFlag.IsRange) != 0 && !header.FormatRange(fileCache.Data.Length))
            {
                response = Http.Response.RangeNotSatisfiable416;
                return;
            }
            byte[] cacheControl = (headerFlag & Http.HeaderFlag.IsVersion) != 0 || isStaticFileCacheControl(header.Path) ? AutoCSer.Net.Http.Response.StaticFileCacheControl : this.cacheControl;
            bool   isOrigin = (headerFlag & Http.HeaderFlag.IsSetOrigin) != 0 && this.isOrigin(header.Origin, (headerFlag & Http.HeaderFlag.IsSsl) != 0), isHeader = !isOrigin && (headerFlag & Http.HeaderFlag.IsRange) == 0 && FileCacheQueue.IsFileCacheHeader;

            if (isHeader && (response = (headerFlag & Http.HeaderFlag.IsGZip) == 0 ? fileCache.Response : fileCache.GZipResponse) != null && response.IsCacheControl(cacheControl))
            {
                return;
            }
            SubArray <byte> body = (headerFlag & Http.HeaderFlag.IsGZip) != 0 && (headerFlag & Http.HeaderFlag.IsRange) == 0 ? fileCache.GZipData : fileCache.Data;

            response = Http.Response.Get();
            //response.State = Http.ResponseState.Ok200;
            if (isHeader && body.Start == FileCache.HttpHeaderSize)
            {
                response.SetCanHeaderSize(ref body);
            }
            else
            {
                response.SetBody(ref body);
            }
            response.CacheControl = cacheControl;
            response.ContentType  = fileCache.ContentType;
            if (body.Array != fileCache.Data.Array)
            {
                response.SetContentEncoding(Http.Response.GZipEncoding);
            }
            response.SetLastModified(fileCache.LastModified);
            if (isOrigin)
            {
                response.SetAccessControlAllowOrigin(header.OriginIndex);
            }
            return;
        }
コード例 #4
0
        /// <summary>
        /// HTTP文件请求处理
        /// </summary>
        /// <param name="header">请求头部</param>
        /// <param name="response">HTTP响应输出</param>
        /// <returns>文件缓存</returns>
        protected unsafe FileCache file(Http.Header header, ref Http.Response response)
        {
            SubArray <byte> path          = header.Path;
            string          cacheFileName = null;

            try
            {
                if (path.Length != 0 && WorkPath.Length + path.Length <= AutoCSer.IO.File.MaxFullNameLength)
                {
                    byte[] contentType = null;
                    bool   isCompress  = true;
                    fixed(byte *pathFixed = path.Array)
                    {
                        byte *pathStart = pathFixed + path.Start, pathEnd = pathStart + path.Length;

                        if (isFile(pathEnd, ref contentType, ref isCompress) == 0)
                        {
                            if (*pathStart == '/')
                            {
                                ++pathStart;
                            }
                            for (byte *formatStart = pathStart; formatStart != pathEnd; ++formatStart)
                            {
                                if (*formatStart == ':')
                                {
                                    response = Http.Response.Blank;
                                    return(null);
                                }
#if !MONO
                                if ((uint)(*formatStart - 'A') < 26)
                                {
                                    *formatStart |= 0x20;
                                }
#endif
                            }
                            int          cachePathLength = (int)(pathEnd - pathStart);
                            FileCacheKey cacheKey        = new FileCacheKey(pathIdentity, path.Array, (int)(pathStart - pathFixed), cachePathLength);
                            FileCache    fileCache       = FileCacheQueue.Get(ref cacheKey);
                            if (fileCache == null)
                            {
                                cacheFileName = StringExtension.FastAllocateString(WorkPath.Length + cachePathLength);
                                fixed(char *nameFixed = cacheFileName)
                                {
                                    char *write = nameFixed + WorkPath.Length;
                                    char  directorySeparatorChar = Path.DirectorySeparatorChar;

                                    StringExtension.CopyNotNull(WorkPath, nameFixed);
                                    for (byte *start = pathStart; start != pathEnd; ++start)
                                    {
                                        *write++ = *start == '/' ? directorySeparatorChar : (char)*start;
                                    }
                                }
                                FileInfo file = new FileInfo(cacheFileName);
                                if (file.Exists)
                                {
                                    string fileName = file.FullName;
                                    if (fileName.Length > WorkPath.Length && WorkPath.equalCaseNotNull(fileName, WorkPath.Length))
                                    {
                                        if (fileName.Length <= AutoCSer.IO.File.MaxFullNameLength && file.Length <= FileCacheQueue.MaxFileSize)
                                        {
                                            if (FileCacheQueue.Get(ref cacheKey, out fileCache, true) != 0)
                                            {
                                                try
                                                {
                                                    fileCache.LastModified = file.LastWriteTimeUtc.UniversalNewBytes();
                                                    int             extensionNameLength = (int)(pathEnd - getExtensionNameStart(pathEnd));
                                                    SubArray <byte> fileData            = readCacheFile(new SubString {
                                                        String = fileName, Start = fileName.Length - extensionNameLength, Length = extensionNameLength
                                                    });
                                                    FileCacheQueue.Set(ref cacheKey, fileCache, fileCache.Set(ref fileData, contentType, cacheControl, isCompress));
                                                    if ((header.Flag & Http.HeaderFlag.IsSetIfModifiedSince) != 0 && header.IfModifiedSinceIndex.Length == fileCache.LastModified.Length)
                                                    {
                                                        if (Memory.EqualNotNull(fileCache.LastModified, pathFixed + header.Buffer.StartIndex + header.IfModifiedSinceIndex.StartIndex, header.IfModifiedSinceIndex.Length))
                                                        {
                                                            response = Http.Response.NotChanged304;
                                                            return(null);
                                                        }
                                                    }
                                                }
                                                finally
                                                {
                                                    if (fileCache.IsData == 0)
                                                    {
                                                        fileCache.PulseAll();
                                                        fileCache = null;
                                                        FileCacheQueue.RemoveOnly(ref cacheKey);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((header.Flag & Http.HeaderFlag.IsSetIfModifiedSince) != 0 && header.IfModifiedSinceIndex.Length == Date.ToByteLength && Date.UniversalByteEquals(file.LastWriteTimeUtc, header.IfModifiedSince) == 0)
                                            {
                                                response = Http.Response.NotChanged304;
                                                return(null);
                                            }
                                            response = Http.Response.Get();
                                            //response.State = Http.ResponseState.Ok200;
                                            response.SetBodyFile(file);
                                            response.CacheControl = cacheControl;
                                            response.ContentType  = contentType;
                                            response.SetLastModified(file.LastWriteTimeUtc.UniversalNewBytes());
                                            return(null);
                                        }
                                    }
                                }
                            }
                            return(fileCache);
                        }
                    }
                }
            }
            catch (Exception error)
            {
                RegisterServer.TcpServer.Log.Add(AutoCSer.Log.LogType.Error, error, cacheFileName);
            }
            return(null);
        }
コード例 #5
0
 protected Http.Response file(Http.Header header)
 {
     Http.Response response = null;
     file(header, file(header, ref response), ref response);
     return(response);
 }
コード例 #6
0
ファイル: ViewServer.cs プロジェクト: AutoCSer/AutoCSer
        /// <summary>
        /// HTTP请求处理[TRY]
        /// </summary>
        /// <param name="socket">HTTP套接字</param>
        public override unsafe void Request(Http.SocketBase socket)
        {
            Http.Header     header = socket.HttpHeader;
            SubArray <byte> path   = header.Path;
            int             index;

            if (header.IsSearchEngine == 0)
            {
                byte[] rewritePath;
#if !MONO
                if (WebConfigIgnoreCase)
                {
                    if ((index = callSearcher.SearchLower(ref path)) >= 0)
                    {
                        call(index, socket);
                        return;
                    }
                    rewritePath = rewritePaths.GetLower(ref path);
                }
                else
#endif
                {
                    if ((index = callSearcher.Search(ref path)) >= 0)
                    {
                        call(index, socket);
                        return;
                    }
                    rewritePath = rewritePaths.Get(ref path);
                }
                if (rewritePath != null)
                {
                    Http.Response response = null;
                    file(header, file(rewritePath, (header.Flag & Http.HeaderFlag.IsSetIfModifiedSince) == 0 ? new SubArray <byte>() : header.IfModifiedSince, ref response, false), ref response);
                    if (response != null)
                    {
                        socket.ResponseIdentity(ref response);
                        return;
                    }
                    socket.ResponseErrorIdentity(Http.ResponseState.NotFound404);
                }
            }
            else
            {
#if !MONO
                if (WebConfigIgnoreCase)
                {
                    if ((index = rewriteSearcher.SearchLower(ref path)) >= 0)
                    {
                        request(index, socket);
                        return;
                    }
                    if ((index = viewSearcher.SearchLower(ref path)) >= 0)
                    {
                        request(index, socket);
                        return;
                    }
                    if ((index = callSearcher.SearchLower(ref path)) >= 0)
                    {
                        call(index, socket);
                        return;
                    }
                }
                else
#endif
                {
                    if ((index = rewriteSearcher.Search(ref path)) >= 0)
                    {
                        request(index, socket);
                        return;
                    }
                    if ((index = viewSearcher.Search(ref path)) >= 0)
                    {
                        request(index, socket);
                        return;
                    }
                    if ((index = callSearcher.Search(ref path)) >= 0)
                    {
                        call(index, socket);
                        return;
                    }
                }
            }
            if (beforeFile(socket))
            {
                base.Request(socket);
            }
        }
コード例 #7
0
        private void ConnectServer()
        {
            Task.Factory.StartNew(async () =>
            {
                try
                {
                    DataReader stream = new DataReader(this._socket.InputStream);

                    // Read HTTP request line.
                    string startLine = await this.ReadLine(stream);
                    if (startLine == null)
                    {
                        throw new Exception("Cannot read HTTP request start line");
                    }

                    Http.RequestLine requestLine = new Http.RequestLine(startLine);
                    this._uri = new Uri(requestLine.RequestURI); // can be checked in
                    // onConnect()

                    // Read HTTP response headers
                    Dictionary<string, string> map = new Dictionary<string, string>();
                    string line;
                    while ((line = await this.ReadLine(stream)) != null && line.Length > 0)
                    {
                        Http.Header header = new Http.Header(line);
                        map.Add(header.HeaderName.ToLower(), header.HeaderValue);
                    }

                    string value = map["sec-websocket-version"];
                    if (!"13".Equals(value))
                        throw new IOException("wrong Sec-WebSocket-Version");

                    string key = map["sec-websocket-key"];
                    if (key == null)
                        throw new IOException("missed Sec-WebSocket-Key");
                    string accept = CreateAccept(key);

                    string upgrade = map["upgrade"];
                    if (upgrade == null || !upgrade.Equals("websocket", StringComparison.OrdinalIgnoreCase))
                        throw new IOException("wrong Upgrade");

                    string connection = map["connection"];
                    if (connection == null || !connection.Equals("upgrade", StringComparison.OrdinalIgnoreCase))
                        throw new IOException("wrong Connection");

                    // Host and Origin can be checked later in onConnect() callback.
                    this._host = map["host"];
                    if (this._host == null)
                        throw new IOException("Missed 'Host' header");

                    this._origin = map["origin"];
                    if (this._origin == null)
                        throw new IOException("Missed 'Origin' header");

                    // Some naive protocol selection.
                    string protocols = map["sec-websocket-protocol"];
                    string selectedProtocol = null;
                    if (protocols != null && protocols.Contains("chat"))
                        selectedProtocol = "chat";

                    DataWriter writer = new DataWriter(this._socket.OutputStream);
                    writer.WriteString("HTTP/1.1 101 Switching Protocols\r\n");
                    writer.WriteString("Upgrade: websocket\r\n");
                    writer.WriteString("Connection: Upgrade\r\n");
                    writer.WriteString("Sec-WebSocket-Accept: " + accept + "\r\n");
                    if (selectedProtocol != null)
                        writer.WriteString("Sec-WebSocket-Protocol: " + selectedProtocol + "\r\n");
                    writer.WriteString("\r\n");
                    await writer.FlushAsync();

                    if (this.Opened != null)
                    {
                        this.Opened(this, EventArgs.Empty);
                    }

                    // Read & process frame
                    for (; ; )
                    {
                        FrameParser.Frame frame = await FrameParser.ReadFrame(stream);
                        await this.ProcessIncomingFrame(frame);
                    }
                }
                catch (IOException ex)
                {
                    if (this.Closed != null)
                    {
                        this.Closed(this, new WebSocketClosedEventArgs(0, "EOF"));
                    }
                }
                catch (Exception ex)
                {
                    if (this.Closed != null)
                    {
                        this.Closed(this, new WebSocketClosedEventArgs(0, "Exception"));
                    }
                }
                finally
                {
                    this.Disconnect();
                }
            });
        }
コード例 #8
0
ファイル: WebSocket.cs プロジェクト: mixedworld/WebSocket.UWP
        private async Task ConnectClientInternal()
        {
            if (_socket != null)
            {
                throw new Exception("connect() is already called");
            }
            try
            {
                int    port = (_uri.Port != -1) ? _uri.Port : (_uri.Scheme.Equals("wss") ? 443 : 80);
                string path = (_uri.AbsolutePath != null) ? _uri.AbsolutePath : "/";
                if (_uri.Query != null)
                {
                    path += "?" + _uri.Query;
                }
                string originScheme = _uri.Scheme.Equals("wss") ? "https" : "http";
                Uri    origin       = new Uri(originScheme + "://" + _uri.Host);
                // To fix: get Origin from extraHeaders if set there.
                this._socket = new InternalSocket();
                await this._socket.ConnectAsync(_uri.Host, port);

                if (_uri.Scheme.Equals("wss"))
                {
                    await this._socket.UpgradeToSslAsync(_uri.Host);
                }
                string     key    = WebSocketHelper.CreateClientKey();
                DataWriter writer = new DataWriter(_socket.OutputStream);
                writer.WriteString("GET " + path + " HTTP/1.1\r\n");
                writer.WriteString("Upgrade: websocket\r\n");
                writer.WriteString("Connection: Upgrade\r\n");
                writer.WriteString("Host: " + _uri.Host + "\r\n");
                writer.WriteString("Origin: " + origin.ToString() + "\r\n");
                writer.WriteString("Sec-WebSocket-Key: " + key + "\r\n");
                writer.WriteString("Sec-WebSocket-Version: 13\r\n");
                if (_extraRequestHeaders != null)
                {
                    foreach (Http.Header header in _extraRequestHeaders)
                    {
                        writer.WriteString(header.ToString() + "\r\n");
                    }
                }
                writer.WriteString("\r\n");
                await writer.StoreAsync(); //异步发送数据

                writer.DetachStream();     //分离
                writer.Dispose();          //结束writer
                DataReader reader = new DataReader(_socket.InputStream);
                reader.ByteOrder = ByteOrder.LittleEndian;
                //// Read HTTP response status line.
                var startLine = await ReadLine(reader);

                if (startLine == null)
                {
                    throw new Exception("Received no reply from server.");
                }
                Http.StatusLine statusLine = new Http.StatusLine(startLine);
                int             statusCode = statusLine.StatusCode;
                if (statusCode != 101)
                {
                    throw new Exception("wrong HTTP response code: " + statusCode);
                }

                // Read HTTP response headers.
                string line;
                while ((line = await ReadLine(reader)) != null && line.Length > 0)
                {
                    Http.Header header = new Http.Header(line);
                    Debug.WriteLine(line);

                    if (header.HeaderName.Equals("Sec-WebSocket-Accept", StringComparison.OrdinalIgnoreCase))
                    {
                        string receivedAccept = header.HeaderValue;
                        string shouldBeAccept = WebSocketHelper.CreateAccept(key);
                        if (!receivedAccept.Equals(shouldBeAccept))
                        {
                            throw new Exception("Wrong Sec-WebSocket-Accept: " + receivedAccept + " should be: " + shouldBeAccept);
                        }
                    }
                    if (_serverResponseHeaders == null)
                    {
                        _serverResponseHeaders = new List <Http.Header>();
                    }
                    _serverResponseHeaders.Add(header);
                }
                if (this.Opened != null)
                {
                    this.Opened(this, EventArgs.Empty);
                }
                //Upgrade: websocket
                //Connection: Upgrade
                //Sec-WebSocket-Accept: 1xY289lHcEMbLpEBgOYRBBL9N9c=
                //Sec-WebSocket-Protocol: chat
                //Content-Type: application/octet-stream
                //Seq-Id: 667035124
                // Read & process frame
                while (true)
                {
                    FrameParser.Frame frame = await FrameParser.ReadFrame(reader);

                    if (frame != null)
                    {
                        await ProcessIncomingFrame(frame);
                    }
                }
            }
            catch (IOException ex)
            {
                if (this.Closed != null)
                {
                    this.Closed(this, new WebSocketClosedEventArgs(0, "EOF"));
                }
            }
            catch (Exception ex)
            {
                if (this.Closed != null)
                {
                    this.Closed(this, new WebSocketClosedEventArgs(0, ex.Message));
                }
            }
            finally
            {
                Disconnect();
            }
        }
コード例 #9
0
ファイル: WebSocket.cs プロジェクト: rwecho/WebSocket.UWP
        private async Task ConnectClientInternal()
        {
            if (_socket != null)
            {
                throw new Exception("connect() is already called");
            }

            await Task.Factory.StartNew(async () =>
                  {

                      try
                      {
                          int port = (_uri.Port != -1) ? _uri.Port : (_uri.Scheme.Equals("wss") ? 443 : 80);
                          string path = (_uri.AbsolutePath != null) ? _uri.AbsolutePath : "/";
                          if (_uri.Query != null)
                          {
                              path += "?" + _uri.Query;
                          }
                          string originScheme = _uri.Scheme.Equals("wss") ? "https" : "http";
                          Uri origin = new Uri(originScheme + "://" + _uri.Host);
                          // To fix: get Origin from extraHeaders if set there.
                          this._socket = new InternalSocket();
                          await this._socket.ConnectAsync(_uri.Host, port);
                          if (_uri.Scheme.Equals("wss"))
                          {
                              await this._socket.UpgradeToSslAsync(_uri.Host);
                          }
                          string key = CreateSecKey();
                          DataWriter writer = new DataWriter(_socket.OutputStream);
                          writer.WriteString("GET " + path + " HTTP/1.1\r\n");
                          writer.WriteString("Upgrade: websocket\r\n");
                          writer.WriteString("Connection: Upgrade\r\n");
                          writer.WriteString("Host: " + _uri.Host + "\r\n");
                          writer.WriteString("Origin: " + origin.ToString() + "\r\n");
                          writer.WriteString("Sec-WebSocket-Key: " + key + "\r\n");
                          writer.WriteString("Sec-WebSocket-Version: 13\r\n");

                          if (_extraRequestHeaders != null)
                          {
                              foreach (Http.Header header in _extraRequestHeaders)
                              {
                                  writer.WriteString(header.ToString() + "\r\n");
                              }
                          }
                          writer.WriteString("\r\n");
                          await writer.StoreAsync();  //异步发送数据
                          writer.DetachStream();  //分离
                          writer.Dispose();  //结束writer
                          DataReader reader = new DataReader(_socket.InputStream);
                          reader.ByteOrder = ByteOrder.LittleEndian;
                          //// Read HTTP response status line.
                          var startLine = await ReadLine(reader);
                          if (startLine == null)
                          {
                              throw new Exception("Received no reply from server.");
                          }
                          Http.StatusLine statusLine = new Http.StatusLine(startLine);
                          int statusCode = statusLine.StatusCode;
                          if (statusCode != 101)
                          {
                              throw new Exception("wrong HTTP response code: " + statusCode);
                          }

                          // Read HTTP response headers.
                          string line;
                          while ((line = await ReadLine(reader)) != null && line.Length > 0)
                          {
                              Http.Header header = new Http.Header(line);
                              Debug.WriteLine(line);

                              if (header.HeaderName.Equals("Sec-WebSocket-Accept", StringComparison.OrdinalIgnoreCase))
                              {
                                  string receivedAccept = header.HeaderValue;
                                  string shouldBeAccept = CreateAccept(key);
                                  if (!receivedAccept.Equals(shouldBeAccept))
                                      throw new Exception("Wrong Sec-WebSocket-Accept: " + receivedAccept + " should be: " + shouldBeAccept);
                              }
                              if (_serverResponseHeaders == null)
                              {
                                  _serverResponseHeaders = new List<Http.Header>();
                              }
                              _serverResponseHeaders.Add(header);

                          }
                          if (this.Opened != null)
                          {
                              this.Opened(this, EventArgs.Empty);
                          }
                          //Upgrade: websocket
                          //Connection: Upgrade
                          //Sec-WebSocket-Accept: 1xY289lHcEMbLpEBgOYRBBL9N9c=
                          //Sec-WebSocket-Protocol: chat
                          //Content-Type: application/octet-stream
                          //Seq-Id: 667035124
                          // Read & process frame
                          while (true)
                          {
                              FrameParser.Frame frame = await FrameParser.ReadFrame(reader);

                              if (frame != null)
                              {
                                  await ProcessIncomingFrame(frame);
                              }

                          }
                      }
                      catch (IOException ex)
                      {
                          if (this.Closed != null)
                          {
                              this.Closed(this, new WebSocketClosedEventArgs(0, "EOF"));
                          }
                      }
                      catch (Exception ex)
                      {
                          if (this.Closed != null)
                          {
                              this.Closed(this, new WebSocketClosedEventArgs(0, "Exception"));
                          }
                      }
                      finally
                      {
                          Disconnect();
                      }

                  });
        }
コード例 #10
0
        /// <summary>
        /// HTTP请求处理[TRY]
        /// </summary>
        /// <param name="socket">HTTP套接字</param>
        public override unsafe void Request(Http.SocketBase socket)
        {
            Http.Header header = socket.HttpHeader;
            if (((uint)header.ContentLength | (uint)header.IsBoundary) == 0)
            {
                Http.Response            response = Http.Response.Get();
                SubBuffer.PoolBufferFull buffer   = header.Buffer;
                byte[]      domain = socket.IsSsl ? sslLocationDomain : locationDomain, bufferArray = buffer.Buffer;
                BufferIndex uri    = header.UriIndex;
                int         length = domain.Length + uri.Length;
                if (uri.Length != 0)
                {
                    if (bufferArray[buffer.StartIndex + uri.StartIndex] == '/')
                    {
                        uri.Next();
                        if (uri.Length == 0)
                        {
                            goto END;
                        }
                        --length;
                    }
                    if (length <= header.HeaderEndIndex)
                    {
                        int startIndex = uri.StartIndex - domain.Length;
                        if (startIndex >= 0)
                        {
                            Buffer.BlockCopy(domain, 0, bufferArray, startIndex += buffer.StartIndex, domain.Length);
                            response.SetLocation(bufferArray, startIndex, length, locationState);
                        }
                        else
                        {
                            Buffer.BlockCopy(bufferArray, buffer.StartIndex + uri.StartIndex, bufferArray, buffer.StartIndex + domain.Length, uri.Length);
                            Buffer.BlockCopy(domain, 0, bufferArray, buffer.StartIndex, domain.Length);
                            response.SetLocation(bufferArray, buffer.StartIndex, length, locationState);
                        }
                        socket.ResponseIdentity(ref response);
                        return;
                        //int endIndex = uri.EndIndex;
                        //if (header.HeaderEndIndex - endIndex - 7 >= length)
                        //{
                        //    fixed (byte* bufferFixed = bufferArray)
                        //    {
                        //        byte* bufferStart = bufferFixed + buffer.StartIndex, write = bufferStart + endIndex;
                        //        Memory.SimpleCopyNotNull64(domain, write, domain.Length);
                        //        Memory.SimpleCopyNotNull64(bufferStart + uri.StartIndex, write + domain.Length, uri.Length);
                        //    }
                        //    response.SetLocation(bufferArray, buffer.StartIndex + endIndex, length, locationState);
                        //    socket.Response(socketIdentity, ref response);
                        //    return;
                        //}
                    }
                }
END:
                response.SetLocation(domain, locationState);
                socket.ResponseIdentity(ref response);
            }
            else
            {
                socket.ResponseErrorIdentity(Http.ResponseState.BadRequest400);
            }
        }
コード例 #11
0
        private void ConnectServer()
        {
            Task.Factory.StartNew(async() =>
            {
                try
                {
                    DataReader stream = new DataReader(this._socket.InputStream);

                    // Read HTTP request line.
                    string startLine = await this.ReadLine(stream);
                    if (startLine == null)
                    {
                        throw new Exception("Cannot read HTTP request start line");
                    }

                    Http.RequestLine requestLine = new Http.RequestLine(startLine);
                    this._uri = new Uri(requestLine.RequestURI); // can be checked in
                    // onConnect()

                    // Read HTTP response headers
                    Dictionary <string, string> map = new Dictionary <string, string>();
                    string line;
                    while ((line = await this.ReadLine(stream)) != null && line.Length > 0)
                    {
                        Http.Header header = new Http.Header(line);
                        map.Add(header.HeaderName.ToLower(), header.HeaderValue);
                    }

                    string value = map["sec-websocket-version"];
                    if (!"13".Equals(value))
                    {
                        throw new IOException("wrong Sec-WebSocket-Version");
                    }

                    string key = map["sec-websocket-key"];
                    if (key == null)
                    {
                        throw new IOException("missed Sec-WebSocket-Key");
                    }
                    string accept = WebSocketHelper.CreateAccept(key);

                    string upgrade = map["upgrade"];
                    if (upgrade == null || !upgrade.Equals("websocket", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new IOException("wrong Upgrade");
                    }

                    string connection = map["connection"];
                    if (connection == null || !connection.Equals("upgrade", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new IOException("wrong Connection");
                    }

                    // Host and Origin can be checked later in onConnect() callback.
                    this._host = map["host"];
                    if (this._host == null)
                    {
                        throw new IOException("Missed 'Host' header");
                    }

                    this._origin = map["origin"];
                    if (this._origin == null)
                    {
                        throw new IOException("Missed 'Origin' header");
                    }

                    // Some naive protocol selection.
                    string protocols        = map["sec-websocket-protocol"];
                    string selectedProtocol = null;
                    if (protocols != null && protocols.Contains("chat"))
                    {
                        selectedProtocol = "chat";
                    }

                    DataWriter writer = new DataWriter(this._socket.OutputStream);
                    writer.WriteString("HTTP/1.1 101 Switching Protocols\r\n");
                    writer.WriteString("Upgrade: websocket\r\n");
                    writer.WriteString("Connection: Upgrade\r\n");
                    writer.WriteString("Sec-WebSocket-Accept: " + accept + "\r\n");
                    if (selectedProtocol != null)
                    {
                        writer.WriteString("Sec-WebSocket-Protocol: " + selectedProtocol + "\r\n");
                    }
                    writer.WriteString("\r\n");
                    await writer.FlushAsync();

                    if (this.Opened != null)
                    {
                        this.Opened(this, EventArgs.Empty);
                    }

                    // Read & process frame
                    for (;;)
                    {
                        FrameParser.Frame frame = await FrameParser.ReadFrame(stream);
                        await this.ProcessIncomingFrame(frame);
                    }
                }
                catch (IOException ex)
                {
                    if (this.Closed != null)
                    {
                        this.Closed(this, new WebSocketClosedEventArgs(0, "EOF"));
                    }
                }
                catch (Exception ex)
                {
                    if (this.Closed != null)
                    {
                        this.Closed(this, new WebSocketClosedEventArgs(0, "Exception"));
                    }
                }
                finally
                {
                    this.Disconnect();
                }
            });
        }