/// <summary> /// Completes the HTTP request. /// </summary> /// <param name="ar">The result of the HTTP request.</param> private void OnRequestCompleted(IAsyncResult ar) { HttpWebResponse httpWebResponse = null; Stream inputStream = null; ConnectionInfo connectionInfo = null; try { connectionInfo = (ConnectionInfo)ar.AsyncState; HttpWebRequest httpWebRequest = connectionInfo.HttpWebRequest; #if (FRM20) // timeout has been already set try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.Timeout) { return; } } #else httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(ar); #endif this.Remote.Renew(this._hostRenewingSpan, false); // process the content inputStream = httpWebResponse.GetResponseStream(); #if DEBUG // if (this.ITransportContext.IEventLogger.AcceptBinaryData) // { // byte[] content = new byte[(int) httpWebResponse.ContentLength]; // GenuineUtility.ReadDataFromStream(inputStream, content, 0, content.Length); // // this.ITransportContext.IEventLogger.Log(LogMessageCategory.Traffic, null, "HttpInvocationConnection.OnRequestCompleted", // content, "The content of the response received by the HttpInvocationConnection. Size: {0}.", content.Length); // inputStream = new MemoryStream(content, false); // } #endif BinaryReader binaryReader = new BinaryReader(inputStream); string serverUri; int sequenceNo; HttpPacketType httpPacketType; int remoteHostUniqueIdentifier; HttpMessageCoder.ReadResponseHeader(binaryReader, out serverUri, out sequenceNo, out httpPacketType, out remoteHostUniqueIdentifier); #if DEBUG // this.ITransportContext.IEventLogger.Log(LogMessageCategory.TransportLayer, null, "HttpInvocationConnection.OnRequestCompleted", // null, "The invocation request returned. Server uri: {0}. Sequence no: {1}. Packet type: {2}. Content-encoding: {3}. Content-length: {4}. Protocol version: {5}. Response uri: \"{6}\". Server: \"{7}\". Status code: {8}. Status description: \"{9}\".", // serverUri, sequenceNo, Enum.Format(typeof(HttpPacketType), httpPacketType, "g"), // httpWebResponse.ContentEncoding, httpWebResponse.ContentLength, // httpWebResponse.ProtocolVersion, httpWebResponse.ResponseUri, // httpWebResponse.Server, httpWebResponse.StatusCode, httpWebResponse.StatusDescription); #endif // if the remote host has asked to terminate a connection if (httpPacketType == HttpPacketType.ClosedManually || httpPacketType == HttpPacketType.Desynchronization || httpPacketType == HttpPacketType.SenderError) { throw GenuineExceptions.Get_Receive_ConnectionClosed(); } // skip the first byte if (binaryReader.ReadByte() != 0) { if (!connectionInfo.Message.IsOneWay) { // this.ITransportContext.IEventLogger.Log(LogMessageCategory.FatalError, GenuineExceptions.Get_Processing_LogicError("The invocation response doesn't contain any messages."), "HttpInvocationConnection.OnRequestCompleted", // null, "The HTTP response doesn't contain content. The response to the request was not received."); } } else { // fetch and process the response messages using (BufferKeeper bufferKeeper = new BufferKeeper(0)) { using (LabelledStream labelledStream = new LabelledStream(this.ITransportContext, inputStream, bufferKeeper.Buffer)) { GenuineChunkedStream receivedRequest = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(labelledStream, receivedRequest); this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedRequest, this.Remote, GenuineConnectionType.Invocation, string.Empty, -1, true, null, null, null); } } } } catch (Exception ex) { // this.ITransportContext.IEventLogger.Log(LogMessageCategory.Error, ex, "HttpInvocationConnection.OnRequestCompleted", // null, "Exception occurred during receiving a response to an invocation request."); // dispatch the exception to the caller context if (connectionInfo != null) { this.ITransportContext.IIncomingStreamHandler.DispatchException(connectionInfo.Message, ex); } } finally { if (inputStream != null) { inputStream.Close(); } if (httpWebResponse != null) { httpWebResponse.Close(); } // release the connection if (connectionInfo != null) { this.ReleaseConnectionEntry(connectionInfo.Index); } } }
/// <summary> /// Reads messages from the stream and processes them. /// </summary> /// <param name="stream">The source stream.</param> /// <param name="xHttpPhysicalConnection">The connection.</param> private void LowLevel_ParseLabelledStream(Stream stream, XHttpPhysicalConnection xHttpPhysicalConnection) { BinaryReader binaryReader = new BinaryReader(stream); while ( binaryReader.ReadByte() == 0 ) { using (LabelledStream labelledStream = new LabelledStream(this.ITransportContext, stream, xHttpPhysicalConnection.AsyncReceiveBuffer)) { GenuineChunkedStream receivedContent = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(labelledStream, receivedContent); this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedContent, xHttpPhysicalConnection.Remote, xHttpPhysicalConnection.XHttpConnection.GenuineConnectionType, xHttpPhysicalConnection.XHttpConnection.ConnectionName, xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, false, null, xHttpPhysicalConnection.ConnectionLevelSecurity, null); } } }
/// <summary> /// Processes the sender's request. /// </summary> /// <param name="genuineConnectionType">The type of the connection.</param> /// <param name="input">The incoming data.</param> /// <param name="httpServerRequestResult">The request.</param> /// <param name="httpServerConnection">The connection.</param> /// <param name="sequenceNo">The sequence number.</param> /// <param name="remote">The information about remote host.</param> public void LowLevel_ProcessSenderRequest(GenuineConnectionType genuineConnectionType, Stream input, HttpServerRequestResult httpServerRequestResult, HttpServerConnection httpServerConnection, int sequenceNo, HostInformation remote) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; GenuineChunkedStream outputStream = null; // parse the incoming stream bool directExecution = genuineConnectionType != GenuineConnectionType.Persistent; BinaryReader binaryReader = new BinaryReader(input); using (BufferKeeper bufferKeeper = new BufferKeeper(0)) { switch(genuineConnectionType) { case GenuineConnectionType.Persistent: Exception gotException = null; try { if (httpServerConnection.Sender_SecuritySession != null) { input = httpServerConnection.Sender_SecuritySession.Decrypt(input); binaryReader = new BinaryReader(input); } while (binaryReader.ReadByte() == 0) using(LabelledStream labelledStream = new LabelledStream(this.ITransportContext, input, bufferKeeper.Buffer)) { GenuineChunkedStream receivedContent = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(labelledStream, receivedContent); this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedContent, httpServerConnection.Remote, genuineConnectionType, httpServerConnection.ConnectionName, httpServerConnection.DbgConnectionId, false, this._iMessageRegistrator, httpServerConnection.Sender_SecuritySession, httpServerRequestResult); } } catch(Exception ex) { gotException = ex; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.LowLevel_ProcessSenderRequest", LogMessageType.Error, ex, null, httpServerConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, httpServerConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Error occurred while processing the sender request N: {0}.", httpServerConnection.Sender_SequenceNo); } } if (gotException != null) { gotException = OperationException.WrapException(gotException); outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.SenderError, sequenceNo, remote); BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other)); binaryFormatter.Serialize(outputStream, gotException); } else { // serialize and send the empty response outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.SenderResponse, sequenceNo, remote); MessageCoder.FillInLabelledStream(null, null, null, outputStream, bufferKeeper.Buffer, (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]); } break; case GenuineConnectionType.Invocation: // register the http context as an invocation waiters string connectionGuid = Guid.NewGuid().ToString("N"); try { if (binaryReader.ReadByte() != 0) { // LOG: if ( binaryLogWriter != null ) { binaryLogWriter.WriteImplementationWarningEvent("HttpServerConnectionManager.LowLevel_ProcessSenderRequest", LogMessageType.Error, GenuineExceptions.Get_Debugging_GeneralWarning("The invocation request doesn't contain any messages."), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "The invocation request doesn't contain any messages."); } } using(LabelledStream labelledStream = new LabelledStream(this.ITransportContext, input, bufferKeeper.Buffer)) { // process the response this._invocation[connectionGuid] = null; this.ITransportContext.IIncomingStreamHandler.HandleMessage(labelledStream, remote, genuineConnectionType, connectionGuid, -1, true, null, null, httpServerRequestResult); } if (binaryReader.ReadByte() != 1) { // LOG: if ( binaryLogWriter != null ) { binaryLogWriter.WriteImplementationWarningEvent("HttpServerConnectionManager.LowLevel_ProcessSenderRequest", LogMessageType.Error, GenuineExceptions.Get_Debugging_GeneralWarning("The invocation request must not contain more than one message."), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "The invocation request must not contain more than one message."); } } // if there is a response, serialize it outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.Usual, sequenceNo, remote); Message message = this._invocation[connectionGuid] as Message; MessageCoder.FillInLabelledStream(message, null, null, outputStream, bufferKeeper.Buffer, (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]); } finally { this._invocation.Remove(connectionGuid); } break; } } // report back to the client Stream finalStream = outputStream; this.LowLevel_SendStream(httpServerRequestResult.HttpContext, false, null, true, ref finalStream, httpServerConnection); }
/// <summary> /// Reads messages from the stream and processes them. /// </summary> /// <param name="stream">The source stream.</param> /// <param name="intermediateBuffer">The intermediate buffer.</param> /// <param name="httpClientConnection">The connection.</param> /// <param name="connectionLevelSecuritySession">The Connection Level Security Session that decrypted this message.</param> public void LowLevel_ParseLabelledStream(Stream stream, byte[] intermediateBuffer, HttpClientConnection httpClientConnection, SecuritySession connectionLevelSecuritySession) { bool directExecution = httpClientConnection.GenuineConnectionType == GenuineConnectionType.Invocation; BinaryReader binaryReader = new BinaryReader(stream); while ( binaryReader.ReadByte() == 0 ) { using (LabelledStream labelledStream = new LabelledStream(this.ITransportContext, stream, intermediateBuffer)) { if (directExecution) this.ITransportContext.IIncomingStreamHandler.HandleMessage(labelledStream, httpClientConnection.Remote, httpClientConnection.GenuineConnectionType, httpClientConnection.ConnectionName, httpClientConnection.DbgConnectionId, true, null, connectionLevelSecuritySession, null); else { GenuineChunkedStream receivedContent = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(labelledStream, receivedContent); this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedContent, httpClientConnection.Remote, httpClientConnection.GenuineConnectionType, httpClientConnection.ConnectionName, httpClientConnection.DbgConnectionId, false, null, connectionLevelSecuritySession, null); } } } }