private void RunResponseBodyTest(string contentType, byte[] expectedBody, Encoding expectedEncoding) { ByteArrayBuilder builder = new ByteArrayBuilder(); byte[] responseHead = Constants.DefaultEncoding.GetBytes(String.Format("HTTP/1.1 200 OK\r\nContent-Type: {0}\r\nContent-Length: {1}\r\n\r\n", contentType, expectedBody.Length)); builder.AddChunkReference(responseHead, responseHead.Length); builder.AddChunkReference(expectedBody, expectedBody.Length); byte[] expectedResponseBytes = builder.ToArray(); HttpRequestInfo expectedRequest = new HttpRequestInfo("GET / HTTP/1.1\r\n\r\n"); HttpResponseInfo expectedResponse = new HttpResponseInfo(expectedResponseBytes); HttpRequestInfo receivedReqInfo; HttpResponseInfo receivedRespInfo; SendTestRequestToMockProxy(expectedRequest, expectedResponse, out receivedReqInfo, out receivedRespInfo); string receivedResponseBody = receivedRespInfo.ResponseBody.ToString(receivedRespInfo.Headers["Content-Type"]); Assert.AreEqual(expectedEncoding.GetString(expectedBody), receivedResponseBody); }
public void Test_HttpClient_RequestBody_POST_Binary() { ByteArrayBuilder builder = new ByteArrayBuilder(); byte [] requestHead = Encoding.UTF8.GetBytes("POST / HTTP/1.1\r\nContent-Type: application/octet-stream\r\nContent-Length:4\r\n\r\n"); builder.AddChunkReference(requestHead, requestHead.Length); builder.AddChunkReference(new byte[4] { 0, 1, 0, 1 }, 4); HttpRequestInfo reqInfo = new HttpRequestInfo(builder.ToArray()); HttpRequestInfo receivedRequestInfo; HttpResponseInfo receivedResponseInfo; SendTestRequestToMockProxy(reqInfo, new HttpResponseInfo("HTTP/1.1 200 OK\r\n\r\n"), out receivedRequestInfo, out receivedResponseInfo); byte [] respBody = receivedRequestInfo.ContentData.ToArray(); Assert.AreEqual(4, respBody.Length); Assert.AreEqual(0, respBody[0]); Assert.AreEqual(1, respBody[1]); Assert.AreEqual(0, respBody[2]); Assert.AreEqual(1, respBody[3]); }
public void TestClearChunk() { ByteArrayBuilder builder = new ByteArrayBuilder(); string firstChunk = "123"; string secondChunk = "ab"; byte[] firstChunkBytes = GetBytesFromString(firstChunk); byte[] secondChunkBytes = GetBytesFromString(secondChunk); builder.AddChunkReference(firstChunkBytes, 3); builder.AddChunkReference(secondChunkBytes, 2); byte[] returnedBytes = builder.ToArray(); string returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual("123ab", returnedBytesString); //now clear builder.ClearChunks(); Assert.AreEqual("", Encoding.UTF8.GetString(builder.ToArray())); //check that the index gets reset after clear builder.AddChunkReference(firstChunkBytes, 3); returnedBytes = builder.ReadChunk(); returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual(firstChunk, returnedBytesString); }
/// <summary> /// Adds a request to the current Traffic Viewer File /// </summary> /// <param name="request"></param> /// <param name="description"></param> private void AddAppScanRequest(XmlNode request, string description) { TVRequestInfo reqInfo = new TVRequestInfo(); reqInfo.Description = description; reqInfo.IsHttps = request.Attributes["scheme"] != null && request.Attributes["scheme"].Equals("https"); reqInfo.ThreadId = Properties.Resources.Settings; XmlNode rawRequestNode = request.SelectSingleNode("raw"); byte[] rawRequestBytes = new byte[0]; if (rawRequestNode.Attributes["encoding"] != null && rawRequestNode.Attributes["encoding"].Value.Equals("none")) { string rawRequest = String.Empty; rawRequest = rawRequestNode.InnerText; rawRequestBytes = Constants.DefaultEncoding.GetBytes(rawRequest); } reqInfo.RequestLine = HttpRequestInfo.GetRequestLine(rawRequestBytes); reqInfo.Id = _tvFile.AddRequestInfo(reqInfo); _tvFile.SaveRequest(reqInfo.Id, rawRequestBytes); XmlNode response = request.SelectSingleNode("response"); //put together the response if (response != null) { ByteArrayBuilder builder = new ByteArrayBuilder(); XmlNode headersNode = response.SelectSingleNode("headers"); if (headersNode != null && headersNode.Attributes["value"] != null) { builder.AddChunkReference(Constants.DefaultEncoding.GetBytes(headersNode.Attributes["value"].Value)); } XmlNode bodyNode = response.SelectSingleNode("body"); if (bodyNode != null) { bool isCompressed = bodyNode.Attributes["compressedBinaryValue"] != null && bodyNode.Attributes["compressedBinaryValue"].Value == "true"; string body = bodyNode.Attributes["value"].Value; byte[] bodyBytes = new byte[0]; if (isCompressed) { bodyBytes = Utils.DecompressBytesFromBase64String(body); } else { body = Utils.Base64Decode(body); bodyBytes = Constants.DefaultEncoding.GetBytes(body); } builder.AddChunkReference(bodyBytes); } _tvFile.SaveResponse(reqInfo.Id, builder.ToArray()); } }
/// <summary> /// Gets the bytes of the request /// </summary> /// <param name="isProxyHttp">Whether this is a request to a proxy</param> /// <returns></returns> public byte[] ToArray(bool isProxyHttp = false) { string requestHead = GetRequestHead(isProxyHttp); ByteArrayBuilder arrayBuilder = new ByteArrayBuilder(); byte[] requestHeadBytes = Constants.DefaultEncoding.GetBytes(requestHead); arrayBuilder.AddChunkReference(requestHeadBytes, requestHeadBytes.Length); if (ContentData != null) { arrayBuilder.AddChunkReference(ContentData, ContentData.Length); } return(arrayBuilder.ToArray()); }
/// Override to change the OnRead behavior /// </summary> /// <param name="ar"></param> protected override void OnRead(IAsyncResult ar) { try { if (Closed) { return; } IsBusy = true; HttpProxyClientStreamWrapper wrapper = (HttpProxyClientStreamWrapper)ar.AsyncState; int bytesRead = 0; bytesRead = wrapper.EndRead(ar); //we are still connected and we read more bytes if (bytesRead > 0) { lock (_proxyLock) { _requestBuilder = new ByteArrayBuilder(); // Append data to the request _requestBuilder.AddChunkReference(Buffer, bytesRead); // not finished keep on reading! ProcessMessage(); } } } catch (Exception ex) { HttpServerConsole.Instance.WriteLine(ex); Close(); } }
private void RunTest(string firstChunk, int firstChunkSize, string secondChunk, int secondChunkSize, string expectedResult, int maxSize) { ByteArrayBuilder builder = new ByteArrayBuilder(maxSize); builder.AddChunkReference(GetBytesFromString(firstChunk), firstChunkSize); builder.AddChunkReference(GetBytesFromString(secondChunk), secondChunkSize); string result = Encoding.UTF8.GetString(builder.ToArray()); Assert.AreEqual(expectedResult, result); if (firstChunkSize + secondChunkSize > maxSize) { Assert.IsTrue(builder.IsTruncated); } }
public void Test_HttpRequestInfo_BinaryContent() { byte[] expectedPostData = new byte[4] { 1, 0, 0, 5 }; string request = "POST / HTTP/1.1\r\nContent-Length: 4\r\n\r\n"; ByteArrayBuilder arrayBuilder = new ByteArrayBuilder(); byte[] requestBytes = Encoding.UTF8.GetBytes(request); arrayBuilder.AddChunkReference(requestBytes, requestBytes.Length); arrayBuilder.AddChunkReference(expectedPostData, expectedPostData.Length); HttpRequestInfo reqInfo = new HttpRequestInfo(arrayBuilder.ToArray()); Assert.AreEqual(4, reqInfo.ContentData.Length); Assert.AreEqual(reqInfo.ContentData[0], 1); Assert.AreEqual(reqInfo.ContentData[1], 0); Assert.AreEqual(reqInfo.ContentData[2], 0); Assert.AreEqual(reqInfo.ContentData[3], 5); }
/// <summary> /// Called to read the response asyncroneusly /// </summary> /// <param name="ar"></param> private void ReadResponse(IAsyncResult ar) { Stream stream = null; int bytesRead = 0; HttpClientResult result = HttpClientResult.Error; try { lock (_lock) { stream = (Stream)ar.AsyncState; bytesRead = stream.EndRead(ar); if (bytesRead > 0) { //add to the exiting data _dataBuilder.AddChunkReference(_buffer, bytesRead); //make a new chunk _buffer = new byte[MAX_BUFFER_SIZE]; //continue reading stream.BeginRead(_buffer, 0, MAX_BUFFER_SIZE, new AsyncCallback(ReadResponse), stream); } else { //construct the full response _response = _dataBuilder.ToArray(); result = HttpClientResult.Success; } } } catch { //we don't care that much for the errors that occur here } finally { if (bytesRead == 0) { //if the caller was waiting on the request complete event allow continuation _requestCompleteEvent.Set(); //we're done reading close the connection and trigger the event with the collected response //the result will be success if (RequestComplete != null) { RequestComplete.Invoke (new HttpClientRequestCompleteEventArgs(new HttpResponseInfo(_response))); } _connection.Close(); } } }
private void RunRequestBodyTest(string method, string contentType, byte [] expectedBody, Encoding expectedEncoding) { ByteArrayBuilder builder = new ByteArrayBuilder(); byte [] requestHead = Encoding.UTF8.GetBytes(String.Format("{0} / HTTP/1.1\r\nContent-Type: {1}\r\nContent-Length: {2}\r\n\r\n", method, contentType, expectedBody.Length)); builder.AddChunkReference(requestHead, requestHead.Length); builder.AddChunkReference(expectedBody, expectedBody.Length); HttpRequestInfo expectedRequest = new HttpRequestInfo(builder.ToArray(), false); HttpRequestInfo receivedReqInfo; HttpResponseInfo receivedRespInfo; SendTestRequestToMockProxy(expectedRequest, new HttpResponseInfo("HTTP/1.1 200 OK"), out receivedReqInfo, out receivedRespInfo); Assert.AreEqual(expectedEncoding.GetString(expectedBody), receivedReqInfo.ContentDataString); }
/// <summary> /// Called to read the response asyncroneusly /// </summary> /// <param name="ar"></param> private void ReadResponse(IAsyncResult ar) { lock (_proxyLock) { Stream stream = null; int bytesRead = 0; _isReading = true; try { stream = (Stream)ar.AsyncState; bytesRead = stream.EndRead(ar); _isReading = false; if (bytesRead > 0 && !ClientStreamWrapper.Closed) { //add to the exiting data _responseBuilder.AddChunkReference(_responseBuffer, bytesRead); byte[] chunk = new byte[bytesRead]; Array.Copy(_responseBuffer, chunk, bytesRead); //save the response send the response down the pipe HttpServerConsole.Instance.WriteLine(LogMessageType.Information, "Sending upstream binary response downstream"); _dataStore.SaveResponse(_messageReqInfo.Id, _responseBuilder.ToArray()); ClientStreamWrapper.Stream.Write(chunk, 0, chunk.Length); if (stream.CanRead && !_isReading) { _isReading = true; //continue reading stream.BeginRead(_responseBuffer, 0, MAX_BUFFER_SIZE, new AsyncCallback(ReadResponse), stream); } } else { Close(); } } catch { Close(); } finally { } } }
/// <summary> /// Override to change the OnRead behavior /// </summary> /// <param name="ar"></param> protected virtual void OnRead(IAsyncResult ar) { try { if (_stop || Closed) { return; } _isBusy = true; HttpProxyClientStreamWrapper wrapper = (HttpProxyClientStreamWrapper)ar.AsyncState; int bytesRead = 0; bytesRead = wrapper.EndRead(ar); //we are still connected and we read more bytes if (bytesRead > 0) { // Append data to the request _requestBuilder.AddChunkReference(Buffer, bytesRead); _requestInfo = new HttpRequestInfo(_requestBuilder.ToArray(), false); if (!_requestInfo.IsFullRequest) { // not finished keep on reading! wrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), wrapper); } else { lock (_proxyLock) { // Done reading, process the request ProcessRequest(); } } } else { //we read 0 bytes _isBusy = _requestBuilder.Length > 0; } } catch (Exception ex) { ClientStreamWrapper.Close(); HttpServerConsole.Instance.WriteLine(ex); } }
public void TestReadChunk() { ByteArrayBuilder builder = new ByteArrayBuilder(); string firstChunk = "123"; string secondChunk = "ab"; string thirdChunk = "--+"; byte[] firstChunkBytes = GetBytesFromString(firstChunk); byte[] secondChunkBytes = GetBytesFromString(secondChunk); byte[] thirdChunkBytes = GetBytesFromString(thirdChunk); builder.AddChunkReference(firstChunkBytes, 3); builder.AddChunkReference(secondChunkBytes, 2); builder.AddChunkReference(thirdChunkBytes, 3); byte[] returnedBytes = builder.ReadChunk(); string returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual(firstChunk, returnedBytesString); returnedBytes = builder.ReadChunk(); returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual(secondChunk, returnedBytesString); //reset the current chunk builder.ResetChunkPosition(); returnedBytes = builder.ReadChunk(); returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual(firstChunk, returnedBytesString); //read to end returnedBytes = builder.ReadChunk(); returnedBytes = builder.ReadChunk(); returnedBytes = builder.ReadChunk(); Assert.IsNull(returnedBytes); //test that the builder resets to the beggining now returnedBytes = builder.ReadChunk(); returnedBytesString = Encoding.UTF8.GetString(returnedBytes); Assert.AreEqual(firstChunk, returnedBytesString); }
private void SendConnect(string host, int port) { string connectRequest = String.Format(Resources.ConnectRequest, host, port); byte[] connectBytes = Constants.DefaultEncoding.GetBytes(connectRequest); _connection.Stream.Write(connectBytes, 0, connectBytes.Length); //read the response ByteArrayBuilder builder = new ByteArrayBuilder(); byte[] buffer = new byte[MAX_BUFFER_SIZE]; int bytesRead = _connection.Stream.Read(buffer, 0, MAX_BUFFER_SIZE); if (bytesRead > 0) { builder.AddChunkReference(buffer, bytesRead); } if (builder.Length == 0) { throw new Exception("No response to connect"); } else { HttpResponseInfo respInfo = new HttpResponseInfo(); respInfo.ProcessResponse(builder.ToArray()); if (respInfo.Status != 200) { throw new Exception("Connect response didn't get 200 status"); } else { //secure the connection _connection.SecureStream(host); } } }
/// <summary> /// Merges all the response chunks into one byte array /// </summary> /// <returns></returns> public byte[] ToArray() { ByteArrayBuilder builder = new ByteArrayBuilder(); builder.AddChunkReference(ResponseHead, ResponseHead.Length); if (ResponseBody != null) { if (ResponseBody.IsChunked) { byte[] chunk; byte[] chunkBuf; while ((chunk = ResponseBody.ReadChunk()) != null) { //write the chunk size line chunkBuf = Constants.DefaultEncoding.GetBytes(String.Format("{0:x}\r\n", chunk.Length)); builder.AddChunkReference(chunkBuf, chunkBuf.Length); //add the chunk builder.AddChunkReference(chunk, chunk.Length); //add a new line after the chunk chunkBuf = Constants.DefaultEncoding.GetBytes("\r\n"); builder.AddChunkReference(chunkBuf, chunkBuf.Length); } //write a last chunk with the value 0 // write the last chunk size chunkBuf = Constants.DefaultEncoding.GetBytes("0\r\n\r\n"); builder.AddChunkReference(chunkBuf, chunkBuf.Length); } else { byte[] chunk = ResponseBody.ToArray(); if (chunk != null) { builder.AddChunkReference(chunk, chunk.Length); } } } return(builder.ToArray()); }