/// <summary> /// Creates and returns the Connection Level Security Session. /// </summary> /// <param name="genuineConnectionType">The type of the connection.</param> /// <returns>The created Security Session.</returns> internal SecuritySession CreateConnectionLevelSecuritySession(GenuineConnectionType genuineConnectionType) { // get connection-level SS string connectionLevelSSName = null; switch (genuineConnectionType) { case GenuineConnectionType.Persistent: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string; break; case GenuineConnectionType.Named: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForNamedConnections] as string; break; case GenuineConnectionType.Invocation: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForInvocationConnections] as string; break; } // create and return the Security Session if (connectionLevelSSName != null) { return(this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null)); } return(null); }
/// <summary> /// Returns a stream containing version of the using protocol and type of the connection being established. /// </summary> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">Type of the connection.</param> /// <param name="connectionId">The identifier of the connection.</param> /// <returns>BinaryWriter containing a stream with serialized data.</returns> public static BinaryWriter SerializeConnectionHeader(byte protocolVersion, GenuineConnectionType genuineConnectionType, string connectionId) { GenuineChunkedStream stream = new GenuineChunkedStream(false); BinaryWriter binaryWriter = new BinaryWriter(stream); binaryWriter.Write((byte)protocolVersion); binaryWriter.Write((byte)genuineConnectionType); binaryWriter.Write((string)connectionId); return(binaryWriter); }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">The host information.</param> /// <param name="genuineConnectionType">A value indicating what kind of connections will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; reason = GenuineExceptions.Get_Channel_ConnectionShutDown(reason); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } if (hostInformation == null) { this.InternalDispose(reason); return; } SharedMemoryConnection sharedMemoryConnection = null; if (hostInformation.Url != null) { sharedMemoryConnection = this._persistent[hostInformation.Url] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } sharedMemoryConnection = null; if (hostInformation.Uri != null) { sharedMemoryConnection = this._persistent[hostInformation.Uri] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } }
/// <summary> /// Parses the HTTP header. /// </summary> /// <param name="binaryReader">The source binary reader.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">The type of connection.</param> /// <param name="hostId">The identifier of the remote host.</param> /// <param name="httpPacketType">The type of the packet.</param> /// <param name="sequenceNo">The packet number.</param> /// <param name="connectionName">The name of the connection.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> public static void ReadRequestHeader(BinaryReader binaryReader, out byte protocolVersion, out GenuineConnectionType genuineConnectionType, out Guid hostId, out HttpPacketType httpPacketType, out int sequenceNo, out string connectionName, out int remoteHostUniqueIdentifier) { if (binaryReader.ReadByte() != MessageCoder.COMMAND_MAGIC_CODE) throw GenuineExceptions.Get_Receive_IncorrectData(); protocolVersion = binaryReader.ReadByte(); genuineConnectionType = (GenuineConnectionType) binaryReader.ReadByte(); hostId = new Guid(binaryReader.ReadBytes(16)); httpPacketType = (HttpPacketType) binaryReader.ReadByte(); sequenceNo = binaryReader.ReadInt32(); connectionName = "$/__GC/" + hostId; remoteHostUniqueIdentifier = 0; if (protocolVersion >= 0x1) { connectionName = binaryReader.ReadString(); remoteHostUniqueIdentifier = binaryReader.ReadInt32(); } }
/// <summary> /// Constructs an instance of the SecuritySessionParameters class. /// </summary> /// <param name="securitySessionName">The name of the Security Session.</param> /// <param name="securitySessionAttributes">Security Session parameters.</param> /// <param name="timeout">The invocation timeout or the TimeSpan.MinValue value to inherit the timeout from channel or Transport Context settings.</param> /// <param name="remoteTransportUser">For load balancing or dispatching the invocation to the specific known appdomain.</param> public SecuritySessionParameters(string securitySessionName, SecuritySessionAttributes securitySessionAttributes, TimeSpan timeout, string remoteTransportUser) { this.Name = securitySessionName; this.Attributes = securitySessionAttributes; this.Timeout = timeout; this._genuineConnectionType = GenuineConnectionType.Persistent; this.RemoteTransportUser = remoteTransportUser; }
/// <summary> /// Constructs an instance of the SecuritySessionParameters class. /// </summary> /// <param name="securitySessionName">The name of the Security Session.</param> /// <param name="securitySessionAttributes">Security Session parameters.</param> /// <param name="timeout">The invocation timeout or the TimeSpan.MinValue value to inherit the timeout from channel or Transport Context settings.</param> /// <param name="genuineConnectionType">Type of the connection being used. The connection type must be support by the corresponding connection manager.</param> /// <param name="connecitonName">The name of the connection if named connection type is specified.</param> /// <param name="closeAfterInactivity">The time of inactivity to close a connection or TimeSpan.MinValue to inherit this value from channel or Transport Context parameters.</param> /// <param name="remoteTransportUser">For load balancing or dispatching the invocation to the specific known appdomain.</param> public SecuritySessionParameters(string securitySessionName, SecuritySessionAttributes securitySessionAttributes, TimeSpan timeout, GenuineConnectionType genuineConnectionType, string connecitonName, TimeSpan closeAfterInactivity, string remoteTransportUser) { this.Name = securitySessionName; this.Attributes = securitySessionAttributes; this.Timeout = timeout; this._genuineConnectionType = genuineConnectionType; this._connectionName = connecitonName; this.CloseAfterInactivity = closeAfterInactivity; this.RemoteTransportUser = remoteTransportUser; }
/// <summary> /// Processes incoming requests and responses. /// </summary> /// <param name="stream">The stream containing a request or a response.</param> /// <param name="remote">The remote host.</param> /// <param name="genuineConnectionType">The type of the connection.</param> /// <param name="connectionName">Connection id to send a response through.</param> /// <param name="dbgConnectionId">The identifier of the connection, which is used for debugging purposes only.</param> /// <param name="useThisThread">True to invoke the target in the current thread.</param> /// <param name="iMessageRegistrator">The message registrator.</param> /// <param name="connectionLevelSecuritySession">Connection Level Security Session.</param> /// <param name="httpServerRequestResult">The HTTP request through which the message was received.</param> /// <returns>True if it's a one-way message.</returns> public bool HandleMessage(Stream stream, HostInformation remote, GenuineConnectionType genuineConnectionType, string connectionName, int dbgConnectionId, bool useThisThread, IMessageRegistrator iMessageRegistrator, SecuritySession connectionLevelSecuritySession, HttpServerRequestResult httpServerRequestResult) { // read the Security Session name BinaryReader binaryReader = new BinaryReader(stream); string sessionName = binaryReader.ReadString(); Message message = null; BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; // and decode the packet SecuritySession securitySession = remote.GetSecuritySession(sessionName, this.ITransportContext.IKeyStore); if (securitySession == null) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage", LogMessageType.SecuritySessionApplied, GenuineExceptions.Get_Security_ContextNotFound(sessionName), message, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, sessionName, dbgConnectionId, 0, 0, 0, null, null, null, null, "The requested Security Session can not be constructed or established. The name of Security Session: {0}.", sessionName); } this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.SecuritySessionWasNotFound, GenuineExceptions.Get_Security_ContextNotFound(sessionName), remote, null)); return true; } // decode the stream and roll back if it was a Security Session's message stream = securitySession.Decrypt(stream); if (stream == null) return true; // read the message message = MessageCoder.Deserialize(stream, sessionName); message.ConnectionName = connectionName; message.SecuritySessionParameters._connectionName = connectionName; message.SecuritySessionParameters._genuineConnectionType = genuineConnectionType; message.Sender = remote; message.ITransportContext = this.ITransportContext; message.ConnectionLevelSecuritySession = connectionLevelSecuritySession; message.HttpServerRequestResult = httpServerRequestResult; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage", LogMessageType.SecuritySessionApplied, null, message, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, sessionName, dbgConnectionId, 0, 0, 0, null, null, null, null, "The Security Session has been used for decrypting the message."); } // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 ) { bool readContent = this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1; if (readContent) { GenuineChunkedStream streamClone = new GenuineChunkedStream(); GenuineUtility.CopyStreamToStream(message.Stream, streamClone); message.Stream = streamClone; } binaryLogWriter.WriteMessageCreatedEvent("GenuineReceivingHandler.HandleMessage", LogMessageType.MessageReceived, null, message, message.ReplyToId > 0, remote, readContent ? message.Stream : null, message.ITransportHeaders[Message.TransportHeadersInvocationTarget] as string, message.ITransportHeaders[Message.TransportHeadersMethodName] as string, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, connectionName, dbgConnectionId, connectionLevelSecuritySession == null ? -1 : connectionLevelSecuritySession.SecuritySessionId, connectionLevelSecuritySession == null ? null : connectionLevelSecuritySession.Name, securitySession == null ? -1 : securitySession.SecuritySessionId, securitySession.Name, "The message has been received."); } if (message.ReplyToId == PING_MESSAGE_REPLYID) return true; if (iMessageRegistrator != null && iMessageRegistrator.WasRegistered(remote.Uri, message.MessageId, message.ReplyToId)) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 ) binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineReceivingHandler.HandleMessage", LogMessageType.MessageDispatched, GenuineExceptions.Get_Debugging_GeneralWarning("The message has been already processed."), message, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, securitySession.Name, dbgConnectionId, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null, "The message has been already processed. Therefore, this message is ignored."); return true; } // if it's a response, then direct the message to the response handler if (message.ReplyToId > 0) { message.IsOneWay = true; IResponseProcessor iResponseProcessor = GenuineReceivingHandler._responseHandlers[message.ReplyToId] as IResponseProcessor; // nothing waits for this request if (iResponseProcessor == null) return true; // 2.5.1: set the answer flag if (iResponseProcessor.Message != null) iResponseProcessor.Message.HasBeenAsnwered = true; if (iResponseProcessor.IsShortInProcessing) { iResponseProcessor.ProcessRespose(message); #if TRIAL #else if (iResponseProcessor.IsExpired(GenuineUtility.TickCount)) GenuineReceivingHandler._responseHandlers.Remove(message.ReplyToId); #endif return true; } } // take care about the thread and call context if (useThisThread) InternalExecuteMessage(message); else GenuineThreadPool.QueueUserWorkItem(this._waitCallback_InternalExecuteMessagewaitCallback, message, false); return message.IsOneWay; }
/// <summary> /// Closes all connections that fit to the specified characteristics. /// Automatically releases all resources acquired by connections being closed. /// </summary> /// <param name="hostInformation">The host or a null reference to embrace all remote hosts.</param> /// <param name="genuineConnectionType">Specifies what connection patterns will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing that will be dispatched to all callers waiting something from the connections being closed.</param> public abstract void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason);
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">The host information.</param> /// <param name="genuineConnectionType">A value indicating what kind of connections will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; reason = GenuineExceptions.Get_Channel_ConnectionShutDown(reason); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } if (hostInformation == null) { this.InternalDispose(reason); return ; } SharedMemoryConnection sharedMemoryConnection = null; if (hostInformation.Url != null) sharedMemoryConnection = this._persistent[hostInformation.Url] as SharedMemoryConnection; if (sharedMemoryConnection != null) this.ConnectionFailed(reason, sharedMemoryConnection); sharedMemoryConnection = null; if (hostInformation.Uri != null) sharedMemoryConnection = this._persistent[hostInformation.Uri] as SharedMemoryConnection; if (sharedMemoryConnection != null) this.ConnectionFailed(reason, sharedMemoryConnection); }
/// <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> /// Writes HTTP header to the specified binary writer. /// </summary> /// <param name="binaryWriter">The binary writer.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">The type of connection.</param> /// <param name="hostId">The id of the remote host.</param> /// <param name="httpPacketType">The type of the packet.</param> /// <param name="sequenceNo">The packet number.</param> /// <param name="connectionName">The name of the connection.</param> /// <param name="localHostUniqueIdentifier">The unique identifier of the local HostInformation.</param> public static void WriteRequestHeader(BinaryWriter binaryWriter, byte protocolVersion, GenuineConnectionType genuineConnectionType, byte[] hostId, HttpPacketType httpPacketType, int sequenceNo, string connectionName, int localHostUniqueIdentifier) { binaryWriter.Write((byte)MessageCoder.COMMAND_MAGIC_CODE); binaryWriter.Write((byte)protocolVersion); binaryWriter.Write((byte)genuineConnectionType); binaryWriter.Write(hostId); binaryWriter.Write((byte)httpPacketType); binaryWriter.Write((int)sequenceNo); binaryWriter.Write(connectionName); binaryWriter.Write((int)localHostUniqueIdentifier); }
/// <summary> /// Sends HTTP content to the remote host. /// Does not process exceptions. /// Automatically initiates asynchronous receiving. /// Automatically manages stream seqNo for clients' connections. /// </summary> /// <param name="timeout">Operation timeout.</param> /// <param name="message">The message.</param> /// <param name="content">The content sent instead of the message.</param> /// <param name="exceptionToBeSent">The exception being sent in the response.</param> /// <param name="messageContainer">The message container.</param> /// <param name="xHttpPhysicalConnection">The physical connection.</param> /// <param name="genuineConnectionType">The type of the connection.</param> /// <param name="httpPacketType">The type of the HTTP packet.</param> /// <param name="repeatSending">Whether the content was already packed.</param> /// <param name="synchronous">Whether to send content synchronously.</param> /// <param name="startAutomaticReceiving">Indicates whether to start automatic receiving of the response/request if the type of the sending is synchronous.</param> /// <param name="applyClss">A boolean value indicating whether the CLSS should be applied.</param> private void LowLevel_SendHttpContent(int timeout, Message message, GenuineChunkedStream content, Exception exceptionToBeSent, MessageContainer messageContainer, XHttpPhysicalConnection xHttpPhysicalConnection, GenuineConnectionType genuineConnectionType, HttpPacketType httpPacketType, bool repeatSending, bool synchronous, bool startAutomaticReceiving, bool applyClss ) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; // check whether the connection is valid and available xHttpPhysicalConnection.CheckConnectionStatus(); // prevent the ping if (! xHttpPhysicalConnection.IsSender) xHttpPhysicalConnection.XHttpConnection.LastTimeContentWasSent = GenuineUtility.TickCount; // valid copies Socket socket; Stream sentContent; // to prevent from changing sequence information or disposing sent content during its encryption lock (xHttpPhysicalConnection.PhysicalConnectionStateLock) { if (! repeatSending) { if (xHttpPhysicalConnection.XHttpConnection.IsClient) xHttpPhysicalConnection.SequenceNo ++; if (message != null || (message == null && content == null && exceptionToBeSent == null)) { GenuineChunkedStream packedMessages = new GenuineChunkedStream(false); MessageCoder.FillInLabelledStream(message, messageContainer, xHttpPhysicalConnection.MessagesBeingSent, packedMessages, xHttpPhysicalConnection.AsyncSendBuffer, (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0 ) { for ( int i = 0; i < xHttpPhysicalConnection.MessagesBeingSent.Count; i++) { Message nextMessage = (Message) xHttpPhysicalConnection.MessagesBeingSent[i]; binaryLogWriter.WriteEvent(LogCategory.Transport, "XHttpConnectionManager.LowLevel_SendHttpContent", LogMessageType.MessageIsSentAsynchronously, null, nextMessage, xHttpPhysicalConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, xHttpPhysicalConnection.ConnectionLevelSecurity, null, xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, xHttpPhysicalConnection.SequenceNo, 0, 0, null, null, null, null, "The message will be sent in the {0} stream N: {1}.", xHttpPhysicalConnection == xHttpPhysicalConnection.XHttpConnection.Sender ? "SENDER" : "LISTENER", xHttpPhysicalConnection.SequenceNo); } } xHttpPhysicalConnection.SentContent = packedMessages; } else if (content != null) { xHttpPhysicalConnection.MessagesBeingSent.Clear(); xHttpPhysicalConnection.SentContent = content; } else //if (exceptionToBeSent != null) { #if DEBUG Debug.Assert(httpPacketType == HttpPacketType.SenderError); #endif Exception exception = OperationException.WrapException(exceptionToBeSent); GenuineChunkedStream output = new GenuineChunkedStream(false); BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other)); binaryFormatter.Serialize(output, exception); xHttpPhysicalConnection.MessagesBeingSent.Clear(); xHttpPhysicalConnection.SentContent = output; } // client applies CLSSE only to the actual content if (applyClss && xHttpPhysicalConnection.XHttpConnection.IsClient && xHttpPhysicalConnection.ConnectionLevelSecurity != null) { GenuineChunkedStream encryptedContent = new GenuineChunkedStream(false); xHttpPhysicalConnection.ConnectionLevelSecurity.Encrypt(xHttpPhysicalConnection.SentContent, encryptedContent); xHttpPhysicalConnection.SentContent = encryptedContent; } // write the binary header GenuineChunkedStream resultStream = new GenuineChunkedStream(false); BinaryWriter binaryWriter = new BinaryWriter(resultStream); if (xHttpPhysicalConnection.XHttpConnection.IsClient) HttpMessageCoder.WriteRequestHeader(binaryWriter, MessageCoder.PROTOCOL_VERSION, genuineConnectionType, xHttpPhysicalConnection.XHttpConnection.HostId, httpPacketType, xHttpPhysicalConnection.SequenceNo, xHttpPhysicalConnection.XHttpConnection.ConnectionName, xHttpPhysicalConnection.XHttpConnection.Remote.LocalHostUniqueIdentifier); else HttpMessageCoder.WriteResponseHeader(binaryWriter, xHttpPhysicalConnection.XHttpConnection.Remote.ProtocolVersion, this.ITransportContext.ConnectionManager.Local.Uri, xHttpPhysicalConnection.SequenceNo, httpPacketType, xHttpPhysicalConnection.XHttpConnection.Remote.LocalHostUniqueIdentifier); resultStream.WriteStream(xHttpPhysicalConnection.SentContent); xHttpPhysicalConnection.SentContent = resultStream; // while server applies CLSSE to the entire response (except HTTP stuff, of course) if (applyClss && ! xHttpPhysicalConnection.XHttpConnection.IsClient && xHttpPhysicalConnection.ConnectionLevelSecurity != null) { GenuineChunkedStream encryptedContent = new GenuineChunkedStream(false); xHttpPhysicalConnection.ConnectionLevelSecurity.Encrypt(xHttpPhysicalConnection.SentContent, encryptedContent); xHttpPhysicalConnection.SentContent = encryptedContent; } // generally it's impossible to have xHttpPhysicalConnection.SentContent without available length in the current implementation // nevertheless, it's necessary to calculate the final length of the content if it's unknown if (! xHttpPhysicalConnection.SentContent.CanSeek) { GenuineChunkedStream actualContent = new GenuineChunkedStream(false); GenuineUtility.CopyStreamToStream(xHttpPhysicalConnection.SentContent, actualContent, xHttpPhysicalConnection.AsyncSendBuffer); xHttpPhysicalConnection.SentContent = actualContent; } // write the header and compose final content resultStream = new GenuineChunkedStream(false); StreamWriter streamWriter = new StreamWriter(new NonClosableStream(resultStream), Encoding.ASCII, 3500); if (xHttpPhysicalConnection.XHttpConnection.IsClient) streamWriter.Write("POST /{0} HTTP/1.1\r\nAccept: */*\r\nContent-Type: application/octet-stream\r\nContent-Length: {1}\r\nUser-Agent: {2}\r\nHost: {3}\r\nConnection: Keep-Alive\r\nPragma: no-cache\r\n\r\n", xHttpPhysicalConnection.EntryUri, xHttpPhysicalConnection.SentContent.Length, xHttpPhysicalConnection.XHttpConnection.UserAgent, xHttpPhysicalConnection.LocalEndPoint); else { string now = DateTime.Now.ToString("r"); streamWriter.Write("HTTP/1.1 200 OK\r\nServer: GXHTTP\r\nDate: {0}\r\nX-Powered-By: Genuine Channels\r\nCache-Control: private\r\nContent-Type: application/octet-stream\r\nContent-Length: {1}\r\n\r\n", now, xHttpPhysicalConnection.SentContent.Length); } streamWriter.Flush(); streamWriter.Close(); resultStream.WriteStream(xHttpPhysicalConnection.SentContent); xHttpPhysicalConnection.SentContent = resultStream; } else { xHttpPhysicalConnection.SentContent.Position = 0; } socket = xHttpPhysicalConnection.Socket; sentContent = xHttpPhysicalConnection.SentContent; } // lock (xHttpPhysicalConnection.PhysicalConnectionStateLock) if (synchronous) { // send the content SyncSocketWritingStream syncSocketWritingStream = new SyncSocketWritingStream(this, socket, timeout, xHttpPhysicalConnection.XHttpConnection.DbgConnectionId, xHttpPhysicalConnection.Remote); GenuineUtility.CopyStreamToStreamPhysically(sentContent, syncSocketWritingStream, xHttpPhysicalConnection.AsyncSendBuffer); // automatically start receiving the response/request if (startAutomaticReceiving) { if (xHttpPhysicalConnection.XHttpConnection.IsClient) this.LowLevel_HalfSync_Client_StartReceiving(xHttpPhysicalConnection); else this.LowLevel_HalfSync_Server_StartReceiving(xHttpPhysicalConnection.Socket); } } else { xHttpPhysicalConnection.AsyncSendBufferCurrentPosition = 0; xHttpPhysicalConnection.AsyncSendBufferIsLastPacket = false; xHttpPhysicalConnection.AsyncSendBufferSizeOfValidContent = 0; xHttpPhysicalConnection.AsyncSendStream = sentContent; this.LowLevel_InitiateAsyncSending(xHttpPhysicalConnection); } }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">Host information.</param> /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param> /// <param name="reason">Reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; ArrayList connectionsToClose = new ArrayList(); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" are terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } using (new WriterAutoLocker(this._disposeLock)) { // persistent if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 ) { ReleaseConnections_Parameters releaseConnections_Parameters = new ReleaseConnections_Parameters(); releaseConnections_Parameters.FailedConnections = connectionsToClose; releaseConnections_Parameters.HostInformation = hostInformation; this._persistent.InspectAllConnections(this._releaseConnections_InspectPersistentConnections, releaseConnections_Parameters); } } // close connections foreach (XHttpConnection nextXHttpConnection in connectionsToClose) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "XHttpConnectionManager.ReleaseConnections", LogMessageType.ConnectionShuttingDown, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, nextXHttpConnection.DbgConnectionId, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connection is terminated."); } this.ConnectionFailed(GenuineExceptions.Get_Channel_ConnectionShutDown(reason), nextXHttpConnection, null); if (nextXHttpConnection.GenuineConnectionType == GenuineConnectionType.Persistent) nextXHttpConnection.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null); } }
/// <summary> /// Parses HTTP request or response. /// </summary> /// <param name="timeout">The reading timeout.</param> /// <param name="client">Specifies the parsing logic.</param> /// <param name="socket">The connection.</param> /// <param name="connectionLevelSecurity">Connection-level Security Session.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="uri">The URI of the remote host.</param> /// <param name="sequenceNo">The sequence no of the parsing packet.</param> /// <param name="genuineConnectionType">The type of the connection.</param> /// <param name="hostId">The identifier of the host.</param> /// <param name="httpPacketType">The type of the HTTP packet.</param> /// <param name="connectionName">The name of the connection.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> /// <returns>A stream based on the specified socket.</returns> private Stream LowLevel_ParseHttpContent(int timeout, bool client, Socket socket, SecuritySession connectionLevelSecurity, out byte protocolVersion, out string uri, out int sequenceNo, out GenuineConnectionType genuineConnectionType, out Guid hostId, out HttpPacketType httpPacketType, out string connectionName, out int remoteHostUniqueIdentifier) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; protocolVersion = MessageCoder.PROTOCOL_VERSION; uri = null; genuineConnectionType = GenuineConnectionType.None; hostId = Guid.Empty; httpPacketType = HttpPacketType.Unkown; connectionName = null; // read the entire header Stream inputStream = new BufferedStream(new SyncSocketStream(socket, this, timeout)); int contentLength = -1; #if DEBUG GenuineChunkedStream httpHeadersContent = new GenuineChunkedStream(false); StreamWriter httpTraffic = new StreamWriter(httpHeadersContent); #endif GXHTTPHeaderParser gxhttpHeaderParser = new GXHTTPHeaderParser(client); int indexOfFirstDigit; int indexOfLastDigit; for ( ; ; ) { string line = this.LowLevel_ReadToUpperLine(inputStream, out indexOfFirstDigit, out indexOfLastDigit); #if DEBUG httpTraffic.Write(line); httpTraffic.Write(Environment.NewLine); #endif if (line.Length <= 0) break; if (gxhttpHeaderParser.ParseHeader(line, indexOfFirstDigit, indexOfLastDigit) == GXHTTPHeaderParser.HeaderFields.Expect100Continue && gxhttpHeaderParser.IsHttp11) this.LowLevel_Send100Continue(socket); } contentLength = (int) gxhttpHeaderParser.ContentLength; #if DEBUG // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 ) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "XHttpConnectionManager.LowLevel_ParseHttpContent", LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, null, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? httpHeadersContent : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, -1, contentLength, socket.RemoteEndPoint.ToString(), null, null, "XHTTP Headers parsed. Content Length: {0}.", contentLength); } httpHeadersContent.Dispose(); #endif // ok, the header has been successfully skipped if (contentLength < 0) throw GenuineExceptions.Get_Receive_IncorrectData(); // TODO: fix this! there is socket -> buffer -> delimiter chain, while it must be socket -> delimiter -> buffer // and we know the content length inputStream = new DelimiterStream(inputStream, contentLength); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0 ) { GenuineChunkedStream contentCopy = null; bool writeContent = binaryLogWriter[LogCategory.LowLevelTransport] > 1; if (writeContent) { contentCopy = new GenuineChunkedStream(false); GenuineUtility.CopyStreamToStream(inputStream, contentCopy, contentLength); } binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "XHttpConnectionManager.LowLevel_ParseHttpContent", LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, null, writeContent ? contentCopy : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, -1, contentLength, socket.RemoteEndPoint.ToString(), null, null, "XHTTP Message.", contentLength); if (writeContent) inputStream = contentCopy; } // server always encrypts the entire content, including response headers if (client && connectionLevelSecurity != null && connectionLevelSecurity.IsEstablished) inputStream = connectionLevelSecurity.Decrypt(inputStream); BinaryReader binaryReader = new BinaryReader(inputStream); // read binary header if (client) HttpMessageCoder.ReadResponseHeader(binaryReader, out uri, out sequenceNo, out httpPacketType, out remoteHostUniqueIdentifier); else HttpMessageCoder.ReadRequestHeader(binaryReader, out protocolVersion, out genuineConnectionType, out hostId, out httpPacketType, out sequenceNo, out connectionName, out remoteHostUniqueIdentifier); return inputStream; }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">Host information.</param> /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param> /// <param name="reason">Reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">Host information.</param> /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param> /// <param name="reason">Reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; HttpClientConnection httpClientConnection = null; ArrayList connectionsToClose = new ArrayList(); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "\"{0}\" connections will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } // TODO: 2.5.3. fix (deadlock by design), will be completely fixed in 3.0 // using (new WriterAutoLocker(this._disposeLock)) { // persistent if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 ) lock (this._persistent.SyncRoot) { foreach (DictionaryEntry entry in this._persistent) { httpClientConnection = (HttpClientConnection) entry.Value; if (hostInformation != null && httpClientConnection.Remote != hostInformation) continue; connectionsToClose.Add(httpClientConnection); } } // close connections foreach (HttpClientConnection nextHttpClientConnection in connectionsToClose) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.ReleaseConnections", LogMessageType.ConnectionShuttingDown, reason, null, nextHttpClientConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, nextHttpClientConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "The connection is being shut down manually."); } this.ConnectionFailed(nextHttpClientConnection, true, GenuineExceptions.Get_Channel_ConnectionShutDown(reason), false); if (nextHttpClientConnection.GenuineConnectionType == GenuineConnectionType.Persistent) { nextHttpClientConnection.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null); } } } }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">Host information or a null reference to close all connection according to specified types.</param> /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param> /// <param name="reason">Reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { TcpSocketInfo tcpSocketInfo = null; BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" are terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } // go through all connections and close such of them that fall under the specified category ArrayList failedConnections = new ArrayList(); // persistent ReleaseConnections_Parameters releaseConnections_Parameters = new ReleaseConnections_Parameters(); releaseConnections_Parameters.FailedConnections = failedConnections; releaseConnections_Parameters.HostInformation = hostInformation; releaseConnections_Parameters.GenuineConnectionType = genuineConnectionType; this._persistent.InspectAllConnections(this._releaseConnections_InspectPersistentConnections, releaseConnections_Parameters); // named if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 || (genuineConnectionType & GenuineConnectionType.Named) != 0) lock (this._named) { foreach (DictionaryEntry entry in this._named) { tcpSocketInfo = (TcpSocketInfo) entry.Value; if (hostInformation != null && tcpSocketInfo.Remote != hostInformation) continue; if ( (genuineConnectionType & tcpSocketInfo.GenuineConnectionType) == 0) continue; failedConnections.Add(tcpSocketInfo); } } // invocation if ( (genuineConnectionType & GenuineConnectionType.Invocation) != 0) { lock (this._invocation.SyncRoot) foreach (DictionaryEntry entry in this._invocation) { ArrayList connections = (ArrayList) entry.Value; lock (connections) { foreach (TcpSocketInfo nextTcpSocketInfo in connections) { if (hostInformation != null && nextTcpSocketInfo.Remote != hostInformation) continue; failedConnections.Add(nextTcpSocketInfo); } } } lock (this._knownInvocationConnections.SyncRoot) foreach (DictionaryEntry entry in this._knownInvocationConnections) { tcpSocketInfo = (TcpSocketInfo) entry.Value; if (hostInformation != null && tcpSocketInfo.Remote != hostInformation) continue; failedConnections.Add(tcpSocketInfo); } } // close connections foreach (TcpSocketInfo failedTcpSocketInfo in failedConnections) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.ReleaseConnections", LogMessageType.ConnectionShuttingDown, reason, null, failedTcpSocketInfo.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, failedTcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null, "The connection is terminated."); } this.SocketFailed(GenuineExceptions.Get_Channel_ConnectionShutDown(reason), failedTcpSocketInfo); if (failedTcpSocketInfo.GenuineConnectionType == GenuineConnectionType.Persistent) failedTcpSocketInfo.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null); } }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">Host information.</param> /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; ArrayList connectionsToClose = new ArrayList(); using (new WriterAutoLocker(this._disposeLock)) { if (this._disposed) return ; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } // persistent if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 ) { // persistent ReleaseConnections_Parameters releaseConnections_Parameters = new ReleaseConnections_Parameters(); releaseConnections_Parameters.FailedConnections = connectionsToClose; releaseConnections_Parameters.HostInformation = hostInformation; this._persistent.InspectAllConnections(this._releaseConnections_InspectPersistentConnections, releaseConnections_Parameters); } // close connections foreach (HttpServerConnection nextHttpServerConnection in connectionsToClose) { lock (nextHttpServerConnection.Listener_Lock) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.ReleaseConnections", LogMessageType.ConnectionShuttingDown, reason, null, nextHttpServerConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, nextHttpServerConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "The connection is being shut down manually."); } nextHttpServerConnection.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null); this._persistent.Remove(nextHttpServerConnection.Remote.Uri, nextHttpServerConnection.ConnectionName); if (nextHttpServerConnection.Listener != null) this.Pool_SendThroughListener(nextHttpServerConnection, HttpPacketType.ClosedManually); } } } }
/// <summary> /// Establishes a connection to the remote host. /// </summary> /// <param name="remote">The HostInformation of the remote host.</param> /// <param name="genuineConnectionType">Type of the connection.</param> /// <param name="localUri">Local URI.</param> /// <param name="localPort">Local port.</param> /// <param name="connectionName">The name of the connection or a null reference.</param> /// <param name="remoteUri">Remote URI.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> /// <returns>A connection.</returns> internal TcpSocketInfo LowLevel_OpenConnection(HostInformation remote, GenuineConnectionType genuineConnectionType, string localUri, int localPort, string connectionName, out string remoteUri, out int remoteHostUniqueIdentifier) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) throw OperationException.WrapException(this._disposeReason); } remoteUri = null; Stream inputStream = null; Stream outputStream = null; remoteHostUniqueIdentifier = 0; string url = remote.Url; // parse provided url and fetch a port and IP address int portNumber; string hostName = GenuineUtility.SplitToHostAndPort(url, out portNumber); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablishing, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The connection is being established to {0}.", hostName); } Socket socket = null; // the time we should finish connection establishing before int timeout = GenuineUtility.GetTimeout( (TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout] ); using (ConnectionEstablishingClosure connectionEstablishingClosure = new ConnectionEstablishingClosure(hostName, portNumber, this.ITransportContext.IParameterProvider)) { connectionEstablishingClosure.StartOperation(); if (! connectionEstablishingClosure.Completed.WaitOne( GenuineUtility.GetMillisecondsLeft(timeout), false)) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Timeout expired."); if (connectionEstablishingClosure.Exception != null) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, connectionEstablishingClosure.Exception.Message); socket = connectionEstablishingClosure.CompleteOperation(); } if (! socket.Connected) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Socket.Connected property is false after connecting."); if (connectionName == null) connectionName = "$/__GC/" + hostName; TcpSocketInfo tcpSocketInfo = new TcpSocketInfo(socket, this.ITransportContext, connectionName #if DEBUG ,"Opened connection" #endif ); tcpSocketInfo.GenuineConnectionType = genuineConnectionType; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, tcpSocketInfo.DbgConnectionId, "The connection is being established to \"{0}\".", hostName); } // send protocol version and the type of the connection Message message = new Message(null, null, -1, new TransportHeaders(), Stream.Null); message.FinishTime = timeout; message.SerializedContent = MessageCoder.SerializeConnectionHeader(MessageCoder.PROTOCOL_VERSION, genuineConnectionType, tcpSocketInfo.ConnectionName).BaseStream; LowLevel_SendSync(message, tcpSocketInfo); tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages(); // get connection-level SS string connectionLevelSSName = null; switch(genuineConnectionType) { case GenuineConnectionType.Persistent: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string; break; case GenuineConnectionType.Named: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForNamedConnections] as string; break; case GenuineConnectionType.Invocation: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForInvocationConnections] as string; break; } SecuritySession securitySession = null; if (connectionLevelSSName != null) securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null); // establish it if (securitySession != null && ! securitySession.IsEstablished) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionSecurityIsEstablished, null, null, tcpSocketInfo.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, connectionLevelSSName, tcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null, "The Connection Level Security Session is being established."); } bool firstPass = true; for ( ; ; ) { inputStream = Stream.Null; try { // prepare streams if (! firstPass) inputStream = this.LowLevel_ReadSync(tcpSocketInfo, timeout, false); else firstPass = false; outputStream = securitySession.EstablishSession(inputStream, true); if (outputStream == null) break; // send a packet to the remote host message = new Message(null, null, -1, new TransportHeaders(), Stream.Null); message.FinishTime = timeout; message.SerializedContent = outputStream; LowLevel_SendSync(message, tcpSocketInfo); tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages(); if (securitySession.IsEstablished) break; } finally { if (inputStream != null) inputStream.Close(); if (outputStream != null) outputStream.Close(); } } } tcpSocketInfo.ConnectionLevelSecurity = securitySession; // now send connection info through the established connection using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false)) { // serialize local info BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo); binaryWriter.Write((string) localUri); // 2.5.2 fix // binaryWriter.Write((int) localPort); binaryWriter.Write((int) -1); binaryWriter.Write((byte) genuineConnectionType); binaryWriter.Write((int) remote.LocalHostUniqueIdentifier); // and send it message = new Message(null, null, -1, new TransportHeaders(), Stream.Null); message.FinishTime = timeout; message.SerializedContent = serializedLocalInfo; LowLevel_SendSync(message, tcpSocketInfo); tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages(); // read remote info using (Stream remoteUriStream = this.LowLevel_ReadSync(tcpSocketInfo, timeout, false)) { BinaryReader binaryReader = new BinaryReader(remoteUriStream); remoteUri = binaryReader.ReadString(); remoteHostUniqueIdentifier = binaryReader.ReadInt32(); } } tcpSocketInfo.IsServer = false; return tcpSocketInfo; }
/// <summary> /// Analyzes the version of the requested protocol and reads type of the connection. /// Throws OperationException on any errors. /// </summary> /// <param name="binaryReader">BinaryReader created on the stream with data.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">Read type of the connection.</param> /// <param name="connectionId">The connection identifier.</param> public static void DeserializeConnectionHeader(BinaryReader binaryReader, out byte protocolVersion, out GenuineConnectionType genuineConnectionType, out string connectionId) { connectionId = "/__GC/Default"; protocolVersion = binaryReader.ReadByte(); genuineConnectionType = (GenuineConnectionType) binaryReader.ReadByte(); if (! Enum.IsDefined(typeof(GenuineConnectionType), genuineConnectionType) || genuineConnectionType == GenuineConnectionType.None || genuineConnectionType == GenuineConnectionType.All) throw GenuineExceptions.Get_Connect_CanNotAcceptIncomingConnection("Incorrect type of the connection."); if (protocolVersion > 0) { connectionId = binaryReader.ReadString(); if (connectionId == null || connectionId.Length <= 0) throw GenuineExceptions.Get_Connect_CanNotAcceptIncomingConnection("Incorrect name of the connection."); } }
/// <summary> /// Parses the HTTP header. /// </summary> /// <param name="binaryReader">The source binary reader.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">The type of connection.</param> /// <param name="hostId">The identifier of the remote host.</param> /// <param name="httpPacketType">The type of the packet.</param> /// <param name="sequenceNo">The packet number.</param> /// <param name="connectionName">The name of the connection.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> public static void ReadRequestHeader(BinaryReader binaryReader, out byte protocolVersion, out GenuineConnectionType genuineConnectionType, out Guid hostId, out HttpPacketType httpPacketType, out int sequenceNo, out string connectionName, out int remoteHostUniqueIdentifier) { if (binaryReader.ReadByte() != MessageCoder.COMMAND_MAGIC_CODE) { throw GenuineExceptions.Get_Receive_IncorrectData(); } protocolVersion = binaryReader.ReadByte(); genuineConnectionType = (GenuineConnectionType)binaryReader.ReadByte(); hostId = new Guid(binaryReader.ReadBytes(16)); httpPacketType = (HttpPacketType)binaryReader.ReadByte(); sequenceNo = binaryReader.ReadInt32(); connectionName = "$/__GC/" + hostId; remoteHostUniqueIdentifier = 0; if (protocolVersion >= 0x1) { connectionName = binaryReader.ReadString(); remoteHostUniqueIdentifier = binaryReader.ReadInt32(); } }
/// <summary> /// Writes HTTP header to the specified binary writer. /// </summary> /// <param name="binaryWriter">The binary writer.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">The type of connection.</param> /// <param name="hostId">The id of the remote host.</param> /// <param name="httpPacketType">The type of the packet.</param> /// <param name="sequenceNo">The packet number.</param> /// <param name="connectionName">The name of the connection.</param> /// <param name="localHostUniqueIdentifier">The unique identifier of the local HostInformation.</param> public static void WriteRequestHeader(BinaryWriter binaryWriter, byte protocolVersion, GenuineConnectionType genuineConnectionType, byte[] hostId, HttpPacketType httpPacketType, int sequenceNo, string connectionName, int localHostUniqueIdentifier) { binaryWriter.Write((byte) MessageCoder.COMMAND_MAGIC_CODE); binaryWriter.Write((byte) protocolVersion); binaryWriter.Write((byte) genuineConnectionType); binaryWriter.Write(hostId); binaryWriter.Write((byte) httpPacketType); binaryWriter.Write((int) sequenceNo); binaryWriter.Write(connectionName); binaryWriter.Write((int) localHostUniqueIdentifier); }
/// <summary> /// Analyzes the version of the requested protocol and reads type of the connection. /// Throws OperationException on any errors. /// </summary> /// <param name="binaryReader">BinaryReader created on the stream with data.</param> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">Read type of the connection.</param> /// <param name="connectionId">The connection identifier.</param> public static void DeserializeConnectionHeader(BinaryReader binaryReader, out byte protocolVersion, out GenuineConnectionType genuineConnectionType, out string connectionId) { connectionId = "/__GC/Default"; protocolVersion = binaryReader.ReadByte(); genuineConnectionType = (GenuineConnectionType)binaryReader.ReadByte(); if (!Enum.IsDefined(typeof(GenuineConnectionType), genuineConnectionType) || genuineConnectionType == GenuineConnectionType.None || genuineConnectionType == GenuineConnectionType.All) { throw GenuineExceptions.Get_Connect_CanNotAcceptIncomingConnection("Incorrect type of the connection."); } if (protocolVersion > 0) { connectionId = binaryReader.ReadString(); if (connectionId == null || connectionId.Length <= 0) { throw GenuineExceptions.Get_Connect_CanNotAcceptIncomingConnection("Incorrect name of the connection."); } } }
/// <summary> /// Creates and returns the Connection Level Security Session. /// </summary> /// <param name="genuineConnectionType">The type of the connection.</param> /// <returns>The created Security Session.</returns> internal SecuritySession CreateConnectionLevelSecuritySession(GenuineConnectionType genuineConnectionType) { // get connection-level SS string connectionLevelSSName = null; switch(genuineConnectionType) { case GenuineConnectionType.Persistent: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string; break; case GenuineConnectionType.Named: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForNamedConnections] as string; break; case GenuineConnectionType.Invocation: connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForInvocationConnections] as string; break; } // create and return the Security Session if (connectionLevelSSName != null) return this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null); return null; }
/// <summary> /// Constructs an instance of the SecuritySessionParameters class. /// </summary> /// <param name="securitySessionName">The name of the Security Session.</param> /// <param name="securitySessionAttributes">Security Session parameters.</param> /// <param name="timeout">The invocation timeout or the TimeSpan.MinValue value to inherit the timeout from channel or Transport Context settings.</param> public SecuritySessionParameters(string securitySessionName, SecuritySessionAttributes securitySessionAttributes, TimeSpan timeout) { this.Name = securitySessionName; this.Attributes = securitySessionAttributes; this.Timeout = timeout; this._genuineConnectionType = GenuineConnectionType.Persistent; }
/// <summary> /// Returns a stream containing version of the using protocol and type of the connection being established. /// </summary> /// <param name="protocolVersion">The version of the protocol.</param> /// <param name="genuineConnectionType">Type of the connection.</param> /// <param name="connectionId">The identifier of the connection.</param> /// <returns>BinaryWriter containing a stream with serialized data.</returns> public static BinaryWriter SerializeConnectionHeader(byte protocolVersion, GenuineConnectionType genuineConnectionType, string connectionId) { GenuineChunkedStream stream = new GenuineChunkedStream(false); BinaryWriter binaryWriter = new BinaryWriter(stream); binaryWriter.Write((byte) protocolVersion); binaryWriter.Write((byte) genuineConnectionType); binaryWriter.Write((string) connectionId); return binaryWriter; }
/// <summary> /// Opens connection to the remote host. /// </summary> /// <param name="remote">The remote host.</param> /// <param name="genuineConnectionType">The type of the connection.</param> /// <param name="connectionName">The name of the connection.</param> /// <returns>The opened connection.</returns> private HttpClientConnection LowLevel_OpenConnection(HostInformation remote, GenuineConnectionType genuineConnectionType, string connectionName) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) throw OperationException.WrapException(this._disposeReason); } // the time we should finish connection establishing before int timeout = GenuineUtility.GetTimeout((TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablishing, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The connection is being established to \"{0}\".", remote == null ? "?" : remote.Url == null ? "?" : remote.Url); } // first - send the check request and start CLSSE HttpClientConnection httpClientConnection = new HttpClientConnection(this.ITransportContext, connectionName); httpClientConnection.Remote = remote; httpClientConnection.GenuineConnectionType = genuineConnectionType; httpClientConnection.Sender_ConnectionLevelSecurity = this.CreateConnectionLevelSecuritySession(genuineConnectionType); httpClientConnection.Listener_ConnectionLevelSecurity = this.CreateConnectionLevelSecuritySession(genuineConnectionType); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpClientConnection.DbgConnectionId, "An HTTP connection is being established."); } // gather the output stream Stream senderInputClsseStream = Stream.Null; Stream listenerInputClsseStream = Stream.Null; Stream clsseStream = null; GenuineChunkedStream outputStream = null; bool resend = false; bool firstFailure = false; // CLSS establishing for ( int i = 0; ; i++ ) { bool noClsseToSend = true; if (! resend) { // build the content outputStream = new GenuineChunkedStream(false); BinaryWriter binaryWriter = new BinaryWriter(outputStream); HttpMessageCoder.WriteRequestHeader(binaryWriter, MessageCoder.PROTOCOL_VERSION, genuineConnectionType, httpClientConnection.HostId, i == 0 ? HttpPacketType.Establishing_ResetConnection : HttpPacketType.Establishing, ++httpClientConnection.SendSequenceNo, httpClientConnection.ConnectionName, remote.LocalHostUniqueIdentifier); // CLSSE info using (new GenuineChunkedStreamSizeLabel(outputStream)) { if (httpClientConnection.Sender_ConnectionLevelSecurity != null && ! httpClientConnection.Sender_ConnectionLevelSecurity.IsEstablished) { clsseStream = httpClientConnection.Sender_ConnectionLevelSecurity.EstablishSession(senderInputClsseStream, true); if (clsseStream != null) { noClsseToSend = false; GenuineUtility.CopyStreamToStream(clsseStream, outputStream); } } } // CLSSE info using (new GenuineChunkedStreamSizeLabel(outputStream)) { if (httpClientConnection.Listener_ConnectionLevelSecurity != null && ! httpClientConnection.Listener_ConnectionLevelSecurity.IsEstablished) { clsseStream = httpClientConnection.Listener_ConnectionLevelSecurity.EstablishSession(listenerInputClsseStream, true); if (clsseStream != null) { noClsseToSend = false; GenuineUtility.CopyStreamToStream(clsseStream, outputStream); } } } } else outputStream.Position = 0; // parse the response HttpWebRequest httpWebRequest = httpClientConnection.InitializeRequest(true, httpClientConnection._keepalive); int millisecondsRemain = GenuineUtility.CompareTickCounts(timeout, GenuineUtility.TickCount); if ( millisecondsRemain <= 0) throw GenuineExceptions.Get_Channel_ConnectionClosedAfterTimeout(); httpWebRequest.Timeout = millisecondsRemain; httpWebRequest.ContentLength = outputStream.Length; Stream requestStream = null; try { requestStream = httpWebRequest.GetRequestStream(); GenuineUtility.CopyStreamToStream(outputStream, requestStream, (int) outputStream.Length); using (HttpWebResponse httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse()) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { StringBuilder stringBuilderHeaders = new StringBuilder(1024); foreach (string headerName in httpWebResponse.Headers.Keys) stringBuilderHeaders.AppendFormat("{0}=\"{1}\"; ", headerName, httpWebResponse.Headers.Get(headerName)); binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablishing, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, httpClientConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "The trial connection has been successfully completed. Content-Length: {0}; Content encoding: {1}; Content type: {2}; Protocol version: {3}; Respose uri: {4}; Status code: {5}; Status description: {6}; HTTP headers: {7}.", httpWebResponse.ContentLength, httpWebResponse.ContentEncoding, httpWebResponse.ContentType, httpWebResponse.ProtocolVersion, httpWebResponse.ResponseUri, httpWebResponse.StatusCode, httpWebResponse.StatusDescription, stringBuilderHeaders.ToString()); } using (Stream responseStream = httpWebResponse.GetResponseStream()) { BinaryReader binaryReader = new BinaryReader(responseStream); string serverUri; int sequenceNo; HttpPacketType httpPacketType; int remoteHostUniqueIdentifier; HttpMessageCoder.ReadResponseHeader(binaryReader, out serverUri, out sequenceNo, out httpPacketType, out remoteHostUniqueIdentifier); if ( httpPacketType != HttpPacketType.Establishing && httpPacketType != HttpPacketType.Establishing_ResetConnection ) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(remote.ToString(), "Wrong response received from the remote host."); // check the restartion if either CLSS or the persistent connection is used if (genuineConnectionType == GenuineConnectionType.Persistent || httpClientConnection.Sender_ConnectionLevelSecurity != null) remote.UpdateUri(serverUri, remoteHostUniqueIdentifier); // the first SS int writtenSize = binaryReader.ReadInt32(); senderInputClsseStream = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(responseStream, senderInputClsseStream, writtenSize); writtenSize = binaryReader.ReadInt32(); listenerInputClsseStream = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(responseStream, listenerInputClsseStream, writtenSize); } } outputStream.Close(); } catch(Exception ex) { if (firstFailure) throw; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablishing, ex, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Exception occurred while establishing the connection to \"{0}\". The connection establishing will be continued.", remote == null ? "?" : remote.Url == null ? "?" : remote.Url); } // try to recover resend = true; continue; } finally { if (requestStream != null) requestStream.Close(); } firstFailure = false; resend = false; if (httpClientConnection.Sender_ConnectionLevelSecurity != null && ! httpClientConnection.Sender_ConnectionLevelSecurity.IsEstablished) continue; if (httpClientConnection.Listener_ConnectionLevelSecurity != null && ! httpClientConnection.Listener_ConnectionLevelSecurity.IsEstablished) continue; if (! noClsseToSend) continue; break; } // start listener if it's a persistent connection remote.PhysicalAddress = remote.Url; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 ) { binaryLogWriter.WriteHostInformationEvent("HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.HostInformationCreated, null, remote, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpClientConnection.Sender_ConnectionLevelSecurity, httpClientConnection.Sender_ConnectionLevelSecurity == null ? null : httpClientConnection.Sender_ConnectionLevelSecurity.Name, httpClientConnection.DbgConnectionId, "HostInformation is ready for actions."); } // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablished, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, httpClientConnection.Sender_ConnectionLevelSecurity, httpClientConnection.Sender_ConnectionLevelSecurity == null ? null : httpClientConnection.Sender_ConnectionLevelSecurity.Name, httpClientConnection.DbgConnectionId, (int) genuineConnectionType, 0, 0, this.GetType().Name, remote.Url, remote.Url, null, "The connection to the remote host is established."); } if (genuineConnectionType == GenuineConnectionType.Persistent) this.LowLevel_InitiateListening(httpClientConnection, true); return httpClientConnection; }
/// <summary> /// Constructs an instance of the SecuritySessionParameters class. /// </summary> /// <param name="securitySessionName">The name of the Security Session.</param> public SecuritySessionParameters(string securitySessionName) { this.Name = securitySessionName; this._genuineConnectionType = GenuineConnectionType.Persistent; }