/// <summary> /// Request trap event arguments /// </summary> /// <param name="tvReqInfo"></param> /// <param name="httpReqInfo"></param> /// <param name="httpRespInfo"></param> /// <param name="reqLock"></param> public RequestTrapEventEventArgs(TVRequestInfo tvReqInfo, HttpRequestInfo httpReqInfo, HttpResponseInfo httpRespInfo, ManualResetEvent reqLock) { _tvReqInfo = tvReqInfo; _reqLock = reqLock; _httpReqInfo = httpReqInfo; _httpRespInfo = httpRespInfo; }
/// <summary> /// Replaces the specified set of matches with the replacement string /// </summary> /// <param name="matchList"></param> /// <param name="replacement"></param> public void Replace(IList <LineMatch> matchList, string replacement) { int count = matchList.Count; for (int i = count - 1; i > -1; i--) { LineMatch match = matchList[i]; if (match.Context == SearchContext.Request) { byte[] reqBytes = LoadRequestData(match.RequestId); reqBytes = ReplaceInComponent(reqBytes, match, replacement); SaveRequest(match.RequestId, reqBytes); //update request line TVRequestInfo reqInfo = GetRequestInfo(match.RequestId); if (String.Compare(match.Line, reqInfo.RequestLine) == 0) { HttpRequestInfo httpReqInfo = new HttpRequestInfo(reqBytes); reqInfo.RequestLine = httpReqInfo.RequestLine; } } else if (match.Context == SearchContext.Response) { byte[] respBytes = LoadResponseData(match.RequestId); respBytes = ReplaceInComponent(respBytes, match, replacement); SaveResponse(match.RequestId, respBytes); } } if (ReplaceEvent != null) { ReplaceEvent.Invoke(new ReplaceEventArgs(matchList, replacement)); } }
/// <summary> /// Adds a new request info row to the list /// </summary> /// <param name="header"></param> /// <returns>The index of the new entry</returns> public int AddRequestInfo(TVRequestInfo header) { int result = -1; try { lock (_lockData) //critical section begins { if (header.Id == -1) { if (_firstIndex == -1) { _firstIndex = 0; _lastIndex = 0; } else { _lastIndex++; } //save the index in the request header header.Id = _lastIndex; } else { if (_firstIndex == -1) { _firstIndex = header.Id; } _lastIndex = header.Id; } _requestInfos.Add(_lastIndex, header); //new request header was added to the list //this means that we have at least the request line //call the RequestAdded event result = _lastIndex; } //end critical section //now that the data was added invoke the event if (RequestEntryAdded != null) { TVDataAccessorDataArgs e = new TVDataAccessorDataArgs(_lastIndex, header); RequestEntryAdded.Invoke(e); } } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "An error occured while adding a request info: {0}", ex.ToString()); } return(result); }
/// <summary> /// Replaces the index at header.id with the passed object and signals that the request info was updated to all listeners /// </summary> /// <param name="header"></param> /// <returns>The index of the new entry</returns> public void UpdateRequestInfo(TVRequestInfo header) { lock (_lockData) { _requestInfos[header.Id] = header; } if (RequestEntryUpdated != null) { TVDataAccessorDataArgs e = new TVDataAccessorDataArgs(header.Id, header); RequestEntryUpdated.Invoke(e); } }
/// <summary> /// Appends the specified request with the associated raw response to the current traffic file and returns the request id /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="isHttps"></param> /// <returns></returns> public int AddRequestResponse(byte[] request, byte[] response, bool isHttps) { TVRequestInfo tvReqInfo = new TVRequestInfo(); tvReqInfo.RequestLine = HttpRequestInfo.GetRequestLine(request); tvReqInfo.Description = "N/A"; tvReqInfo.RequestTime = DateTime.Now; tvReqInfo.ResponseTime = DateTime.Now; tvReqInfo.ThreadId = Utils.GetCurrentWin32ThreadId().ToString(); tvReqInfo.IsHttps = isHttps; tvReqInfo.ResponseStatus = HttpResponseInfo.GetResponseStatus(response); AddRequestInfo(tvReqInfo); SaveRequestResponse(tvReqInfo.Id, request, response); return(tvReqInfo.Id); }
private void Load() { SetState(AccessorState.Loading); //Open the decompressed files //load index byte[] bytes; string line; int currentIndex = -1, count = 0; TVRequestInfo currentRequestInfo; _requestInfos = new SortedDictionary <int, TVRequestInfo>(); _rawTrafficFile = File.Open(_tempFileFolder + "\\" + RAW_TRAFFIC_FILE_NAME, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); XmlDocument customDataFile = new XmlDocument(); customDataFile.XmlResolver = null; if (File.Exists(_tempFileFolder + "\\" + CUSTOM_DATA_FILE_NAME)) { customDataFile.Load(_tempFileFolder + "\\" + CUSTOM_DATA_FILE_NAME); } Profile = new ParsingOptions(); //Load the parsing options that were used to create this file if (File.Exists(_tempFileFolder + "\\" + OPTIONS_FILE_NAME)) { Profile.Load(_tempFileFolder + "\\" + OPTIONS_FILE_NAME); } _firstIndex = -1; FileStream indexFile = File.Open(_tempFileFolder + "\\" + INDEX_FILE_NAME, FileMode.OpenOrCreate, FileAccess.ReadWrite); while ((bytes = Utils.ReadLine(indexFile, ESTIMATED_LINE_SIZE)) != null) { try { line = Utils.ByteToString(bytes); currentRequestInfo = new TVRequestInfo(); currentRequestInfo.ReadValues(line); currentIndex = currentRequestInfo.Id; AddRequestInfo(currentRequestInfo); //load the data for the first requests in the buffer if (!RequestDataCache.Instance.MaxSizeReached) { this.LoadRequestData(currentIndex); this.LoadResponseData(currentIndex); } //load custom fields XmlNodeList customFields = customDataFile.SelectNodes( String.Format("/Requests/Request[@id='{0}']/Field", currentIndex)); if (customFields.Count > 0) { currentRequestInfo.CustomFields = new Dictionary <string, string>(); foreach (XmlNode node in customFields) { currentRequestInfo.CustomFields.Add(node.Attributes["name"].Value, node.InnerText); } } count++; } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "Error loading request from index: {0}", ex.Message); } } //set the position of the rawdatafile to the end _rawTrafficFile.Position = _rawTrafficFile.Length; //close the other files indexFile.Close(); //set the keep on close flag to false _keepOnClose = false; SetState(AccessorState.Idle); }
/// <summary> /// Constructor /// </summary> /// <param name="requestId"></param> /// <param name="header"></param> public TVDataAccessorDataArgs(int requestId, TVRequestInfo header) { _requestId = requestId; _header = header; }
/// <summary> /// Constructor /// </summary> /// <param name="tvReqInfo"></param> /// <param name="reqLock"></param> public RequestTrapEventEventArgs(TVRequestInfo tvReqInfo, ManualResetEvent reqLock) : this(tvReqInfo, null, null, reqLock) { }
/// <summary> /// COnstructor /// </summary> /// <param name="tvReqInfo"></param> /// <param name="httpRespInfo"></param> /// <param name="reqLock"></param> public RequestTrapEventEventArgs(TVRequestInfo tvReqInfo, HttpResponseInfo httpRespInfo, ManualResetEvent reqLock) : this(tvReqInfo, null, httpRespInfo, reqLock) { }
/// <summary> /// Saves response bytes to disk and caches it if tail is on /// </summary> /// <param name="requestId"></param> /// <param name="data">Request data object storing the response</param> public void SaveResponse(int requestId, RequestResponseBytes data) { if (data == null || data.RawResponse == null) { return; } bool isResponseChanged = false; TVRequestInfo reqInfo = null; try { lock (_lockData) //critical section begins { if (_requestInfos.ContainsKey(requestId)) { //save to memory buffer only if tail is on //this is done to use minimum memory footprint since on //normal load the user is viewing the requests //at the beginning of the file reqInfo = _requestInfos[requestId]; //save to disk reqInfo.ResponseStartPosition = WritePosition; string respStatus = null; if (_tailInProgress || RequestDataCache.Instance.GetEntry(_objectId ^ requestId) != null || reqInfo.IsEncrypted) { byte[] rawResponse = data.RawResponse; respStatus = HttpResponseInfo.GetResponseStatus(rawResponse); //this takes memory but at the same time insures that the user can see the data fast during tail if (reqInfo.IsEncrypted) { rawResponse = Encryptor.Encrypt(rawResponse); } BufferSaveResponse(requestId, rawResponse); DataWrite(rawResponse, 0, rawResponse.Length); reqInfo.ResponseLength = rawResponse.Length; } else { byte[] chunk; //this saves memory and writes the chunks of data directly to disk data.ResetResponseChunkPosition(); while ((chunk = data.ReadResponseChunk()) != null) { if (respStatus == null) { respStatus = HttpResponseInfo.GetResponseStatus(chunk); } DataWrite(chunk, 0, chunk.Length); } reqInfo.ResponseLength = data.ResponseSize; } reqInfo.ResponseStatus = respStatus; isResponseChanged = true; } } //critical section ends if (isResponseChanged && ResponseChanged != null) { ResponseChanged.Invoke( new TVDataAccessorDataArgs(requestId, reqInfo)); } } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "Error saving response data for request id: {0} . Stack trace: {1}", requestId, ex.ToString()); } }