Ejemplo n.º 1
0
        public void DownloadFile(string remoteFileName, string localFileName)
        {
            if (string.IsNullOrEmpty(localFileName))
            {
                localFileName = Path.GetFileName(remoteFileName.Replace("\\", "/"));
            }

            if (string.IsNullOrEmpty(localFileName))
            {
                return;
            }

            var completeFilePath = Path.Combine(Scanner.Configuration.Proxy.MirrorRoot, VersionName, localFileName);
            var fileDirectory    = Path.GetDirectoryName(completeFilePath);

            if (string.IsNullOrEmpty(fileDirectory))
            {
                return;
            }

            if (!Directory.CreateDirectory(fileDirectory).Exists)
            {
                return;
            }

            if (File.Exists(completeFilePath))
            {
                return;
            }

            var fileEntry = GetEntry(remoteFileName);

            if (fileEntry == null)
            {
                return;
            }

            using (var blte = new BLTE(CDN.Hosts[0]))
            {
                if (fileEntry.ArchiveIndex != -1)
                {
                    blte.AddHeader("Range", $"bytes={fileEntry.Offset}-{fileEntry.Offset + fileEntry.Size - 1}");
                }

                var archiveName = fileEntry.Hash.ToHexString();
                if (fileEntry.ArchiveIndex != -1)
                {
                    archiveName = Indices.Archives[fileEntry.ArchiveIndex].ToHexString();
                }

                blte.Send($"/{CDN.Path}/data/{archiveName.Substring(0, 2)}/{archiveName.Substring(2, 2)}/{archiveName}");

                Scanner.WriteLine($"[{VersionName}] Downloading {localFileName} from {blte.URL} ...");

                using (var fileStream = File.OpenWrite(completeFilePath))
                    blte.PipeTo(fileStream);
            }
        }
Ejemplo n.º 2
0
        private static void Process(HttpListenerContext context)
        {
            var tokens = context.Request.Url.AbsolutePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            if (tokens.Length == 0)
            {
                WriteError(context, "Badly formatted request.", HttpStatusCode.BadRequest);
                return;
            }

            var buildName = tokens[0];
            var fileHash  = ulong.Parse(tokens[1]);
            var fileName  = tokens[2];

            var buildInfo = RemoteBuildManager.GetBuild(buildName);

            if (buildInfo == null)
            {
                WriteError(context, "Unknown build.", HttpStatusCode.BadRequest);
                return;
            }

            var fileEntry = buildInfo.GetEntry(fileHash);

            if (fileEntry == null)
            {
                WriteError(context, "This build is currently loading. Try again later.", HttpStatusCode.BadRequest);
                return;
            }

            try
            {
                using (var blte = new BLTE(buildInfo.CDN.Hosts[0]))
                {
                    if (fileEntry.ArchiveIndex != -1)
                    {
                        blte.AddHeader("Range", $"bytes={fileEntry.Offset}-{fileEntry.Offset + fileEntry.Size - 1}");
                    }

                    var archiveName = fileEntry.Hash.ToHexString();
                    if (fileEntry.ArchiveIndex != -1)
                    {
                        archiveName = buildInfo.Indices.Archives[fileEntry.ArchiveIndex].ToHexString();
                    }

                    blte.Send($"/{buildInfo.CDN.Path}/data/{archiveName.Substring(0, 2)}/{archiveName.Substring(2, 2)}/{archiveName}");

                    Scanner.WriteLine($"[PROXY] Serving {fileName} through {blte.URL}.");

                    if (!blte.Failed)
                    {
                        context.Response.ContentType     = "application/octet-stream";
                        context.Response.ContentLength64 = blte.DecompressedLength;
                        context.Response.AddHeader("Date", blte.ResponseHeaders.Get("Date"));
                        context.Response.AddHeader("ETag", blte.ResponseHeaders.Get("ETag"));
                        context.Response.AddHeader("Last-Modified", DateTime.Now.ToString("r"));
                        context.Response.AddHeader("Connection", "Keep-Alive");

                        context.Response.StatusCode = (int)HttpStatusCode.OK;

                        Scanner.WriteLine($"[PROXY] Serving {fileName} to {context.Request.RemoteEndPoint} - {archiveName}");

                        blte.PipeTo(context.Response.OutputStream);
                    }
                    else
                    {
                        var sBuilder = new StringBuilder();
                        sBuilder.AppendLine($"File {fileName} cannot be downloaded - it might be an encrypted archive...");
                        sBuilder.AppendLine();
                        sBuilder.AppendLine($"Requested archive: {blte.URL}");
                        if (fileEntry.ArchiveIndex != -1)
                        {
                            sBuilder.AppendLine($"Range: {fileEntry.Offset}-{fileEntry.Offset + fileEntry.Size - 1}");
                        }
                        WriteError(context, sBuilder.ToString(), HttpStatusCode.InternalServerError);
                    }
                }
            }
            catch (IOException ioe)
            {
                Scanner.WriteLine("[PROXY] Remote client closed the connection.");
            }
            catch (Exception e)
            {
                Scanner.WriteLine(e.ToString());

                WriteError(context, e.ToString(), HttpStatusCode.InternalServerError);
            }
        }