/// <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(); } } }
// This gets called after failure or success protected void OnRequestComplete() { RequestComplete?.Invoke(this, null); }
/// <summary> /// Sends the specified request to the server /// (Proxy not supported) /// </summary> /// <param name="parsedRequest"></param> /// <param name="host"></param> /// <param name="port"></param> /// <param name="https"></param> public void SendRequest(HttpRequestInfo parsedRequest, string host, int port, bool https) { _requestCompleteEvent.Reset(); _dataBuilder = new ByteArrayBuilder(); if (_connection == null) { _connection = new HttpClientConnection(host, port, https); } try { //connect if (_connection.Connect()) { bool isProxy = _connection.Host != host; //add connection closed header only this is supported at the moment parsedRequest.Headers["Connection"] = "close"; if (isProxy) { parsedRequest.Headers["Proxy-Connection"] = "close"; } // Turn off accepting of gzip/deflate //parsedRequest.Headers.Remove("Accept-Encoding"); //calculate the content length if (parsedRequest.ContentData != null) { parsedRequest.Headers["Content-Length"] = parsedRequest.ContentData.Length.ToString(); } parsedRequest.Host = host; parsedRequest.Port = port; parsedRequest.IsSecure = https; if (isProxy && https) { //send a connect message to the proxy SendConnect(host, port); } byte[] reqBytes = Constants.DefaultEncoding.GetBytes(parsedRequest.ToString(isProxy && !https)); //write to the stream _connection.Stream.Write(reqBytes, 0, reqBytes.Length); //start reading _buffer = new byte[MAX_BUFFER_SIZE]; _connection.Stream.BeginRead(_buffer, 0, MAX_BUFFER_SIZE, new AsyncCallback(ReadResponse), _connection.Stream); } else { throw new Exception("Cannot connect to server"); } } catch (Exception ex) { SdkSettings.Instance.Logger.Log(TraceLevel.Error, "HttpClient error sending request {0}", ex.Message); //notify the caller that the request was completed with an error if (RequestComplete != null) { RequestComplete.Invoke( new HttpClientRequestCompleteEventArgs()); RequestCompleteEvent.Set(); } _connection.Close(); } }
/// <summary> /// Request complete invoker /// </summary> protected void OnRequestComplete(Guid id, LogInfo requestLog, LogInfo responseLog) { RequestComplete?.Invoke(this, new RequestEventArgs(id, requestLog, responseLog)); }