Пример #1
0
        private void ParseInternal()
        {
            _transactionInfos = new List <TransactionInfo>();

            _transactionInfo             = null;
            _pageUniqueId                = 0;
            _implicitTransactionUniqueId = 0;
            _harPages   = null;
            _harEntries = null;
            _internalIdToHarEntryMap = null;
            _harPage = null;

            _line            = null;
            _lineIndex       = 0;
            _skipFetchOnce   = false;
            _scriptStartTime = null;

            while (FetchLine())
            {
                var utcStartTimeMatch = _line.MatchAgainst(ParsingHelper.UtcStartTimeRegex);
                if (utcStartTimeMatch.Success)
                {
                    if (_scriptStartTime.HasValue)
                    {
                        throw new InvalidOperationException(@"The script's start date/time was already found.");
                    }

                    var year  = utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateYearGroupName).ParseInt();
                    var month = utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateMonthGroupName).ParseInt();
                    var day   = utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateDayGroupName).ParseInt();

                    var hour   = utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateHourGroupName).ParseInt();
                    var minute =
                        utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateMinuteGroupName).ParseInt();
                    var second =
                        utcStartTimeMatch.GetSucceededGroupValue(ParsingHelper.DateSecondGroupName).ParseInt();

                    _scriptStartTime = new DateTimeOffset(year, month, day, hour, minute, second, TimeSpan.Zero);
                    continue;
                }

                var transactionEndMatch = _line.MatchAgainst(ParsingHelper.TransactionEndRegex);
                if (transactionEndMatch.Success)
                {
                    CommitTransactionIfPending();
                    continue;
                }

                var transactionStartMatch = _line.MatchAgainst(ParsingHelper.TransactionStartRegex);
                if (transactionStartMatch.Success)
                {
                    CommitTransactionIfPending();

                    var name = transactionStartMatch.GetSucceededGroupValue(ParsingHelper.NameGroupName);
                    _transactionInfo = CreateTransaction(name);
                    continue;
                }

                var connectedSocketMatch = _line.MatchAgainst(ParsingHelper.ConnectedSocketRegex);
                if (connectedSocketMatch.Success)
                {
                    var socketId =
                        connectedSocketMatch.GetSucceededGroupValue(ParsingHelper.SocketIdGroupName).ParseInt();

                    var sourceEndpoint = connectedSocketMatch
                                         .GetSucceededGroupValue(ParsingHelper.SourceEndpointGroupName)
                                         .ParseEndPoint();

                    var targetEndpoint = connectedSocketMatch
                                         .GetSucceededGroupValue(ParsingHelper.TargetEndpointGroupName)
                                         .ParseEndPoint();

                    var connectTimeInMilliseconds =
                        connectedSocketMatch.GetSucceededGroupValue(ParsingHelper.DurationGroupName).ParseLong();

                    var socketData = new SocketData
                    {
                        SourceEndpoint = sourceEndpoint,
                        TargetEndpoint = targetEndpoint
                    };

                    EnsureTransactionInfo();

                    _socketIdToDataMap.EnsureNotNull().Add(socketId, socketData);

                    FetchRequestHeaders(connectTimeInMilliseconds, sourceEndpoint, targetEndpoint);
                    continue;
                }

                var alreadyConnectedMatch = _line.MatchAgainst(ParsingHelper.AlreadyConnectedRegex);
                if (alreadyConnectedMatch.Success)
                {
                    var socketId =
                        alreadyConnectedMatch.GetSucceededGroupValue(ParsingHelper.SocketIdGroupName).ParseInt();

                    EnsureTransactionInfo();

                    var socketData = _socketIdToDataMap.EnsureNotNull().GetValueOrDefault(socketId);
                    if (socketData == null)
                    {
                        throw new InvalidOperationException(
                                  $"Socket data for the already connected socket {socketId} was not found.");
                    }

                    FetchRequestHeaders(0, socketData.SourceEndpoint, socketData.TargetEndpoint);
                    continue;
                }

                var responseHeadersMarkerMatch = _line.MatchAgainst(ParsingHelper.ResponseHeadersMarkerRegex);
                if (responseHeadersMarkerMatch.Success)
                {
                    ProcessResponseHeaders(responseHeadersMarkerMatch);
                    continue;
                }

                var encodedResponseBodyReceivedMatch =
                    _line.MatchAgainst(ParsingHelper.EncodedResponseBodyReceivedRegex);
                if (encodedResponseBodyReceivedMatch.Success)
                {
                    ProcessResponseBody(encodedResponseBodyReceivedMatch);
                    continue;
                }

                var responseBodyMarkerRegexMatch = _line.MatchAgainst(ParsingHelper.ResponseBodyMarkerRegex);
                if (responseBodyMarkerRegexMatch.Success)
                {
                    ProcessResponseBody(responseBodyMarkerRegexMatch);
                    continue;
                }

                //// TODO [vmcl] Parse request body

                var requestDoneMatch = _line.MatchAgainst(ParsingHelper.RequestDoneRegex);
                if (requestDoneMatch.Success)
                {
                    var url = requestDoneMatch.GetSucceededGroupValue(ParsingHelper.UrlGroupName);

                    var harEntry = _urlToOpenRequestHarEntryMap.EnsureNotNull().GetValueOrDefault(url);
                    if (harEntry == null)
                    {
                        throw new InvalidOperationException(
                                  $@"Cannot find a corresponding entry for the completed request ""{url}"" (line {_lineIndex
                                }).");
                    }

                    var doneTime = GetTime(requestDoneMatch);
                    var elapsed  = doneTime - harEntry.StartedDateTime.EnsureNotNull();

                    var timings = harEntry.Timings.EnsureNotNull();
                    timings.Receive = (decimal)elapsed.TotalMilliseconds - timings.Wait.GetValueOrDefault();

                    continue;
                }

                Debug.WriteLine($"[{GetType().GetQualifiedName()}] Skipping line: {_line}");
            }
        }
