Пример #1
0
        /// <summary>
        /// This is used to process a client.
        /// </summary>
        /// <param name="directory">The requested directory.</param>
        /// <param name="file">The requested file.</param>
        /// <param name="version">The HTTP version to play back.</param>
        /// <param name="address">The address of the client.</param>
        /// <param name="ns">The transport.</param>
        /// <returns></returns>
        private async Task Process(string directory, string file, string version, string address, Stream ns)
        {
            if (!directory.Contains("..")) //   Only root ('/') is allowed.
            {
                var cleanedPath = GetLocalPath(file, directory);
                if (!(cleanedPath.Contains("players.csv") || cleanedPath.Contains("logs")) &&
                    cleanedPath.Contains("?"))
                {
                    cleanedPath = cleanedPath.Remove(
                        cleanedPath.IndexOf("?", StringComparison.InvariantCultureIgnoreCase),
                        cleanedPath.Length -
                        cleanedPath.IndexOf("?", StringComparison.InvariantCultureIgnoreCase));
                }

                if (File.Exists(cleanedPath))
                {
                    var mimeType = ParseMime(cleanedPath);
                    //COMPARISION : If the file type is supported, move on to the next comparision. If not, send the error.
                    if (mimeType != null)
                    {
                        //COMPARISION : Send client from memory or an unloaded file from the disk.
                        if (cleanedPath.Contains("client.html"))
                        {
                            await WriteDocument(Document, "text/html", ns, version).ConfigureAwait(false);
                        }
                        else
                        {
                            var document = await File.ReadAllBytesAsync(cleanedPath).ConfigureAwait(false);
                            await WriteDocument(document, mimeType, ns, version).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        await WriteDocument(DocumentTypeNotSupported, "text/html", ns, version, StatusCodes.NotImplemented501).ConfigureAwait(false);
                    }
                }
                else
                {
                    List <string> handlers;
                    lock (InvalidPageHandlers) handlers = InvalidPageHandlers.ToList();
                    if (cleanedPath.Contains("players.csv") && cleanedPath.Contains('?'))
                    {
                        var key = cleanedPath.Substring(cleanedPath.IndexOf('?') + 1);
                        if (ApiServer.CheckKey(key))
                        {
                            var response = Encoding.UTF8.GetBytes(MainClass.CompilePlayers());
                            await WriteDocument(response, "text/csv", ns, version).ConfigureAwait(false);
                        }
                        else
                        {
                            var data = Encoding.UTF8.GetBytes("<h1>You have entered an invalid key. Please stop trying to break into our system!</h1>");
                            await WriteDocument(data, "text/html", ns, version).ConfigureAwait(false);
                        }
                    }
                    else if (cleanedPath.Contains("logs.csv") && cleanedPath.Contains('?'))
                    {
                        var requestData = cleanedPath.Substring(cleanedPath.IndexOf('?') + 1).Split('&');
                        if (requestData.Length == 2 && !string.IsNullOrEmpty(requestData[0]) &&
                            !string.IsNullOrEmpty(requestData[1]))
                        {
                            var key = requestData[0];
                            if (!ApiServer.CheckKey(key))
                            {
                                var data = Encoding.UTF8.GetBytes(
                                    "<h1>You have entered an invalid key. Please stop trying to break into our system!</h1>");
                                await WriteHeader(version, "text/html", data.Length, " 200 OK", ns).ConfigureAwait(false);

                                await ns.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
                            }
                            else
                            {
                                var requestedLog = Path.Combine("hqlogs",
                                                                Path.GetFileNameWithoutExtension(requestData[1]) + ".self");
                                var logs = MainClass.LogManager.GetLogNames();
                                if (!logs.Contains(requestedLog))
                                {
                                    var data = Encoding.UTF8.GetBytes(
                                        "<h1>Could not find the logs you requested.</h1>");
                                    await WriteHeader(version, "text/html", data.Length, " 404 Not Found", ns).ConfigureAwait(false);

                                    await ns.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
                                }
                                else
                                {
                                    byte[] data;
                                    using (FileStream fs = new FileStream(requestedLog, FileMode.Open,
                                                                          FileAccess.Read, FileShare.ReadWrite))
                                    {
                                        //we don't want to read while it is writing.
                                        lock (MainClass.LogManager.FileLock)
                                        {
                                            data = new byte[fs.Length];
                                            fs.Read(data, 0, (int)fs.Length);
                                        }
                                    }

                                    //i am not doing it directly off the stream so i don't lock the manager for too long...
                                    //should not be a problem, logs will be quite small.
                                    var logData = GetCsv(data);
                                    await WriteHeader(version, "text/csv", logData.Length, " 200 OK", ns).ConfigureAwait(false);

                                    await ns.WriteAsync(logData, 0, logData.Length).ConfigureAwait(false);
                                }
                            }
                        }
                    }
                    else if (handlers.Contains(cleanedPath))
                    {
                        OnSpecialHandlerInvoked?.Invoke(
                            cleanedPath.Replace("dashboard\\", "").Replace("dashboard/", ""), ns, version,
                            address);
                    }
                    else
                    {
                        await WriteHeader(version, "text/html", Document404Error.Length, " 404 Not Found", ns).ConfigureAwait(false);

                        await ns.WriteAsync(Document404Error, 0, Document404Error.Length).ConfigureAwait(false);
                    }
                }
            }
            else
            {
                await WriteHeader(version, "text/html", Document404Error.Length, " 404 Not Found", ns).ConfigureAwait(false);

                await ns.WriteAsync(Document404Error, 0, Document404Error.Length).ConfigureAwait(false);
            }
        }