コード例 #1
0
            private RenderingResult RenderUrlImpl(HttpCookie[] cookies, string url, string outputImageFilePath, string mode)
            {
                Verify.ArgumentNotNull(cookies, nameof(cookies));

                string cookieDomain = new Uri(url).Host;
                string cookieInfo = string.Join(",",
                    cookies.Select(cookie => cookie.Name + "," + cookie.Value + "," + cookieDomain));

                string requestLine = cookieInfo + ";" + url + ";" + outputImageFilePath + ";" + mode;

                // Async way:
                //Task<string> readerTask = Task.Run(async () =>
                //{
                //    await _stdin.WriteLineAsync(requestLine);
                //    return await _stdout.ReadLineAsync();
                //});

                Task<string> readerTask = Task.Run(() =>
                {
                    _stdin.WriteLine(requestLine);
                    return _stdout.ReadLine();
                });

                double timeout = (DateTime.Now - _process.StartTime).TotalSeconds < 120 ? 65 : 30;

                readerTask.Wait(TimeSpan.FromSeconds(timeout));

                string output;

                switch (readerTask.Status)
                {
                    case TaskStatus.RanToCompletion:
                        output = readerTask.Result;
                        break;
                    default:
                        return new RenderingResult
                        {
                            Status = RenderingResultStatus.PhantomServerTimeout,
                            Output = "Request failed to complete within expected time: " +
#if DEBUG
                                requestLine
#else
                                url + " " + mode
#endif
                        };
                }

                if (C1File.Exists(outputImageFilePath))
                {
                    return new RenderingResult 
                    { 
                        Status = RenderingResultStatus.Success, 
                        Output = output,
                        FilePath = outputImageFilePath
                    };
                }

                const string redirectResponsePrefix = "REDIRECT: ";
                if (output.StartsWith(redirectResponsePrefix))
                {
                    return new RenderingResult
                    {
                        Status = RenderingResultStatus.Redirect,
                        Output = output,
                        RedirectUrl = output.Substring(redirectResponsePrefix.Length)
                    };
                }

                const string timeoutResponsePrefix = "TIMEOUT: ";
                if (output.StartsWith(timeoutResponsePrefix))
                {
                    return new RenderingResult
                    {
                        Status = RenderingResultStatus.Timeout,
                        Output = output,
                        RedirectUrl = output.Substring(timeoutResponsePrefix.Length)
                    };
                }

                const string errorResponsePrefix = "ERROR: ";
                if (output.StartsWith(errorResponsePrefix))
                {
                    return new RenderingResult
                    {
                        Status = RenderingResultStatus.Error,
                        Output = output,
                        RedirectUrl = output.Substring(errorResponsePrefix.Length)
                    };
                }

                return new RenderingResult
                {
                    Status = RenderingResultStatus.PhantomServerIncorrectResponse,
                    Output = output
                };
            }
コード例 #2
0
ファイル: PhantomServer.cs プロジェクト: Orckestra/C1-CMS
        private RenderingResult RenderUrlImpl(HttpCookie[] cookies, string url, string outputImageFilePath, string mode)
        {
            Verify.ArgumentNotNull(cookies, nameof(cookies));

            string cookieDomain = new Uri(url).Host;

            var request = new RenderPreviewRequest
            {
                requestId = "1",
                mode = mode,
                url = url,
                outputFilePath = outputImageFilePath,
                cookies = cookies.Select(cookie => new CookieInformation
                {
                    name = cookie.Name,
                    value = cookie.Value,
                    domain = cookieDomain
                }).ToArray()
            };

            var ms = new MemoryStream();
            var ser = new DataContractJsonSerializer(typeof(RenderPreviewRequest));
            ser.WriteObject(ms, request);

            var json = Encoding.UTF8.GetString(ms.ToArray());

            var output = new List<string>();

            Task readerTask = Task.Run(() =>
            {
                _stdin.WriteLine(json);

                string line;

                do
                {
                    line = _stdout.ReadLine();
                    lock (output)
                    {
                        output.Add(line);
                    }

                } while (!IsEndOfReply(line));
            });

            var secondsSinceStartup = (DateTime.Now - _process.StartTime).TotalSeconds;
            double timeout = secondsSinceStartup < 120 || mode == "test" ? 65 : 30;

            readerTask.Wait(TimeSpan.FromSeconds(timeout));

            // TODO: check for theother task statuses
            switch (readerTask.Status)
            {
                case TaskStatus.RanToCompletion:
                    if (output.Count == 0)
                    {
                        return new RenderingResult
                        {
                            Status = RenderingResultStatus.PhantomServerNoOutput,
                            Output = new [] { "(null)" }
                        };
                    }
                    break;
                default:
                    string[] outputCopy;
                    lock (output)
                    {
                        outputCopy = output.ToArray();
                    }

                    string logMessage = "Request failed to complete within expected time: " +
#if DEBUG
                        json
#else
                                url + " " + mode
#endif
                        ;


                    return new RenderingResult
                    {
                        Status = RenderingResultStatus.PhantomServerTimeout,
                        Output = new [] { logMessage}.Concat(outputCopy).ToArray(),
                        FilePath = outputImageFilePath
                    };
            }

            if (C1File.Exists(outputImageFilePath))
            {
                return new RenderingResult
                {
                    Status = RenderingResultStatus.Success,
                    Output = output,
                    FilePath = outputImageFilePath
                };
            }

            var lastMessage = output.Last();

            if (!lastMessage.StartsWith(EndOfReplyMarker))
            {
                Log.LogError(LogTitle, $"Missing {EndOfReplyMarker} in the response");
            }

            string redirectUrl = null;
            RenderingResultStatus? status = null;

            foreach (var line in output)
            {
                const string redirectResponsePrefix = "REDIRECT: ";

                if (line == "SUCCESS")
                {
                    status = RenderingResultStatus.Success;
                }
                else if (line.StartsWith(redirectResponsePrefix))
                {
                    status = RenderingResultStatus.Redirect;
                    redirectUrl = line.Substring(redirectResponsePrefix.Length);
                }
                else if (line.StartsWith("TIMEOUT: "))
                {
                    status = RenderingResultStatus.Timeout;
                }
                else if (line.StartsWith("ERROR: "))
                {
                    status = RenderingResultStatus.Error;
                }
            }

            status = status ?? RenderingResultStatus.PhantomServerIncorrectResponse;

            return new RenderingResult
            {
                Status = status.Value,
                Output = output,
                RedirectUrl = redirectUrl
            };
        }