private void TrafficViewSaveRequested(RequestTrafficViewSaveArgs e) { if (_currentId > -1) { //update the request info //parse the data HttpRequestInfo reqInfo = new HttpRequestInfo(e.Request); _responseBytes = Constants.DefaultEncoding.GetBytes(e.Response); HttpResponseInfo respInfo = new HttpResponseInfo(); respInfo.ProcessResponse(_responseBytes); TVRequestInfo currentTVInfo = _dataSource.GetRequestInfo(_currentId); //do not set the dom uniqueness id, needs to be explicitly calculated currentTVInfo.DomUniquenessId = String.Empty; currentTVInfo.RequestLine = reqInfo.RequestLine; currentTVInfo.RequestTime = DateTime.Now; currentTVInfo.ResponseStatus = respInfo.Status.ToString(); currentTVInfo.ResponseTime = DateTime.Now; currentTVInfo.Description = "Traffic Viewer Request"; currentTVInfo.ThreadId = "[0000]"; //convert the strings to bytes RequestResponseBytes reqData = new RequestResponseBytes(); reqData.AddToRequest(Constants.DefaultEncoding.GetBytes(e.Request)); reqData.AddToResponse(_responseBytes); //save the requests to the current data source _dataSource.SaveRequest(_currentId, reqData); _dataSource.SaveResponse(_currentId, reqData); _requestText = e.Request; _responseText = e.Response; } }
private void HandleFirstRequestLine(string line, byte[] lineBytes) { _currentThreadInfo.Location = LocationInThread.InsideRequest; //if a current request already exists in the thread this is end of that request //except in the case of AppScan standard where manual explore requests are doubled if (!Utils.IsMatch(_currentThreadInfo.Description, _proxyConnectionToSiteRegex) && _currentThreadInfo.CurrentRequests.Count > 0) { KeyValuePair <int, RequestResponseBytes> top = _currentThreadInfo.CurrentRequests.Pop(); TVRequestInfo header = _trafficViewerFile.GetRequestInfo(top.Key); if (header != null) { if (top.Value.RawResponse == null) //there is no response, time out { if (top.Value.RequestSize > header.RequestLength) { _trafficViewerFile.SaveRequest(top.Key, top.Value); } } else { //the request was already saved save the response if necessary if (top.Value.ResponseSize > header.ResponseLength) { _trafficViewerFile.SaveResponse(top.Key, top.Value); } } //this concludes the current request update the requests counter _thisSessionRequestCount++; } } //discard exclusions if (IsExcluded(line)) { _currentThreadInfo.Location = LocationInThread.Exclusion; return; } //create new request header _currentHeader = new TVRequestInfo(); _currentHeader.Description = _currentThreadInfo.Description; _currentHeader.ThreadId = _currentThreadInfo.ThreadId; _currentHeader.RequestLine = line; try { _currentHeader.RequestTime = DateTime.ParseExact(_currentTime, _timeFormat, _dateTimeFormatInfo); } catch { } //save newly created request header to the list of headers _currentIndex = _trafficViewerFile.AddRequestInfo(_currentHeader); if (lineBytes != null) //if lineBytes is null we are using the _currentRequestData { //create new requestdata _currentRequestData = new RequestResponseBytes(); _currentRequestData.AddToRequest(lineBytes); } _isNewThreadChunk = false; //push request header and request data to the stack of active requests for the current thread _currentThreadInfo.CurrentRequests.Push(new KeyValuePair <int, RequestResponseBytes>(_currentIndex, _currentRequestData)); //since a request line was encountered we are inside a request from now on }
private void HandleSendingRequestLine(string line) { byte[] bytes; bytes = ReadNextBytes(line, _sendingRequestRegex); if (bytes != null) { if (_currentRequestData == null || _currentRequestData.RawResponse != null) { _currentRequestData = new RequestResponseBytes(); _currentHeader = null; } _currentRequestData.AddToRequest(bytes); //check if this the start of a new request if (_currentHeader == null || String.IsNullOrEmpty(_currentHeader.RequestLine)) { string reqLine = HttpRequestInfo.GetRequestLine(_currentRequestData.RawRequest); //check if it's recognized as a valid request line if (_lineTypeSelector.GetLineType(reqLine) == LineType.FirstRequestLine) { HandleFirstRequestLine(reqLine, null); } } } }
/// <summary> /// Adds the request to the proxy data store /// </summary> protected void AddRequestToDataStore() { TVRequestInfo currDataStoreRequestInfo = new TVRequestInfo(); currDataStoreRequestInfo.RequestLine = _requestInfo.RequestLine; currDataStoreRequestInfo.Description = _requestDescription; currDataStoreRequestInfo.RequestTime = _currentRequestTime; currDataStoreRequestInfo.ThreadId = Utils.GetCurrentWin32ThreadId().ToString(); currDataStoreRequestInfo.IsHttps = _requestInfo.IsSecure; currDataStoreRequestInfo.Host = _requestInfo.Host; int reqId = TrafficDataStore.AddRequestInfo(currDataStoreRequestInfo); if (reqId != -1) { _currentRequestResponseBytes = new RequestResponseBytes(); _currentRequestResponseBytes.AddToRequest(_requestInfo.ToArray(false)); //saving the request in a direct to site format, since it will come //in proxy format GET http://site.com/ rather than GET /, //if we need a server to connect to the target the client will handle that TrafficDataStore.SaveRequest(reqId, _currentRequestResponseBytes); _currDataStoreRequestInfo = TrafficDataStore.GetRequestInfo(reqId); } }
private void HandleFirstResponseLine(string line, byte[] lineBytes) { //if you are inside an exclusion discard if (_currentThreadInfo.Location == LocationInThread.Exclusion) { return; } //if you never had a request before discard if (_currentIndex < 0) { return; } //save current request if (_currentRequestData.RawRequest != null) { if (_currentHeader != null && _currentHeader.RequestLength < _currentRequestData.RequestSize) { _trafficViewerFile.SaveRequest(_currentIndex, _currentRequestData); } } //handle the case when there are two or more subsequent responses on the same thread(AppScan Manual Explore) //the fact that we still have more than one requests in this threads stack means we //didn't finish to process the first while (_currentRequestData.RawResponse != null && _currentThreadInfo.CurrentRequests.Count > 1) { //the fact that we are now receiving the second response means that the first request is complete //extract the first request from the stack of current requests of the thread, save it and drop it KeyValuePair <int, RequestResponseBytes> top = _currentThreadInfo.CurrentRequests.Pop(); TVRequestInfo header = _trafficViewerFile.GetRequestInfo(top.Key); //save the response only if it has changed since last if (top.Value.ResponseSize > header.ResponseLength) { _trafficViewerFile.SaveResponse(top.Key, top.Value); } //update the request counter _thisSessionRequestCount++; //set the _currentRequestData to the next request data in the stack _currentRequestData = _currentThreadInfo.CurrentRequests.Peek().Value; _currentIndex = _currentThreadInfo.CurrentRequests.Peek().Key; _currentHeader = _trafficViewerFile.GetRequestInfo(_currentIndex); } if (lineBytes != null) { _currentRequestData.AddToResponse(lineBytes); } _isNewThreadChunk = false; _currentHeader.ResponseStatus = Utils.RegexFirstGroupValue(line, _responseStatusRegex); try { _currentHeader.ResponseTime = DateTime.ParseExact(_currentTime, _timeFormat, _dateTimeFormatInfo); } catch { } _currentThreadInfo.Location = LocationInThread.InsideResponse; }
public void EditTVF() { TrafficViewerFile tvf = UnitTestUtils.GenerateTestTvf(); //check delete int initialCount = tvf.RequestCount; //get the first request id int i = -1; TVRequestInfo first = tvf.GetNext(ref i); TVRequestInfo second = tvf.GetNext(ref i); HttpRequestInfo secondRequest = new HttpRequestInfo(tvf.LoadRequestData(second.Id)); HttpResponseInfo secondResponse = new HttpResponseInfo(); byte [] respBytes = tvf.LoadResponseData(second.Id); secondResponse.ProcessResponse(respBytes); int referenceResponseStatus = secondResponse.Status; int referenceHash = secondRequest.GetHashCode(); Assert.IsTrue(tvf.RemoveRequest(first.Id)); Assert.AreEqual(initialCount - 1, tvf.RequestCount); Assert.IsNull(tvf.GetPrevious(ref i)); RequestDataCache.Instance.Clear(); //check that //check add TVRequestInfo reqInfo = new TVRequestInfo(); reqInfo.RequestLine = "GET /newrequest HTTP/1.1"; string request = "GET /newrequest HTTP/1.1\r\nHeader1:1\r\n\r\n"; string response = "HTTP 200 OK\r\nHeader1:1\r\n\r\n<html><body>Added request</body></html>"; RequestResponseBytes reqData = new RequestResponseBytes(); reqData.AddToRequest(Constants.DefaultEncoding.GetBytes(request)); reqData.AddToResponse(Constants.DefaultEncoding.GetBytes(response)); tvf.AddRequestInfo(reqInfo); tvf.SaveRequest(reqInfo.Id, reqData); tvf.SaveResponse(reqInfo.Id, reqData); //Check that the request was added response = Constants.DefaultEncoding.GetString(tvf.LoadResponseData(reqInfo.Id)); Assert.AreEqual(38, response.IndexOf("Added request")); Assert.AreEqual(65, response.Length); //modify the recently added request slightly }
private void AddASERequest(XmlNode url) { XmlNode requestNode = url.SelectSingleNode("option[@enum='esCOTExploreRequest']"); XmlNode responseNode = url.SelectSingleNode("option[@enum='esCOTExploreResponse']"); XmlNode requestTypeNode = url.SelectSingleNode("option[@enum='elCOTExploreType']"); XmlNode responseHeaderNode = url.SelectSingleNode("option[@enum='esCOTExploreResponseHeader']"); ExploreType requestType = (ExploreType)int.Parse(requestTypeNode.Attributes["value"].Value); string description = String.Empty; switch (requestType) { case ExploreType.eETLogin: description = Resources.RecordedLoginPage; break; case ExploreType.eETRegularInSession: description = Resources.InSessionPage; break; case ExploreType.eETRegular: description = Resources.ManualExplore; break; } string request = requestNode.Attributes["value"].Value; request = Utils.Base64Decode(request); HttpRequestInfo reqInfo = new HttpRequestInfo(request); TVRequestInfo tvInfo = new TVRequestInfo(); tvInfo.RequestLine = reqInfo.RequestLine; tvInfo.ThreadId = Resources.Settings; tvInfo.Description = description; RequestResponseBytes data = new RequestResponseBytes(); data.AddToRequest(request); if (responseHeaderNode != null && responseHeaderNode.Attributes["value"] != null) { data.AddToResponse(responseHeaderNode.Attributes["value"].Value + Environment.NewLine); } byte[] response = Convert.FromBase64String(responseNode.Attributes["value"].Value); response = Utils.DecompressData(response); response = Encoding.Convert(Encoding.Unicode, Constants.DefaultEncoding, response); data.AddToResponse(response); //attempt to parse the response try { HttpResponseInfo respInfo = new HttpResponseInfo(); respInfo.ProcessResponse(data.RawResponse); tvInfo.ResponseStatus = respInfo.Status.ToString(); } catch { tvInfo.ResponseStatus = "???"; } _tvFile.AddRequestInfo(tvInfo); _tvFile.SaveRequest(tvInfo.Id, data); _tvFile.SaveResponse(tvInfo.Id, data); }
private void HandleBeginThread(string line) { //save current request if (_currentRequestData.RawRequest != null) { if (_currentHeader != null && _currentHeader.RequestLength < _currentRequestData.RequestSize) { _trafficViewerFile.SaveRequest(_currentIndex, _currentRequestData); } } _isNewThreadChunk = true; //the traffic might have been broken by the new line //extract a new thread id string currentThreadId = Utils.RegexFirstGroupValue(line, _threadIdRegex); string temp = Utils.RegexFirstGroupValue(line, _timeRegex); if (temp != String.Empty) { _currentTime = temp; } if (currentThreadId != String.Empty && currentThreadId != _currentThreadInfo.ThreadId) { //check if the thread exists if not create a new one if (_threads.ContainsKey(currentThreadId)) { _currentThreadInfo = _threads[currentThreadId]; if (_currentThreadInfo.CurrentRequests.Count > 0) { KeyValuePair <int, RequestResponseBytes> top = _currentThreadInfo.CurrentRequests.Peek(); _currentIndex = top.Key; _currentHeader = _trafficViewerFile.GetRequestInfo(_currentIndex); _currentRequestData = top.Value; } else { _currentIndex = -1; _currentHeader = null; _currentRequestData = new RequestResponseBytes(); } } else { ThreadInfo newInfo = new ThreadInfo(); newInfo.ThreadId = currentThreadId; _threads.Add(currentThreadId, newInfo); _currentThreadInfo = newInfo; _currentRequestData = new RequestResponseBytes(); } } //if a begin line occured resume the _current thread _currentThreadInfo.Suspended = false; string description = Utils.RegexFirstGroupValue(line, _descriptionRegex); if (description != String.Empty) { _currentThreadInfo.Description = description; } }
/// <summary> /// Writes a response to the client stream /// </summary> /// <param name="responseInfo"></param> protected virtual void ReturnResponse(HttpResponseInfo responseInfo) { HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Sending response: {0} for request: {1}", responseInfo.StatusLine, _requestInfo.RequestLine); if (_currDataStoreRequestInfo != null) { _currDataStoreRequestInfo.ResponseStatus = responseInfo.Status.ToString(); _currDataStoreRequestInfo.ResponseTime = DateTime.Now; } //process response headers if (responseInfo.Status == 401) { //we need to send the proxy support header/ or overwrite the existing proxy support header responseInfo.Headers["Proxy-Support"] = "Session-Based-Authentication"; } //if connection is close disconnect, or if the client sent us a connection close message if (String.Compare(responseInfo.Headers[CONNECTION_HEADER], "close", true) == 0 || String.Compare(_requestInfo.Headers[CONNECTION_HEADER], "close", true) == 0) { _isClose = true; } byte[] responseHead = HandleResponseByteChunk(responseInfo.ResponseHead); if (!TryWriteToStream(responseHead)) { return; } ; // Return the substitute response body if (responseInfo.ResponseBody.IsChunked) { byte[] chunk; byte[] chunkBuf; while ((chunk = responseInfo.ResponseBody.ReadChunk()) != null) { //write the chunk size line chunkBuf = Constants.DefaultEncoding.GetBytes(String.Format("{0:x}\r\n", chunk.Length)); chunkBuf = HandleResponseByteChunk(chunkBuf); if (!TryWriteToStream(chunkBuf)) { return; } //write the chunk chunk = HandleResponseByteChunk(chunk); if (!TryWriteToStream(chunk)) { return; } chunkBuf = Constants.DefaultEncoding.GetBytes("\r\n"); chunkBuf = HandleResponseByteChunk(chunkBuf); if (!TryWriteToStream(chunkBuf)) { return; } } //write a last chunk with the value 0 // write the last chunk size chunkBuf = Constants.DefaultEncoding.GetBytes("0\r\n\r\n"); chunkBuf = HandleResponseByteChunk(chunkBuf); if (!TryWriteToStream(chunkBuf)) { return; } } else { byte[] buffer = responseInfo.ResponseBody.ToArray(); if (buffer != null) { buffer = HandleResponseByteChunk(buffer); if (!TryWriteToStream(buffer)) { return; } } } //cleanup the request info _requestBuilder = new ByteArrayBuilder(); if (_currDataStoreRequestInfo != null) { TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, _currentRequestResponseBytes); } _currDataStoreRequestInfo = null; _currentRequestResponseBytes = null; //close the connection if the request had a connection close header if (_isClose) { ClientStreamWrapper.Close(); } else { _isBusy = false; ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper); } }