/// <summary> /// Mutates a request in order to execute a test /// </summary> /// <param name="rawRequest"></param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="reqLocation"></param> /// <param name="entityString"></param> /// <param name="entityId"></param> /// <param name="testDef"></param> /// <returns></returns> public List <string> GenerateMutatedRequestList(string rawRequest, TestJob testJob, string entityString, string entityId) { //generate payload bool hasFuzz = rawRequest.Contains(Constants.FUZZ_STRING) || rawRequest.Contains(ENCODED_FUZZ); List <string> mutatedRequestsList = new List <string>(); List <string> payloadList = GeneratePayloadListFromMutation(rawRequest, testJob, hasFuzz, entityId); for (int i = 0; i < payloadList.Count; i++) { string payload = payloadList[i]; _testController.Log("Running test '{0}' with payload: '{1}'", testJob.TestDef.Name, payload); string mutatedRequest; if (hasFuzz) { mutatedRequest = rawRequest.Replace(Constants.FUZZ_STRING, payload); mutatedRequest = mutatedRequest.Replace(ENCODED_FUZZ, payload); } else if (entityString != null && OccurenceCount(entityString, testJob.ParameterValue) == 1) { string mutatedString = entityString.Replace(testJob.ParameterValue, payload); mutatedRequest = rawRequest.Replace(entityString, mutatedString); } else { //try to parse the request HttpRequestInfo mutatedReqInfo = new HttpRequestInfo(rawRequest, true); //attempt to find the parameter switch (testJob.RequestLocation) { case RequestLocation.Body: mutatedReqInfo.BodyVariables.Set(testJob.ParameterName, payload); break; case RequestLocation.Cookies: mutatedReqInfo.Cookies.Set(testJob.ParameterName, payload); break; case RequestLocation.Headers: mutatedReqInfo.Headers[testJob.ParameterName] = payload; break; case RequestLocation.Query: mutatedReqInfo.QueryVariables.Set(testJob.ParameterName, payload); break; case RequestLocation.Path: mutatedReqInfo.PathVariables.Set(testJob.ParameterName, payload); break; } mutatedRequest = mutatedReqInfo.ToString(); } //update dynamic values mutatedRequest = mutatedRequest.Replace("__dynamic_value__ticks__", (DateTime.Now.Ticks + i).ToString()); mutatedRequestsList.Add(mutatedRequest); } return(mutatedRequestsList); }
public void Test_HttpRequestInfo_QueryParameters_QRadarBug() { HttpRequestInfo reqInfo = new HttpRequestInfo("GET /console/do/core/genericsearchlist?appName=assets&pageId=VaScannerSchedulesList&countDown=true&columnSorting=true&orderBy=priority&sorting=asc&pageNumber=1 HTTP/1.1\r\n", true); string newRawReqInfo = reqInfo.ToString(); reqInfo = new HttpRequestInfo(newRawReqInfo, true); Assert.AreEqual("true", reqInfo.QueryVariables["columnSorting"]); }
public void Test_HttpRequestInfo_PseudoHeaders() { HttpRequestInfo reqInfo1 = new HttpRequestInfo("POST /1 HTTP/2.0"); reqInfo1.Headers.Add(":authority", "google.com"); Assert.AreEqual("google.com", reqInfo1.Headers[":authority"]); HttpRequestInfo reqInfo2 = new HttpRequestInfo(reqInfo1.ToString()); Assert.AreEqual("google.com", reqInfo2.Headers[":authority"]); Assert.AreEqual("google.com", reqInfo2.Host); }
public void Test_HttpRequestInfo_AddQueryVariables() { HttpRequestInfo reqInfo = new HttpRequestInfo(Resources.RequestWithEmptyQUery); Assert.AreEqual("/bank/login.aspx", reqInfo.PathAndQuery); reqInfo.QueryVariables.Add("a", "1"); Assert.AreEqual("/bank/login.aspx?a=1", reqInfo.PathAndQuery); reqInfo = new HttpRequestInfo(reqInfo.ToString()); reqInfo.QueryVariables.Add("b", "2"); Assert.AreEqual("/bank/login.aspx?a=1&b=2", reqInfo.PathAndQuery); }
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> /// Identifies aliases and in the first stage replaces them with the original value /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> protected override HttpRequestInfo OnBeforeRequestToSite(HttpRequestInfo requestInfo) { requestInfo = base.OnBeforeRequestToSite(requestInfo); _trackingReqInfo = null; //update the request info if (requestInfo.Path.Contains(AdvancedExploreProxyConnection.REQ_ID_STRING)) //this is an alias request { //get the req id string idString = Utils.RegexFirstGroupValue(requestInfo.Path, REQ_ID_RX); //load the original path int id; if (int.TryParse(idString, out id)) { _trackingReqInfo = _dataStore.GetRequestInfo(id); if (_trackingReqInfo != null) { var lastPath = _trackingReqInfo.UpdatedPath; if (String.IsNullOrWhiteSpace(lastPath)) { throw new Exception(String.Format("Original path not the traffic file for request id: {0}", id)); } else { HttpServerConsole.Instance.WriteLine("Path substituted to: '{0}'", lastPath); } requestInfo.Path = lastPath; AddSpecialHeader(requestInfo); _originalRawRequest = requestInfo.ToString(); } } } return(requestInfo); }
private TVRequestInfo SaveRequest(string description, HttpRequestInfo reqInfo, bool isSecure, string testResponse, DateTime requestTime, DateTime responseTime, string validation) { TVRequestInfo newReqInfo = new TVRequestInfo(); newReqInfo.Description = description; newReqInfo.Validation = validation; newReqInfo.Host = reqInfo.Host; newReqInfo.ResponseStatus = HttpResponseInfo.GetResponseStatus(testResponse); newReqInfo.RequestTime = requestTime; newReqInfo.IsHttps = isSecure; newReqInfo.ThreadId = Utils.GetCurrentWin32ThreadId().ToString(); newReqInfo.RequestLine = reqInfo.RequestLine; int newId = _trafficFile.AddRequestInfo(newReqInfo); _trafficFile.SaveRequest(newId, Constants.DefaultEncoding.GetBytes(reqInfo.ToString(false))); if (!String.IsNullOrWhiteSpace(testResponse)) { _trafficFile.SaveResponse(newId, Constants.DefaultEncoding.GetBytes(testResponse)); newReqInfo.ResponseTime = responseTime; } return(newReqInfo); }
private void RequestHandlerThread() { while (IsListening) { HttpRequestInfo reqInfo = null; HttpResponseInfo respInfo = null; int thisThreadRequestIndex = -1; lock (_lock) { reqInfo = null; if (_requestsToTest.Count > 0) { thisThreadRequestIndex = _requestsToTest.Dequeue(); _currentTestReqIdx = thisThreadRequestIndex; reqInfo = _requestIndex[thisThreadRequestIndex]; respInfo = _responseIndex[thisThreadRequestIndex]; } } if (reqInfo != null) { bool isSecure = reqInfo.IsSecure; string rawRequest = reqInfo.ToString(); string rawResponse = respInfo != null?respInfo.ToString() : String.Empty; if (ShouldBeTested(rawRequest)) { //parse parameters reqInfo = new HttpRequestInfo(rawRequest, true); reqInfo.IsSecure = isSecure; int hash = reqInfo.GetHashCode(TrafficServerMode.IgnoreCookies); lock (_lock) { if (_testedRequestHashes.Contains(hash)) { HttpServerConsole.Instance.WriteLine(LogMessageType.Warning, "Request already tested: '{0}'", reqInfo.FullUrl); continue; //we tested this request before } else { _testedRequestHashes.Add(hash); } } Uri reqUri = new Uri(reqInfo.FullUrl); MultiThreadedTestExecution testExecution = new MultiThreadedTestExecution(_tester, rawRequest, rawResponse, reqUri, _numThreads); lock (_lock) { GenerateEntities(thisThreadRequestIndex, reqInfo); testExecution.TestsQueue = _workList[thisThreadRequestIndex]; } testExecution.StartTestsAsync(); while (testExecution.IsRunning) { if (!IsListening) { testExecution.CancelTests(); break; } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Requests in queue: {0}, Tests in queue for current request: {1}, testing with {2} threads.", _requestsToTest.Count, testExecution.TestsQueue.Count, _numThreads); Thread.Sleep(1000); } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Test execution completed."); } } Thread.Sleep(10); } HttpServerConsole.Instance.WriteLine(LogMessageType.Notification, "Drive by Attack Proxy stopped."); }
/// <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); }
/// <summary> /// Handles a request /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> public HttpRequestInfo HandleRequest(HttpRequestInfo requestInfo, out bool mutated) { lock (_lock) { mutated = false; //make a request info that we parse in order to generate a hash and entities to test _curWorkingRawRequest = requestInfo.ToString(); if (!ShouldBeTested(_curWorkingRawRequest)) { return(requestInfo); } _curWorkingReqInfo = new HttpRequestInfo(_curWorkingRawRequest, true); _curWorkingReqInfo.IsSecure = requestInfo.IsSecure; int hash = _curWorkingReqInfo.GetHashCode(TrafficServerMode.IgnoreCookies); //get a hash including only the parameter names if (_firstRequestHash == 0) { _firstRequestHash = hash; } if (hash == _firstRequestHash) { if (_currentReqIdx > _detectedFlowRequests) { _detectedFlowRequests = _currentReqIdx + 1; } //reset the counter _currentReqIdx = 0; } else { //increment the request counter _currentReqIdx++; } if (_currentTestReqIdx < 0) //this is the first request { if (String.IsNullOrEmpty(_testFile.PatternOfFirstRequestToTest)) //if this is not the first request { _currentTestReqIdx = 0; } else { if (Utils.IsMatch(_curWorkingRawRequest, _testFile.PatternOfFirstRequestToTest)) { _currentTestReqIdx = _currentReqIdx; } } } if (_currentReqIdx == _currentTestReqIdx) { if (!_workList.ContainsKey(_currentTestReqIdx)) //no tests have been generated for this request { GenerateEntities(_currentReqIdx, _curWorkingReqInfo); } //this is the test request execute the next test Queue <TestJob> testQueue = _workList[_currentTestReqIdx]; if (testQueue.Count == 0 && _curMutatedRawReqQueue.Count == 0) { _currentTestReqIdx++; } else { if (_curMutatedRawReqQueue.Count == 0) { _curTestJob = testQueue.Dequeue(); //TODO: alter the request Uri workingReqUri = new Uri(_curWorkingReqInfo.FullUrl); _curEntityId = _tester.GetEntityId(workingReqUri, _curTestJob.ParameterName); string entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, _curTestJob.ParameterValue); if (entityString == null)//we could not find the parameter name /value combination { //try to obtain an updated value for the parameter string updatedParameterValue = GetUpdatedParameterValue(_curWorkingReqInfo, _curTestJob); entityString = _tester.GetEntityString(_curWorkingRawRequest, workingReqUri, _curTestJob.ParameterName, updatedParameterValue); } _curMutatedRequestList = _tester.GenerateMutatedRequestList(_curWorkingRawRequest, _curTestJob, entityString, _curEntityId); foreach (string req in _curMutatedRequestList) { _curMutatedRawReqQueue.Enqueue(req); } _curTestResponseCollection = new Dictionary <int, List <string> >(); //re-init the current test response list for multi response validation } //check again in case for some reason requests could not be generated (empty parameters) if (_curMutatedRawReqQueue.Count > 0) { //if multiple mutations are generated for the test then they need to be executed with each flow iteration _curMutatedRawReq = _curMutatedRawReqQueue.Dequeue(); //return the mutated request requestInfo = new HttpRequestInfo(_curMutatedRawReq, false); requestInfo.IsSecure = _curWorkingReqInfo.IsSecure; mutated = true; } } } } return(requestInfo); }
public void Test_HttpRequestInfo_ParsingWithoutParameters() { HttpRequestInfo reqInfo = new HttpRequestInfo(Resources.POSTRequest, false); Assert.AreEqual(Resources.POSTRequest, reqInfo.ToString()); }
/// <summary> /// Constructs an AppScan request format /// </summary> /// <param name="writer">The writer to write the request to</param> /// <param name="newHost"></param> /// <param name="newPort"></param> /// <param name="scheme"></param> /// <param name="reqInfo">Http request information</param> /// <param name="respInfo">Http response information</param> /// <param name="additionalAttributes">Additional attributes to be added to the request</param> protected void WriteRequest(XmlWriter writer, string newHost, int newPort, string scheme, HttpRequestInfo reqInfo, HttpResponseInfo respInfo, params KeyValuePair<string, string>[] additionalAttributes) { string host; int port; //check if the host needs to be changed if (String.IsNullOrEmpty(newHost)) { host = reqInfo.Host; } else { host = newHost; } if (newPort == 0) { port = reqInfo.Port; } else { port = newPort; } writer.WriteStartElement("request"); writer.WriteAttributeString("method", reqInfo.Method); writer.WriteAttributeString("scheme", scheme); writer.WriteAttributeString("httpVersion", reqInfo.HttpVersion); writer.WriteAttributeString("host", host); writer.WriteAttributeString("port", port.ToString()); writer.WriteAttributeString("path", reqInfo.Path); writer.WriteAttributeString("contentType", "OTHER"); writer.WriteAttributeString("boundary", ""); writer.WriteAttributeString("pathQuerySeparator", "?"); writer.WriteAttributeString("japEncoding", "0"); foreach (KeyValuePair<string, string> attribute in additionalAttributes) { writer.WriteAttributeString(attribute.Key, attribute.Value); } //write request body if there is one string postData = reqInfo.ContentDataString; int numberOfPatternParams = 0; if (reqInfo.QueryVariables.Count > 0 && !reqInfo.QueryVariables.MatchingDefinition.IsRegular) { numberOfPatternParams += reqInfo.QueryVariables.Count; } if (reqInfo.BodyVariables.Count > 0 && !reqInfo.BodyVariables.MatchingDefinition.IsRegular) { numberOfPatternParams += reqInfo.BodyVariables.Count; } writer.WriteAttributeString("numberOfPatternParameters", numberOfPatternParams.ToString()); writer.WriteStartElement("raw"); writer.WriteAttributeString("encoding", "none"); writer.WriteString(reqInfo.ToString()); writer.WriteEndElement(); if (!String.IsNullOrEmpty(postData)) { writer.WriteStartElement("body"); writer.WriteAttributeString("encodeValue", "true"); writer.WriteAttributeString("value", Utils.Base64Encode(postData)); writer.WriteEndElement(); } WriteParameters(writer, reqInfo.QueryVariables); WriteParameters(writer, reqInfo.BodyVariables); //writes the headers WriteHeaders(writer, host, port, reqInfo.Headers); //write cookies foreach (KeyValuePair<string, string> pair in reqInfo.Cookies) { writer.WriteStartElement("cookie"); writer.WriteAttributeString("name", pair.Key); writer.WriteAttributeString("value", pair.Value); writer.WriteEndElement(); } /*if(!String.IsNullOrWhiteSpace(reqInfo.ContentDataString) && Utils.IsMatch(reqInfo.ContentDataString,"W([\\w]+)_treeSel")) { writer.WriteRaw(Resources.ParametersDefinitions); }*/ //write response if (respInfo != null) { WriteResponse(writer, respInfo); } writer.WriteEndElement(); }
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); } } } }
private void TrackRequestContext(HttpRequestInfo requestInfo) { foreach (TrackingPattern pattern in _autoTrackingPatternList.Values) { string rawRequest = requestInfo.ToString(); string needle = Utils.RegexFirstGroupValue(rawRequest, pattern.RequestPattern); if (String.IsNullOrWhiteSpace(needle)) { continue; } //first search for the path of the current request in responses LineMatches results = SearchParameterValue(needle); if (results.Count == 0) { needle = Utils.UrlDecode(needle); results = SearchParameterValue(needle); } //if any of the two searches returned results if (results.Count != 0) { //get the last match to extract the request context var match = results[results.Count - 1]; CurrDataStoreRequestInfo.RefererId = match.RequestId; //replace the path in the match string requestContext = match.Line.Replace(needle, REQ_CONTEXT_ID); if (requestContext.Length > MAX_REQUEST_CONTEXT_SIZE) { requestContext = TrimRequestContext(requestContext); } //also replace hexadecimal values requestContext = Regex.Replace(requestContext, HEX_REGEX, HEX_VAL); //escape the line requestContext = Regex.Escape(requestContext); //insert the group requestContext = requestContext.Replace(REQ_CONTEXT_ID, RX_GROUP); //insert the HEX regex requestContext = requestContext.Replace(HEX_VAL, HEX_REGEX); CurrDataStoreRequestInfo.RequestContext = requestContext; CurrDataStoreRequestInfo.TrackingPattern = pattern.Name; TrafficDataStore.UpdateRequestInfo(CurrDataStoreRequestInfo); string originalPath = requestInfo.Path; CurrDataStoreRequestInfo.UpdatedPath = originalPath; //change the path of the request HttpRequestInfo newReq = new HttpRequestInfo(requestInfo.ToArray(false), false); //we are only replacing the last portion of the path and the query string to prevent relative path issues and also cookie path issues int lastIndexOfSlash = originalPath.LastIndexOf('/'); if (lastIndexOfSlash >= 0) { originalPath = originalPath.Substring(0, lastIndexOfSlash + 1); } newReq.Path = String.Format("{0}{1}{2}", originalPath, REQ_ID_STRING, CurrDataStoreRequestInfo.Id); TrafficDataStore.SaveRequest(CurrDataStoreRequestInfo.Id, newReq.ToArray(false)); HttpServerConsole.Instance.WriteLine ("Found request context for request '{0}' id: {1}, referer id:{2}", requestInfo.Path, CurrDataStoreRequestInfo.Id, CurrDataStoreRequestInfo.RefererId); HttpServerConsole.Instance.WriteLine (requestContext); return; //we can only have one tracking pattern per request } } }
/// <summary> /// Triggered before the request is sent to the site /// </summary> /// <param name="requestInfo"></param> /// <returns></returns> protected override HttpRequestInfo OnBeforeRequestToSite(HttpRequestInfo requestInfo) { bool wasModified = false; if (_requestReplacements != null) { string request = requestInfo.ToString(); foreach (string key in _requestReplacements.Keys) { if (Utils.IsMatch(request, key)) { request = Utils.ReplaceGroups(request, key, _requestReplacements[key]); wasModified = true; HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Request replacement applied for pattern: '{0}'", key); } } if (wasModified) { requestInfo = new HttpRequestInfo(request, false); //update the content length if (requestInfo.ContentData != null) { requestInfo.Headers["Content-Length"] = requestInfo.ContentData.Length.ToString(); } requestInfo.IsSecure = ClientStreamWrapper.IsSecure; } } if (!_isNonEssential) { var originalRawRequest = requestInfo.ToString(); //update tracked values string updatedRequest = PatternTracker.Instance.UpdateRequest(originalRawRequest); updatedRequest = UpdateDynamicPatterns(updatedRequest); if (!originalRawRequest.Equals(updatedRequest)) { bool isSecure = requestInfo.IsSecure; requestInfo = new HttpRequestInfo(updatedRequest, false); requestInfo.IsSecure = isSecure; wasModified = true; } if (wasModified) { //update the request in the file TrafficDataStore.SaveRequest(CurrDataStoreRequestInfo.Id, Constants.DefaultEncoding.GetBytes(updatedRequest)); } } if (CurrDataStoreRequestInfo != null) { //see if the request was trapped if (HttpTrap.Instance.TrapRequests && HttpTrap.Instance.TrapRequest(CurrDataStoreRequestInfo, requestInfo)) { //then we need to update the request info from the data source requestInfo = new HttpRequestInfo(TrafficDataStore.LoadRequestData(CurrDataStoreRequestInfo.Id), false); //update the content length if (requestInfo.ContentData != null) { requestInfo.Headers["Content-Length"] = requestInfo.ContentData.Length.ToString(); } requestInfo.IsSecure = ClientStreamWrapper.IsSecure; } } return(requestInfo); }