private static void ReplaceTest(string replacement) { TrafficViewer.Instance.NewTvf(); ITrafficDataAccessor tvf = TrafficViewer.Instance.TrafficViewerFile; string firstRequest = "GET /a1 HTTP/1.1\r\nHeader1: a1"; string secondRequest = "GET /a2 HTTP/1.1\r\nHeader1: a2"; string firstResponse = "HTTP 200 OK\r\n<r>1</r>"; string secondResponse = "HTTP 200 OK\r\n<r>2</r><tag><r>3</r>"; tvf.AddRequestResponse(firstRequest, firstResponse); tvf.AddRequestResponse(secondRequest, secondResponse); Assert.AreEqual(2, tvf.RequestCount); LineSearcher searcher = new LineSearcher(); LineMatches result = new LineMatches(); SearchCriteriaSet criteriaSet = new SearchCriteriaSet(); criteriaSet.Add(new SearchCriteria(SearchContext.Full, true, @"a1|a=2|<r>\d</r>")); searcher.Search(tvf, criteriaSet, result); tvf.Replace(result, replacement); firstRequest = Constants.DefaultEncoding.GetString(tvf.LoadRequestData(0)); secondRequest = Constants.DefaultEncoding.GetString(tvf.LoadRequestData(1)); firstResponse = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(0)); secondResponse = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(1)); Assert.AreEqual("GET /" + replacement + " HTTP/1.1\r\nHeader1: " + replacement, firstRequest); Assert.AreEqual("HTTP 200 OK\r\n" + replacement + "<tag>" + replacement, secondResponse); }
/// <summary> /// Gets a memory stream to search in for the specified context /// </summary> /// <param name="dataSource"></param> /// <param name="header"></param> /// <param name="context"></param> /// <returns></returns> protected MemoryStream GetMemoryStream(ITrafficDataAccessor dataSource, TVRequestInfo header, SearchContext context) { MemoryStream toBeSearched; if (context == SearchContext.Request || context == SearchContext.RequestBody) { toBeSearched = new MemoryStream(dataSource.LoadRequestData(header.Id)); } else if (context == SearchContext.Response) { toBeSearched = new MemoryStream(dataSource.LoadResponseData(header.Id)); } else { toBeSearched = new MemoryStream(); byte[] data = dataSource.LoadRequestData(header.Id); toBeSearched.Write(data, 0, data.Length); data = Constants.DefaultEncoding.GetBytes(Environment.NewLine); toBeSearched.Write(data, 0, data.Length); data = dataSource.LoadResponseData(header.Id); toBeSearched.Write(data, 0, data.Length); //reset the prosition so readline can start from the beggining toBeSearched.Position = 0; } return(toBeSearched); }
public void TestRequestLineAfterReplace() { TrafficViewer.Instance.NewTvf(); ITrafficDataAccessor tvf = TrafficViewer.Instance.TrafficViewerFile; string firstRequest = "GET http://site.com/a1 HTTP/1.1\r\nHeader1: a1"; tvf.AddRequestResponse(firstRequest, String.Empty); TVRequestInfo reqInfo = tvf.GetRequestInfo(0); Assert.AreEqual("GET http://site.com/a1 HTTP/1.1", reqInfo.RequestLine); Assert.AreEqual(1, tvf.RequestCount); LineSearcher searcher = new LineSearcher(); LineMatches result = new LineMatches(); SearchCriteriaSet criteriaSet = new SearchCriteriaSet(); criteriaSet.Add(new SearchCriteria(SearchContext.RequestLine, true, "a1|a=2|<r>2</r>")); searcher.Search(tvf, criteriaSet, result); tvf.Replace(result, "replacement"); firstRequest = Constants.DefaultEncoding.GetString(tvf.LoadRequestData(0)); Assert.AreEqual("GET http://site.com/replacement HTTP/1.1\r\nHeader1: a1", firstRequest); Assert.AreEqual("GET http://site.com/replacement HTTP/1.1", reqInfo.RequestLine); }
/// <summary> /// Exports data from the specified source to the specifies strems /// </summary> /// <param name="source"></param> /// <param name="stream"></param> /// <param name="overwriteScheme">Wether to overrite existing http scheme</param> /// <param name="isSSL">Wether the request is secure or not. This will overrite the http scheme of the request if applicable</param> /// <param name="newHost">New host for the request</param> /// <param name="newPort">New port for the request</param> protected virtual void Export(ITrafficDataAccessor source, Stream stream, bool overwriteScheme, bool isSSL, string newHost, int newPort) { TVRequestInfo info; int i = -1; string overridenScheme = isSSL ? "https" : "http"; //using an xml writer for memory concerns XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8); writer.WriteStartDocument(); writer.WriteComment(String.Format("Automatically created by Traffic Viewer SDK at {0}", DateTime.Now)); writer.WriteComment(String.Format("Number of requests in file {0}", source.RequestCount)); writer.WriteStartElement("requests"); while ((info = source.GetNext(ref i)) != null) { string scheme = info.IsHttps ? "https" : "http"; scheme = overwriteScheme ? overridenScheme : scheme; //get the request information byte[] data = source.LoadRequestData(info.Id); if (data != null) { HttpRequestInfo reqInfo = new HttpRequestInfo(data); reqInfo.IsSecure = scheme == "https"; WriteRequest(writer, newHost, newPort, scheme, reqInfo); } } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); }
private string GetText(int index) { StringBuilder sb = new StringBuilder(); byte[] bytes = _source.LoadRequestData(index); sb.Append(Constants.DefaultEncoding.GetString(bytes)); sb.Append(Environment.NewLine); sb.Append(Environment.NewLine); bytes = _source.LoadResponseData(index); sb.Append(Constants.DefaultEncoding.GetString(bytes)); return(sb.ToString()); }
/// <summary> /// Gets the next unsent request /// </summary> /// <returns>Http Request Info</returns> private HttpRequestInfo GetNextRequest() { TVRequestInfo tvReqInfo = null; HttpRequestInfo httpReqInfo = null; ICacheable cacheEntry = null; //get the next unvisited request bool isCached = true; int hash = 0; do { tvReqInfo = Source.GetNext(ref _currId); if (tvReqInfo != null) { isCached = true; //skip js files and images if (!Utils.IsMatch(tvReqInfo.RequestLine, KNOWN_RESOURCE_EXTENSIONS)) { byte[] requestBytes = Source.LoadRequestData(tvReqInfo.Id); httpReqInfo = new HttpRequestInfo(requestBytes); //skip invalid requests if (httpReqInfo.Path.Contains("/")) { hash = httpReqInfo.GetHashCode(); //check the cache for the request to see if it was already visited //allow the same request to be sent more than once if (hash != _lastRequestHash) { cacheEntry = TrafficServerCache.Instance.GetEntry(hash); isCached = cacheEntry != null; } } } } //keep doing this until the end of requests or until we found a request that is not cached }while (tvReqInfo != null && isCached); if (hash != _lastRequestHash) { _lastRequestHash = hash; //clear the cache so we don't skip any repeats of the previous request TrafficServerCache.Instance.Clear(); } return(httpReqInfo); }
void ValidateTrafficSourcesRequestsAreSame(ITrafficDataAccessor src1, ITrafficDataAccessor src2, bool includeResponses = true) { Assert.AreEqual(src1.RequestCount, src2.RequestCount); int i = -1, j = -1; while (true) { TVRequestInfo first = src1.GetNext(ref i); TVRequestInfo second = src2.GetNext(ref j); if (first == null && second == null) { break; } Assert.AreEqual(first.RequestLine, second.RequestLine); //proceed to compare http requests byte[] firstRequest = src1.LoadRequestData(first.Id); byte[] secondRequest = src2.LoadRequestData(second.Id); HttpRequestInfo firstRequestInfo = new HttpRequestInfo(firstRequest); HttpRequestInfo seconRequestInfo = new HttpRequestInfo(secondRequest); Assert.AreEqual(firstRequestInfo.ToString(), seconRequestInfo.ToString()); if (includeResponses) { //proceed to compare responses Assert.AreEqual(first.ResponseStatus, second.ResponseStatus); byte[] firstResponse = src1.LoadResponseData(first.Id); byte[] secondResponse = src2.LoadResponseData(second.Id); HttpResponseInfo firstResponseInfo = new HttpResponseInfo(firstResponse); HttpResponseInfo secondResponseInfo = new HttpResponseInfo(secondResponse); Assert.AreEqual(firstResponseInfo.ToString(), secondResponseInfo.ToString()); } } }
/// <summary> /// Add the hosts in the traffic log to the host file /// </summary> private void AddHosts() { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Using the host of the first request"); int i = -1; TVRequestInfo tvReqInfo = _sourceStore.GetNext(ref i); if (tvReqInfo != null) { HttpRequestInfo httpReqInfo = new HttpRequestInfo(_sourceStore.LoadRequestData(tvReqInfo.Id)); if (httpReqInfo.Host == String.Empty) { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Could not find a host. You might need to add the host manually"); } } }
public void Execute(ITrafficDataAccessor curDataAccessor, List <TVRequestInfo> selectedRequests, IHttpClientFactory curHttpClientFactory) { if (selectedRequests.Count < 1) { ErrorBox.ShowDialog(Resources.SelectOneRequest); return; } TVRequestInfo req = selectedRequests[0]; byte[] request = curDataAccessor.LoadRequestData(req.Id); HttpRequestInfo reqInfo = new HttpRequestInfo(request); reqInfo.IsSecure = req.IsHttps; var csrfSetupForm = new CSRFSetupForm(reqInfo, curDataAccessor); csrfSetupForm.Show(); }
public void TestLineSearchFullRegex() { TrafficViewer.Instance.NewTvf(); ITrafficDataAccessor tvf = TrafficViewer.Instance.TrafficViewerFile; string firstRequest = "POST /a1 HTTP/1.1\r\nHeader1: a1\r\n\r\na=1"; string secondRequest = "POST /a2 HTTP/1.1\r\nHeader1: a2\r\n\r\na=2"; string firstResponse = "HTTP 200 OK\r\n<r>1</r>"; string secondResponse = "HTTP 200 OK\r\n<r>2</r>"; tvf.AddRequestResponse(firstRequest, firstResponse); string testValue = Constants.DefaultEncoding.GetString(tvf.LoadRequestData(0)); Assert.AreEqual(firstRequest, testValue, "Incorrect first request"); testValue = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(0)); Assert.AreEqual(firstResponse, testValue, "Incorrect first response"); tvf.AddRequestResponse(secondRequest, secondResponse); Assert.AreEqual(2, tvf.RequestCount, "Correct number of requests not added"); LineSearcher searcher = new LineSearcher(); LineMatches result = new LineMatches(); SearchCriteriaSet criteriaSet = new SearchCriteriaSet(); criteriaSet.Add(new SearchCriteria(SearchContext.Full, true, "a=1|<r>2</r>")); searcher.Search(tvf, criteriaSet, result); Assert.AreEqual(2, result.Count); Assert.AreEqual(0, result[0].RequestId); Assert.AreEqual(1, result[1].RequestId); Assert.AreEqual(SearchContext.Request, result[0].Context); Assert.AreEqual(SearchContext.Response, result[1].Context); Assert.AreEqual("a=1", firstRequest.Substring(result[0].MatchCoordinatesList[0].MatchPosition, result[0].MatchCoordinatesList[0].MatchLength)); Assert.AreEqual("<r>2</r>", secondResponse.Substring(result[1].MatchCoordinatesList[0].MatchPosition, result[1].MatchCoordinatesList[0].MatchLength)); }
/// <summary> /// Loads the request and response data to the GUI /// </summary> /// <param name="requestId"></param> /// <param name="dataSource">Traffic viewer file or other data source</param> private void LoadRequest(int requestId) { byte[] requestBytes = _dataSource.LoadRequestData(requestId); TVRequestInfo reqInfo = _dataSource.GetRequestInfo(requestId); Encoding enc = Constants.DefaultEncoding; /* * if (reqInfo != null && reqInfo.Description.Contains("Binary")) * { * enc = new TrafficViewerEncoding(); * }*/ if (requestBytes != null) { _requestText = enc.GetString(requestBytes); } else { _requestText = String.Empty; } _responseBytes = _dataSource.LoadResponseData(requestId); if (_responseBytes != null) { _responseText = enc.GetString(_responseBytes); } else { _responseBytes = new byte[0]; _responseText = String.Empty; } _currentId = requestId; LoadSelectedView(); }
/// <summary> /// Sends the specified request info /// </summary> /// <param name="source"></param> /// <param name="info"></param> private void SendRequest(ITrafficDataAccessor source, TVRequestInfo info) { byte[] reqBytes = source.LoadRequestData(info.Id); string updatedRequest = PatternTracker.Instance.UpdateRequest(Constants.DefaultEncoding.GetString(reqBytes)); HttpRequestInfo reqInfo = new HttpRequestInfo(updatedRequest); reqInfo.IsSecure = info.IsHttps; _sessionIdHelper.UpdateSessionIds(reqInfo, _prevRequest, _prevResponse); info.RequestTime = DateTime.Now; //save the request that will be sent source.SaveRequest(info.Id, Constants.DefaultEncoding.GetBytes(updatedRequest)); try { _prevResponse = _httpClient.SendRequest(reqInfo); _prevRequest = reqInfo; //save the request and response if (_prevResponse != null) { info.ResponseTime = DateTime.Now; PatternTracker.Instance.UpdatePatternValues(_prevResponse); source.SaveResponse(info.Id, _prevResponse.ToArray()); } else { source.SaveResponse(info.Id, Constants.DefaultEncoding.GetBytes(_communicationError)); } } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "Error playing back request {0}", ex.Message); source.SaveResponse(info.Id, Constants.DefaultEncoding.GetBytes(Resources.CommunicationError)); } }
/// <summary> /// Actually gets a matching response from the mock data /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> public HttpResponseInfo SendRequest(HttpRequestInfo requestInfo) { HttpResponseInfo responseInfo = null; string currentRequestString = requestInfo.ToString(); string currentAlertId = Utils.RegexFirstGroupValue(currentRequestString, ALERT_MATCH); TrafficServerMode currentMatchMode = _matchMode; if (!String.IsNullOrEmpty(currentAlertId)) //override the redundancy tuning if we are trying to match a alert { currentMatchMode = TrafficServerMode.BrowserFriendly; } //parse the request variables because we will need them to construct the hash requestInfo.ParseVariables(); TrafficServerResponseSet responseSet = null; //look in the server cache for the request ICacheable entry = TrafficServerCache.Instance.GetEntry(requestInfo.GetHashCode(currentMatchMode)); if (entry != null) { responseSet = entry.Reserve() as TrafficServerResponseSet; entry.Release(); } TrafficServerResponseSet similarRequests = new TrafficServerResponseSet(); if (responseSet == null) { //create a new empty response set responseSet = new TrafficServerResponseSet(); RequestSearcher searcher = new RequestSearcher(); SearchCriteriaSet criteriaSet; criteriaSet = GetCriteriaSet(requestInfo, currentMatchMode); RequestMatches matches = new RequestMatches(); //do the search! searcher.Search(_sourceStore, criteriaSet, matches); //normalize the matches and keep only the ones that have the same variables and values if (matches.Count > 0) { HttpRequestInfo original; HttpRequestInfo found; byte[] requestBytes; int i, n = matches.Count; for (i = 0; i < n & i < MATCHES_LIMIT; i++) { int match = matches[i]; TVRequestInfo header = _sourceStore.GetRequestInfo(match); if (_ignoreAuth) { if ( String.Compare(header.ResponseStatus, "401", true) == 0 || String.Compare(header.ResponseStatus, "407", true) == 0) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping authentication challenge"); //simply skip 401 matches continue; } } if (String.Compare(header.Description, Resources.TrafficLogProxyDescription, true) == 0) { //is likely that the source store is also the save store and this may be //the current request being saved HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Skipping request to traffic store"); continue; } requestBytes = _sourceStore.LoadRequestData(match); string requestString = Constants.DefaultEncoding.GetString(requestBytes); if (String.IsNullOrEmpty(requestString)) { continue; //skip the current match is incorrect } original = new HttpRequestInfo(DynamicElementsRemover.Remove(currentRequestString)); found = new HttpRequestInfo(DynamicElementsRemover.Remove(requestString)); if (RequestMatcher.IsMatch(original, found, TrafficServerMode.Strict)) { responseSet.Add(match); } else if (currentMatchMode != TrafficServerMode.Strict && RequestMatcher.IsMatch(original, found, currentMatchMode)) { similarRequests.Add(match); } } //if no exact requests were found if (responseSet.Count == 0 && similarRequests.Count > 0) { HttpServerConsole.Instance.WriteLine (LogMessageType.Warning, "Warning, exact match was not found for {0} returning a similar request.", requestInfo.RequestLine); } responseSet.AddRange(similarRequests.Matches); } //add this response set to the cache TrafficServerCache.Instance.Add(requestInfo.GetHashCode(currentMatchMode), new CacheEntry(responseSet)); } //get the next response id from the response set int requestId = responseSet.GetNext(); if (requestId == NULL_INDEX) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "(404) Request not found: {0}" , requestInfo.RequestLine); //the request was not found at all, return a 404 return(new HttpResponseInfo(HttpErrorResponse.GenerateHttpErrorResponse(HttpStatusCode.NotFound, "Request Not Found", "<html><head><title>Error code: 404</title><body><h1>Request was not found or variables didn't match.</h1></body></html>"))); } if (requestId != NULL_INDEX) { HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Returning response from request id: {0}", requestId); byte[] responseBytes = _sourceStore.LoadResponseData(requestId); if (responseBytes != null) { responseInfo = new HttpResponseInfo(responseBytes); if (!String.IsNullOrEmpty(currentAlertId)) { Encoding encoding = HttpUtil.GetEncoding(responseInfo.Headers["Content-Type"]); string responseString = encoding.GetString(responseBytes); responseString = Utils.ReplaceGroups(responseString, ALERT_MATCH, currentAlertId); responseInfo = new HttpResponseInfo(encoding.GetBytes(responseString)); } } //add the request id header responseInfo.Headers.Add("Traffic-Store-Req-Id", requestId.ToString()); } return(responseInfo); }
protected override void Export(ITrafficDataAccessor source, System.IO.Stream stream, bool overwriteScheme, bool isSSL, string newHost, int newPort) { TVRequestInfo info; int i = -1; string overridenScheme = isSSL ? "https" : "http"; //using an xml writer for memory concerns XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8); writer.WriteStartDocument(); writer.WriteStartElement("StateInducer"); writer.WriteAttributeString("Version", "1.1"); writer.WriteStartElement("Sequences"); writer.WriteStartElement("Sequence"); writer.WriteAttributeString("Name", "Exported from X-Force Black Ops"); writer.WriteAttributeString("Enabled", "True"); writer.WriteAttributeString("ReplayOptimizationsEnabled", "False"); writer.WriteAttributeString("TestInIsolation", "True"); writer.WriteAttributeString("TestSingleThreadedly", "True"); writer.WriteAttributeString("ManualExploreEnabled", "False"); writer.WriteAttributeString("LoginRequired", "True"); writer.WriteStartElement("requests"); while ((info = source.GetNext(ref i)) != null) { string scheme = info.IsHttps ? "https" : "http"; scheme = overwriteScheme ? overridenScheme : scheme; //get the request information byte[] reqData = source.LoadRequestData(info.Id); byte[] respData = source.LoadResponseData(info.Id); if (reqData != null) { HttpRequestInfo reqInfo = new HttpRequestInfo(reqData); HttpResponseInfo respInfo = new HttpResponseInfo(respData); //add to the list of variables AddToVariableInfoCollection(reqInfo.Cookies.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.QueryVariables.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.BodyVariables.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.PathVariables.GetVariableInfoCollection()); WriteRequest(writer, newHost, newPort, scheme, reqInfo, respInfo); } } writer.WriteEndElement(); //writer.WriteRaw(Resources.VariableDefinitions); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); writer.Close(); }
/// <summary> /// Verifies that a request matches /// </summary> /// <param name="dataSource"></param> /// <param name="header"></param> /// <param name="criteriaSet"></param> /// <param name="result"></param> protected override void RequestMatches(ITrafficDataAccessor dataSource, TVRequestInfo header, SearchCriteriaSet criteriaSet, ISearchResult result) { bool found = true; int hashSum = criteriaSet.DescriptionFilter.GetHashCode(); if (criteriaSet.DescriptionFilter == null || criteriaSet.DescriptionFilter == String.Empty || header.Description.IndexOf(criteriaSet.DescriptionFilter, StringComparison.CurrentCultureIgnoreCase) > -1) { //apply an AND operation with all the search criterias from the last search criteria cached int i, n = criteriaSet.Count, start = criteriaSet.StartCriteriaIndex; for (i = start; i < n; i++) { ISearchCriteria criteria = criteriaSet[i]; //compose the text to search string toBeSearched; if (criteria.Context == SearchContext.RequestLine) { toBeSearched = header.RequestLine; } else if (criteria.Context == SearchContext.RequestBody || criteria.Context == SearchContext.Request) { toBeSearched = Constants.DefaultEncoding.GetString(dataSource.LoadRequestData(header.Id)); if (criteria.Context == SearchContext.RequestBody) { HttpRequestInfo reqInfo = new HttpRequestInfo(toBeSearched); toBeSearched = reqInfo.ContentDataString; } } else if (criteria.Context == SearchContext.Response) { toBeSearched = Constants.DefaultEncoding.GetString(dataSource.LoadResponseData(header.Id)); } else { string request = Constants.DefaultEncoding.GetString(dataSource.LoadRequestData(header.Id)); string response = Constants.DefaultEncoding.GetString(dataSource.LoadResponseData(header.Id)); StringBuilder sb = new StringBuilder(request.Length + response.Length); sb.Append(request); sb.Append(response); toBeSearched = sb.ToString(); } found = criteria.Matches(toBeSearched); if (found) //if found is still true cache the request id as a match for the current set of criterias { hashSum = hashSum ^ criteria.GetHashCode(); ICacheable entry = SearchSubsetsCache.Instance.GetEntry(hashSum); SearchSubset subset; if (entry == null) { subset = new SearchSubset(); subset.Add(header.Id); SearchSubsetsCache.Instance.Add(hashSum, new CacheEntry(subset)); } else { subset = entry.Reserve() as SearchSubset; //if (!subset.Contains(header.Id)) //not checking if the entry exists for performance reasons //{ subset.Add(header.Id); //} entry.Release(); } } else { break; //criteria didn't match, break the loop } } //end of for, all the criterias were matched or one criteria did not match if (found) { //add all the temp matches to the results result.Add(header.Id); } } //end description check }
/// <summary> /// If the response obtained is different than original attempt to update the path and resend to obtain a good response /// </summary> /// <param name="responseInfo"></param> /// <returns></returns> protected override HttpResponseInfo OnBeforeResponseToClient(HttpResponseInfo responseInfo) { responseInfo = base.OnBeforeResponseToClient(responseInfo); if (_trackingReqInfo != null) { //this is a tracked request we may need to update it if (IsDifferentThanOriginalResponse(responseInfo)) { //we need to obtain the referer response and update the request if (_trackingReqInfo.RefererId > -1 && !String.IsNullOrWhiteSpace(_trackingReqInfo.RequestContext)) { //load the referer request var refererInfo = _dataStore.GetRequestInfo(_trackingReqInfo.RefererId); var refererReqBytes = _dataStore.LoadRequestData(_trackingReqInfo.RefererId); if (refererReqBytes != null && refererReqBytes.Length > 0) { var refererHttpInfo = new HttpRequestInfo(refererReqBytes); refererHttpInfo.IsSecure = refererInfo.IsHttps; //update request cookie headers from the current request refererHttpInfo.Cookies.Clear(); refererHttpInfo.Headers["Cookie"] = _requestInfo.Headers["Cookie"]; //now that the referer request is ready send it to the tracking proxy where if the response is different than the original it will in turn //get its referer resent IHttpClient trackingProxyClient = GetTrackingProxyHttpClient(); //following lines equivalent to a recursive call var refererUpdatedResponse = trackingProxyClient.SendRequest(refererHttpInfo); string refererRawResponse = refererUpdatedResponse.ToString(); //update autotrack traccking patterns string updatedRequestValue = Utils.RegexFirstGroupValue(refererRawResponse, _trackingReqInfo.RequestContext); if (!String.IsNullOrWhiteSpace(updatedRequestValue) && AutoTrackingPatternList.ContainsKey(_trackingReqInfo.TrackingPattern)) { TrackingPattern curPattern = AutoTrackingPatternList[_trackingReqInfo.TrackingPattern]; //update request _originalRawRequest = Utils.ReplaceGroups(_originalRawRequest, curPattern.RequestPattern, updatedRequestValue); } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Could not update autodetect parameter for tracked request id {0}. Will resend anyway", _trackingReqInfo.Id); } //update patterns string updatedRawRequest = PatternTracker.Instance.UpdateRequest(_originalRawRequest); updatedRawRequest = UpdateDynamicPatterns(updatedRawRequest); HttpRequestInfo newRequest = new HttpRequestInfo(updatedRawRequest); newRequest.IsSecure = _requestInfo.IsSecure; AddSpecialHeader(newRequest); if (!_trackingReqInfo.UpdatedPath.Equals(newRequest.Path)) { _trackingReqInfo.UpdatedPath = newRequest.Path; //update the path in the ui _dataStore.UpdateRequestInfo(_trackingReqInfo); //now send the request one more time } //send the request with the normal HTTP client this time responseInfo = HttpClient.SendRequest(newRequest); //no matter what we return the last value PatternTracker.Instance.UpdatePatternValues(responseInfo); } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Missing http traffic for request id {0}", _trackingReqInfo.Id); } } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Error, "Missing referer or request context for request id {0}", _trackingReqInfo.Id); } } else { HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Response similar for request id {0}", _trackingReqInfo.Id); } } return(responseInfo); }
private void GenerateRequestsToFuzz() { _requestsToFuzz = new Dictionary <string, TVRequestInfo>(); foreach (TVRequestInfo tvInfo in _requests) { byte[] reqData = _dataAccessor.LoadRequestData(tvInfo.Id); string reqString = Constants.DefaultEncoding.GetString(reqData); if (reqString.Contains(FUZZ)) { //this is the only place to fuzz _requestsToFuzz.Add(reqString, tvInfo); } else { //parse request for parameters to fuzz HttpRequestInfo baseReqInfo = new HttpRequestInfo(reqString, true); HttpRequestInfo newReqInfo; Uri uri = new Uri(baseReqInfo.FullUrl); foreach (string key in uri.Segments) { if (!key.Equals("/"))//skip the path element { newReqInfo = new HttpRequestInfo(reqString); newReqInfo.Path = baseReqInfo.Path.Replace(key, FUZZ); string newReqString = newReqInfo.ToString(); if (!newReqInfo.Path.Equals(baseReqInfo.Path)) { AddRequestToFuzz(newReqString, tvInfo); } } } foreach (string key in baseReqInfo.QueryVariables.Keys) { newReqInfo = new HttpRequestInfo(reqString, true); newReqInfo.QueryVariables[key] = FUZZ; AddRequestToFuzz(newReqInfo.ToString(), tvInfo); } foreach (string key in baseReqInfo.BodyVariables.Keys) { newReqInfo = new HttpRequestInfo(reqString, true); newReqInfo.BodyVariables[key] = FUZZ; AddRequestToFuzz(newReqInfo.ToString(), tvInfo); } foreach (string key in baseReqInfo.Cookies.Keys) { newReqInfo = new HttpRequestInfo(reqString, true); newReqInfo.Cookies[key] = FUZZ; AddRequestToFuzz(newReqInfo.ToString(), tvInfo); } foreach (var header in baseReqInfo.Headers) { newReqInfo = new HttpRequestInfo(reqString, true); newReqInfo.Headers[header.Name] = FUZZ; AddRequestToFuzz(newReqInfo.ToString(), tvInfo); } } } }
protected override void Export(ITrafficDataAccessor source, System.IO.Stream stream, bool overwriteScheme, bool isSSL, string newHost, int newPort) { TVRequestInfo info, inSessionRequestInfo = null; int i = -1, count = 0; string overridenScheme = isSSL ? "https" : "http"; //using an xml writer for memory concerns XmlWriter writer = new XmlTextWriter(stream, Encoding.UTF8); writer.WriteStartDocument(); writer.WriteStartElement("SessionManagement"); writer.WriteAttributeString("Version", "1.2"); writer.WriteElementString("SessionManagementMode", "Manual"); writer.WriteElementString("AllowConcurrentLogins", "True"); writer.WriteElementString("EnableJSXInLoginReplay", "False"); writer.WriteStartElement("RecordedSessionRequests"); bool loginFound = false; while ((info = source.GetNext(ref i)) != null) { string scheme = info.IsHttps ? "https" : "http"; scheme = overwriteScheme ? overridenScheme : scheme; //get the request information byte[] reqData = source.LoadRequestData(info.Id); byte[] respData = source.LoadResponseData(info.Id); if (reqData != null) { HttpRequestInfo reqInfo = new HttpRequestInfo(reqData); reqInfo.IsSecure = scheme.Equals("https"); HttpResponseInfo respInfo = new HttpResponseInfo(respData); //add to the list of variables AddToVariableInfoCollection(reqInfo.Cookies.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.QueryVariables.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.BodyVariables.GetVariableInfoCollection()); AddToVariableInfoCollection(reqInfo.PathVariables.GetVariableInfoCollection()); if (info.Description.IndexOf(Resources.Login, StringComparison.OrdinalIgnoreCase) != -1) { WriteRequest(writer, newHost, newPort, scheme, reqInfo, respInfo, new KeyValuePair <string, string>("SessionRequestType", "Login")); loginFound = true; count++; } else if (info.Description.IndexOf(Resources.Session, StringComparison.OrdinalIgnoreCase) != -1) { WriteRequest(writer, newHost, newPort, scheme, reqInfo, respInfo, new KeyValuePair <string, string>("IsSessionVerifier", "True")); inSessionRequestInfo = info; break; } else if (loginFound) { break; } } } writer.WriteEndElement(); if (inSessionRequestInfo != null) { writer.WriteStartElement("SessionVerifier"); writer.WriteElementString("Enable", "True"); writer.WriteElementString("Pattern", @"(?i)((log|sign)\s?(out|off)|exit|quit)"); writer.WriteElementString("PatternType", "RegularExpression"); byte[] reqData = source.LoadRequestData(inSessionRequestInfo.Id); byte[] respData = source.LoadResponseData(inSessionRequestInfo.Id); string scheme = inSessionRequestInfo.IsHttps ? "https" : "http"; scheme = overwriteScheme ? overridenScheme : scheme; WriteRequest(writer, newHost, newPort, scheme, new HttpRequestInfo(reqData), new HttpResponseInfo(respData), new KeyValuePair <string, string>("SessionRequestType", "Regular")); writer.WriteEndElement(); writer.WriteElementString("InSessionRequestIndex", count.ToString()); } //WriteVariableDefinitions(writer); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Close(); if (!loginFound) { //warn the user throw new Exception(Resources.NoLoginRequestsFound); } }
/// <summary> /// Executes a diff operation /// </summary> /// <param name="firstRequestId"></param> /// <param name="secondRequestId"></param> /// <param name="source"></param> /// <returns></returns> public RequestsDifferResult Diff(int firstRequestId, int secondRequestId, ITrafficDataAccessor source) { RequestsDifferResult result = null; if (source.ContainsId(firstRequestId) && source.ContainsId(secondRequestId)) { //first retrieve the requests byte [] bytes1 = source.LoadRequestData(firstRequestId); byte [] bytes2 = source.LoadRequestData(secondRequestId); string firstRequest = String.Empty; string secondRequest = String.Empty; if (bytes1 != null) { firstRequest = GetString(bytes1); } if (bytes2 != null) { secondRequest = GetString(bytes2); } result = new RequestsDifferResult(); try //try to diff the request components { //diff the request line result = DiffFirstLine(result, firstRequest, secondRequest, 0, 0); //diff the request headers result = DiffHeaders(result, firstRequest, secondRequest, 0, 0); //next compare POST data if available result = DiffPostData(result, firstRequest, secondRequest); } catch (DiffException) //if the request are malformed use a regular letters differ { LettersDiffer lettersDiffer = new LettersDiffer(); DiffResult lettersResult = lettersDiffer.DoDiff(firstRequest, secondRequest); result.DiffsForFirst = lettersResult.DifferencesForFirst; result.DiffsForSecond = lettersResult.DifferencesForSecond; } //done with the requests calculate the base position for the response result.FirstText = firstRequest + "\n\n"; result.SecondText = secondRequest + "\n\n"; int firstRespBasePos = result.FirstText.Length; int secondRespBasePos = result.SecondText.Length; //load the responses bytes1 = source.LoadResponseData(firstRequestId); bytes2 = source.LoadResponseData(secondRequestId); string firstResponse = String.Empty; string secondResponse = String.Empty; if (bytes1 != null) { firstResponse = GetString(bytes1); } if (bytes2 != null) { secondResponse = GetString(bytes2); } try { //diff the status line result = DiffFirstLine(result, firstResponse, secondResponse, firstRespBasePos, secondRespBasePos); //diff the request headers result = DiffHeaders(result, firstResponse, secondResponse, firstRespBasePos, secondRespBasePos); //diff the response body result = DiffResponseBody(result, firstResponse, secondResponse, firstRespBasePos, secondRespBasePos); } catch (DiffException) { //if the responses are missing the headers use a regular lines differ LinesDiffer linesDiffer = new LinesDiffer(); linesDiffer.AddTask(firstResponse, firstRespBasePos); linesDiffer.AddTask(secondResponse, secondRespBasePos); linesDiffer.DoDiff(); result.DiffsForFirst = linesDiffer.GetResultingDifferences(0); result.DiffsForSecond = linesDiffer.GetResultingDifferences(1); } //append the responses to the result text result.FirstText += firstResponse; result.SecondText += secondResponse; //sort and merge the resulting differences result.DiffsForFirst.MergeAll(); result.DiffsForSecond.MergeAll(); } return(result); }