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}"); } }
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; }