Ejemplo n.º 1
0
 private bool SingleDownload(string url, string dst)
 {
     try
     {
         using (HttpFileDownloader dl = new HttpFileDownloader())
         {
             dl.Download(url, dst, null);
         }
     }
     catch
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 2
0
        public static List <LogInfo> WebGet(EngineState s, CodeCommand cmd)
        { // WebGet,<URL>,<DestPath>[<HashType>=<HashDigest>][,TimeOut=<Int>][,Referer=<URL>][,UserAgent=<Agent>][,NOERR]
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_WebGet info = cmd.Info.Cast <CodeInfo_WebGet>();

            string url      = StringEscaper.Preprocess(s, info.URL);
            string destPath = StringEscaper.Preprocess(s, info.DestPath);
            int    timeOut  = 10;

            if (info.TimeOut != null)
            {
                string timeOutStr = StringEscaper.Preprocess(s, info.TimeOut);
                if (!NumberHelper.ParseInt32(timeOutStr, out timeOut))
                {
                    return(LogInfo.LogErrorMessage(logs, $"TimeOut [{timeOutStr}] is not a valid positive integer"));
                }
                if (timeOut <= 0)
                {
                    return(LogInfo.LogErrorMessage(logs, $"TimeOut [{timeOutStr}] is not a valid positive integer"));
                }
            }

            string refererUrl = null;

            if (info.Referer != null)
            {
                refererUrl = StringEscaper.Preprocess(s, info.Referer);
            }

            // Check PathSecurity in destPath
            if (!StringEscaper.PathSecurityCheck(destPath, out string pathErrorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, pathErrorMsg));
            }

            Uri    uri = new Uri(url);
            string destFile;

            if (Directory.Exists(destPath))
            {
                destFile = Path.Combine(destPath, Path.GetFileName(uri.LocalPath));
            }
            else // downloadTo is file
            {
                if (File.Exists(destPath))
                {
                    if (cmd.Type == CodeType.WebGetIfNotExist)
                    {
                        logs.Add(new LogInfo(LogState.Ignore, $"File [{destPath}] already exists"));
                        return(logs);
                    }

                    logs.Add(new LogInfo(LogState.Overwrite, $"File [{destPath}] will be overwritten"));
                }
                else
                {
                    Directory.CreateDirectory(FileHelper.GetDirNameEx(destPath));
                }
                destFile = destPath;
            }

            string destFileExt = Path.GetExtension(destFile);

            s.MainViewModel.SetBuildCommandProgress("WebGet Progress");
            try
            {
                // Set User-Agent to use
                // (1) Use Command's custom User-Agent
                // (2) Use EngineState's custom User-Agent
                // (3) Use PEBakery's default User-Agent
                string userAgent = null;
                if (info.UserAgent != null)
                {
                    userAgent = info.UserAgent;
                }
                else
                {
                    userAgent = s.CustomUserAgent;
                }

                if (info.HashType == HashHelper.HashType.None)
                { // Standard WebGet
                    string tempPath = FileHelper.GetTempFile(destFileExt);

                    HttpFileDownloader        downloader = new HttpFileDownloader(s.MainViewModel, timeOut, userAgent, refererUrl);
                    HttpFileDownloader.Report report;
                    try
                    {
                        CancellationTokenSource ct = new CancellationTokenSource();
                        s.CancelWebGet = ct;

                        Task <HttpFileDownloader.Report> task = downloader.Download(url, tempPath, ct.Token);
                        task.Wait(ct.Token);

                        report = task.Result;
                    }
                    catch (Exception e)
                    {
                        report = new HttpFileDownloader.Report(false, 0, Logger.LogExceptionMessage(e));
                    }
                    finally
                    {
                        s.CancelWebGet = null;
                    }

                    int statusCode = report.StatusCode;
                    if (report.Result)
                    {
                        FileHelper.FileReplaceEx(tempPath, destFile);
                        logs.Add(new LogInfo(LogState.Success, $"[{destFile}] downloaded from [{url}]"));
                    }
                    else
                    {
                        LogState state = info.NoErrFlag ? LogState.Warning : LogState.Error;
                        logs.Add(new LogInfo(state, $"Error occured while downloading [{url}]"));
                        logs.Add(new LogInfo(LogState.Info, report.ErrorMsg));
                        if (statusCode == 0)
                        {
                            logs.Add(new LogInfo(LogState.Info, "Request failed, no response received."));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Info, $"Response returned HTTP status code [{statusCode}]"));
                        }
                    }

                    // PEBakery extension -> Report exit code via #r
                    if (!s.CompatDisableExtendedSectionParams)
                    {
                        s.ReturnValue = statusCode.ToString();
                        if (statusCode < 100)
                        {
                            logs.Add(new LogInfo(LogState.Success, $"Returned [{statusCode}] into [#r]"));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Success, $"Returned HTTP status code [{statusCode}] to [#r]"));
                        }
                    }
                }
                else
                { // Validate downloaded file with hash
                    Debug.Assert(info.HashDigest != null);

                    string tempPath = FileHelper.GetTempFile(destFileExt);

                    HttpFileDownloader        downloader = new HttpFileDownloader(s.MainViewModel, timeOut, userAgent, refererUrl);
                    HttpFileDownloader.Report report;
                    try
                    {
                        CancellationTokenSource ct = new CancellationTokenSource();
                        s.CancelWebGet = ct;

                        Task <HttpFileDownloader.Report> task = downloader.Download(url, tempPath, ct.Token);
                        task.Wait(ct.Token);

                        report = task.Result;
                    }
                    catch (Exception e)
                    {
                        report = new HttpFileDownloader.Report(false, 0, Logger.LogExceptionMessage(e));
                    }
                    finally
                    {
                        s.CancelWebGet = null;
                    }

                    int statusCode = report.StatusCode;
                    if (report.Result)
                    { // Success -> Check hash
                        string hashDigest = StringEscaper.Preprocess(s, info.HashDigest);
                        if (hashDigest.Length != 2 * HashHelper.GetHashByteLen(info.HashType))
                        {
                            return(LogInfo.LogErrorMessage(logs, $"Hash digest [{hashDigest}] is not [{info.HashType}]"));
                        }

                        string downDigest;
                        using (FileStream fs = new FileStream(tempPath, FileMode.Open, FileAccess.Read))
                        {
                            byte[] digest = HashHelper.GetHash(info.HashType, fs);
                            downDigest = StringHelper.ToHexStr(digest);
                        }

                        if (hashDigest.Equals(downDigest, StringComparison.OrdinalIgnoreCase)) // Success
                        {
                            FileHelper.FileReplaceEx(tempPath, destFile);
                            logs.Add(new LogInfo(LogState.Success, $"[{destFile}] downloaded from [{url}] and verified "));
                        }
                        else
                        {
                            statusCode = 1; // 1 means hash mismatch
                            logs.Add(new LogInfo(LogState.Error, $"Downloaded file from [{url}] was corrupted"));
                        }
                    }
                    else
                    { // Failure -> Log error message
                        LogState state = info.NoErrFlag ? LogState.Warning : LogState.Error;
                        logs.Add(new LogInfo(state, $"Error occured while downloading [{url}]"));
                        logs.Add(new LogInfo(LogState.Info, report.ErrorMsg));
                        if (statusCode == 0)
                        {
                            logs.Add(new LogInfo(LogState.Info, "Request failed, no response received."));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Info, $"Response returned HTTP Status Code [{statusCode}]"));
                        }
                    }

                    // PEBakery extension -> Report exit code via #r
                    if (!s.CompatDisableExtendedSectionParams)
                    {
                        s.ReturnValue = statusCode.ToString();
                        if (statusCode < 100)
                        {
                            logs.Add(new LogInfo(LogState.Success, $"Returned [{statusCode}] into [#r]"));
                        }
                        else
                        {
                            logs.Add(new LogInfo(LogState.Success, $"Returned HTTP status code [{statusCode}] to [#r]"));
                        }
                    }
                }
            }
            finally
            {
                s.MainViewModel.ResetBuildCommandProgress();
            }

            return(logs);
        }