Пример #2
0
        private void FetchRequestHeaders(
            long connectTimeInMilliseconds,
            IPEndPoint sourceEndpoint,
            IPEndPoint targetEndpoint)
        {
            FetchLine();
            var match = _line.MatchAgainst(ParsingHelper.RequestHeadersMarkerRegex);

            if (!match.Success)
            {
                throw new InvalidOperationException($"Request header was expected at line {_lineIndex}.");
            }

            var url        = match.GetSucceededGroupValue(ParsingHelper.UrlGroupName);
            var size       = match.GetSucceededGroupValue(ParsingHelper.SizeGroupName).ParseLong();
            var frameId    = match.GetSucceededGroupValue(ParsingHelper.FrameIdGroupName).ParseNullableLong();
            var internalId = match.GetSucceededGroupValue(ParsingHelper.InternalIdGroupName).ParseLong();

            var startTime = GetTime(match);

            if (frameId.HasValue || _harPage == null)
            {
                _harPage = new HarPage
                {
                    Id              = $"page_{++_pageUniqueId}",
                    Title           = url,
                    StartedDateTime = startTime
                };

                _harPages.EnsureNotNull().Add(_harPage);
            }

            var harRequest = new HarRequest
            {
                HeadersSize = size,
                Url         = url,
                BodySize    = 0
            };

            var harEntryTimings = new HarEntryTimings
            {
                Blocked = HarConstants.NotApplicableTiming,
                Dns     = HarConstants.NotApplicableTiming,
                Connect = connectTimeInMilliseconds,
                Ssl     = HarConstants.NotApplicableTiming,
                Send    = 0 //// Currently, it's technically impossible to determine the 'send' timing value
            };

            var harEntry = new HarEntry
            {
                PageRef         = _harPage.Id,
                ConnectionId    = sourceEndpoint.Port.ToString(CultureInfo.InvariantCulture),
                ServerIPAddress = targetEndpoint.Address.ToString(),
                StartedDateTime = startTime,
                Request         = harRequest,
                Response        = new HarResponse {
                    BodySize = 0, Content = new HarContent()
                },
                Timings = harEntryTimings
            };

            AddHarEntry(harEntry, internalId, url);

            var multilineString = FetchMultipleLines();

            var requestLineString    = multilineString.Lines.FirstOrDefault();
            var httpRequestLineMatch = requestLineString.MatchAgainst(ParsingHelper.HttpRequestLineRegex);

            if (!httpRequestLineMatch.Success)
            {
                throw new InvalidOperationException(
                          $"An HTTP Request-Line was expected at line {multilineString.LineIndexRange.Lower}.");
            }

            harRequest.Method      = httpRequestLineMatch.GetSucceededGroupValue(ParsingHelper.HttpMethodGroupName);
            harRequest.HttpVersion =
                httpRequestLineMatch.GetSucceededGroupValue(ParsingHelper.HttpVersionGroupName);

            var harHeaders = ParseHttpHeaders(multilineString);

            harRequest.Headers = harHeaders;
        }