diff --git a/eng/Versioning.props b/eng/Versioning.props index 94b37faf74b..18951dc162e 100644 --- a/eng/Versioning.props +++ b/eng/Versioning.props @@ -1,6 +1,8 @@ true + false + true diff --git a/src/System.Private.ServiceModel/src/System.Private.ServiceModel.csproj b/src/System.Private.ServiceModel/src/System.Private.ServiceModel.csproj index d983ae8f79c..6020f5fb120 100644 --- a/src/System.Private.ServiceModel/src/System.Private.ServiceModel.csproj +++ b/src/System.Private.ServiceModel/src/System.Private.ServiceModel.csproj @@ -18,6 +18,7 @@ true true true + $(Ship_WcfPackages) diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/MethodCall.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/MethodCall.cs index fa4178cf3db..c6d5ba30455 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/MethodCall.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/MethodCall.cs @@ -5,12 +5,16 @@ using System.Diagnostics.Contracts; using System.Reflection; +using System.Runtime; +using System.ServiceModel.Description; namespace System.ServiceModel.Channels { // MethodCall associates a MethodBase with the arguments to pass to it. internal class MethodCall { + private object[] _inArgs; + public MethodCall(object[] args) { Contract.Assert(args != null); @@ -21,10 +25,44 @@ public MethodCall(MethodBase methodBase, object[] args) : this(args) { Contract.Assert(methodBase != null); MethodBase = methodBase; + CreateInArgs(); } public MethodBase MethodBase { get; private set; } public object[] Args { get; private set; } + + public object[] InArgs => _inArgs ?? Args; + + private void CreateInArgs() + { + var parameters = MethodBase.GetParameters(); + int inCount = 0; + foreach(var param in parameters) + { + if (ServiceReflector.FlowsIn(param)) + { + inCount++; + } + } + + if (inCount == Args.Length) // All parameters are InArgs so do nothing and fallback to returning Args + { + return; + } + + _inArgs = new object[inCount]; + int inPos = 0; + for(int argPos = 0; argPos < parameters.Length; argPos++) + { + if (ServiceReflector.FlowsIn(parameters[argPos])) + { + _inArgs[inPos] = Args[argPos]; + inPos++; + } + } + + Fx.Assert((inPos - 1) != (inCount), $"Incorrect number of arguments put into _inArgs array, expected {inCount} and copied {inPos - 1}"); + } } } diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/ServiceChannelProxy.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/ServiceChannelProxy.cs index dc772aa347d..33f015580ff 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/ServiceChannelProxy.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/ServiceChannelProxy.cs @@ -164,9 +164,9 @@ public static Task CreateTask(ServiceChannel channel, MethodCall methodCall, Pro { if (operation.TaskTResult == ServiceReflector.VoidType) { - return TaskCreator.CreateTask(channel, operation, methodCall.Args); + return TaskCreator.CreateTask(channel, operation, methodCall.InArgs); } - return TaskCreator.CreateGenericTask(channel, operation, methodCall.Args); + return TaskCreator.CreateGenericTask(channel, operation, methodCall.InArgs); } private static Task CreateGenericTask(ServiceChannel channel, ProxyOperationRuntime operation, object[] inputParameters) diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/SocketConnection.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/SocketConnection.cs index 35cb1e0dff8..5852f976f16 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/SocketConnection.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/SocketConnection.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Net; using System.Net.Sockets; @@ -14,26 +14,36 @@ namespace System.ServiceModel.Channels { internal class SocketConnection : IConnection { - private static EventHandler s_onReceiveAsyncCompleted; - private static EventHandler s_onSocketSendCompleted; + static AsyncCallback s_onReceiveCompleted; + static EventHandler s_onReceiveAsyncCompleted; + static EventHandler s_onSocketSendCompleted; // common state private Socket _socket; - private bool _noDelay = false; - private TimeSpan _sendTimeout; - private TimeSpan _receiveTimeout; + private TimeSpan _asyncSendTimeout; + private TimeSpan _readFinTimeout; + private TimeSpan _asyncReceiveTimeout; + + // Socket.SendTimeout/Socket.ReceiveTimeout only work with the synchronous API calls and therefore they + // do not get updated when asynchronous Send/Read operations are performed. In order to make sure we + // Set the proper timeouts on the Socket itself we need to keep these two additional fields. + private TimeSpan _socketSyncSendTimeout; + private TimeSpan _socketSyncReceiveTimeout; + private CloseState _closeState; + private bool _isShutdown; + private bool _noDelay = false; private bool _aborted; // close state - private static Action s_onWaitForFinComplete = new Action(OnWaitForFinComplete); private TimeoutHelper _closeTimeoutHelper; - private bool _isShutdown; + private static Action s_onWaitForFinComplete = new Action(OnWaitForFinComplete); // read state - private SocketAsyncEventArgs _asyncReadEventArgs; - private TimeSpan _readFinTimeout; private int _asyncReadSize; + private SocketAsyncEventArgs _asyncReadEventArgs; + private byte[] _readBuffer; + private int _asyncReadBufferSize; private object _asyncReadState; private Action _asyncReadCallback; private Exception _asyncReadException; @@ -46,37 +56,100 @@ internal class SocketConnection : IConnection private Exception _asyncWriteException; private bool _asyncWritePending; - private static Action s_onSendTimeout; - private static Action s_onReceiveTimeout; private IOTimer _receiveTimer; + private static Action s_onReceiveTimeout; private IOTimer _sendTimer; + private static Action s_onSendTimeout; private string _timeoutErrorString; private TransferOperation _timeoutErrorTransferOperation; + private IPEndPoint _remoteEndpoint; private ConnectionBufferPool _connectionBufferPool; - private string _remoteEndpointAddressString; + private string _remoteEndpointAddress; - public SocketConnection(Socket socket, ConnectionBufferPool connectionBufferPool) + public SocketConnection(Socket socket, ConnectionBufferPool connectionBufferPool, bool autoBindToCompletionPort) { _connectionBufferPool = connectionBufferPool ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(connectionBufferPool)); _socket = socket ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(socket)); _closeState = CloseState.Open; - AsyncReadBuffer = _connectionBufferPool.Take(); - AsyncReadBufferSize = AsyncReadBuffer.Length; - _sendTimeout = _receiveTimeout = TimeSpan.MaxValue; - _closeState = CloseState.Open; - _socket.SendBufferSize = _socket.ReceiveBufferSize = AsyncReadBufferSize; - _sendTimeout = _receiveTimeout = TimeSpan.MaxValue; - } + _readBuffer = connectionBufferPool.Take(); + _asyncReadBufferSize = _readBuffer.Length; + _socket.SendBufferSize = _socket.ReceiveBufferSize = _asyncReadBufferSize; + _asyncSendTimeout = _asyncReceiveTimeout = TimeSpan.MaxValue; + _socketSyncSendTimeout = _socketSyncReceiveTimeout = TimeSpan.MaxValue; - public int AsyncReadBufferSize { get; } + _remoteEndpoint = null; - public byte[] AsyncReadBuffer { get; private set; } + if (autoBindToCompletionPort) + { + _socket.UseOnlyOverlappedIO = false; + } + + // In SMSvcHost, sockets must be duplicated to the target process. Binding a handle to a completion port + // prevents any duplicated handle from ever binding to a completion port. The target process is where we + // want to use completion ports for performance. This means that in SMSvcHost, socket.UseOnlyOverlappedIO + // must be set to true to prevent completion port use. + if (_socket.UseOnlyOverlappedIO) + { + // Init BeginRead state + if (s_onReceiveCompleted == null) + { + s_onReceiveCompleted = Fx.ThunkCallback(new AsyncCallback(OnReceiveCompleted)); + } + } + } + public int AsyncReadBufferSize + { + get { return _asyncReadBufferSize; } + } + + public byte[] AsyncReadBuffer + { + get + { + return _readBuffer; + } + } private object ThisLock { get { return this; } } + public IPEndPoint RemoteIPEndPoint + { + get + { + // this property should only be called on the receive path + if (_remoteEndpoint == null && _closeState == CloseState.Open) + { + try + { + _remoteEndpoint = (IPEndPoint)_socket.RemoteEndPoint; + } + catch (SocketException socketException) + { + // will never be a timeout error, so TimeSpan.Zero is ok + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( + ConvertReceiveException(socketException, TimeSpan.Zero, TimeSpan.Zero)); + } + catch (ObjectDisposedException objectDisposedException) + { + Exception exceptionToThrow = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Undefined); + if (ReferenceEquals(exceptionToThrow, objectDisposedException)) + { + throw; + } + else + { + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exceptionToThrow); + } + } + } + + return _remoteEndpoint; + } + } + private IOTimer SendTimer { get @@ -85,7 +158,7 @@ private IOTimer SendTimer { if (s_onSendTimeout == null) { - s_onSendTimeout = OnSendTimeout; + s_onSendTimeout = new Action(OnSendTimeout); } _sendTimer = new IOTimer(s_onSendTimeout, this); @@ -103,7 +176,7 @@ private IOTimer ReceiveTimer { if (s_onReceiveTimeout == null) { - s_onReceiveTimeout = OnReceiveTimeout; + s_onReceiveTimeout = new Action(OnReceiveTimeout); } _receiveTimer = new IOTimer(s_onReceiveTimeout, this); @@ -113,116 +186,64 @@ private IOTimer ReceiveTimer } } - private IPEndPoint RemoteEndPoint - { - get - { - if (!_socket.Connected) - { - return null; - } - return (IPEndPoint)_socket.RemoteEndPoint; - } - } - - private string RemoteEndpointAddressString + private string RemoteEndpointAddress { get { - if (_remoteEndpointAddressString == null) + if (_remoteEndpointAddress == null) { - IPEndPoint remote = RemoteEndPoint; - if (remote == null) + try { - return string.Empty; + if (TryGetEndpoints(out IPEndPoint local, out IPEndPoint remote)) + { + _remoteEndpointAddress = remote.Address + ":" + remote.Port; + } + else + { + //null indicates not initialized. + _remoteEndpointAddress = string.Empty; + } } - _remoteEndpointAddressString = remote.Address + ":" + remote.Port; - } + catch (Exception exception) + { + if (Fx.IsFatal(exception)) + { + throw; + } - return _remoteEndpointAddressString; + } + } + return _remoteEndpointAddress; } } - private static void OnReceiveAsyncCompleted(object sender, SocketAsyncEventArgs e) + private static void OnReceiveTimeout(object state) { - ((SocketConnection)e.UserToken).OnReceiveAsync(sender, e); + SocketConnection thisPtr = (SocketConnection)state; + thisPtr.Abort(SR.Format(SR.SocketAbortedReceiveTimedOut, thisPtr._asyncReceiveTimeout), TransferOperation.Read); } - private static void OnSendAsyncCompleted(object sender, SocketAsyncEventArgs e) + private static void OnSendTimeout(object state) { - ((SocketConnection)e.UserToken).OnSendAsync(sender, e); + SocketConnection thisPtr = (SocketConnection)state; + thisPtr.Abort(4, // TraceEventType.Warning + SR.Format(SR.SocketAbortedSendTimedOut, thisPtr._asyncSendTimeout), TransferOperation.Write); } - private static void OnWaitForFinComplete(object state) + private static void OnReceiveCompleted(IAsyncResult result) { - // Callback for read on a socket which has had Shutdown called on it. When - // the response FIN packet is received from the remote host, the pending - // read will complete with 0 bytes read. If more than 0 bytes has been read, - // then something has gone wrong as we should have no pending data to be received. - SocketConnection thisPtr = (SocketConnection)state; - - try - { - int bytesRead; - - try - { - bytesRead = thisPtr.EndRead(); - - if (bytesRead > 0) - { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, thisPtr.RemoteEndPoint))); - } - } - catch (TimeoutException timeoutException) - { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( - SR.Format(SR.SocketCloseReadTimeout, thisPtr.RemoteEndPoint, thisPtr._readFinTimeout), - timeoutException)); - } - - thisPtr.ContinueClose(thisPtr._closeTimeoutHelper.RemainingTime()); - } - catch (Exception e) - { - if (Fx.IsFatal(e)) - { - throw; - } - - Fx.Exception.TraceUnhandledException(e); - - // The user has no opportunity to clean up the connection in the async and linger - // code path, ensure cleanup finishes. - thisPtr.Abort(); - } + ((SocketConnection)result.AsyncState).OnReceive(result); } - private static void OnReceiveTimeout(SocketConnection socketConnection) + private static void OnReceiveAsyncCompleted(object sender, SocketAsyncEventArgs e) { - try - { - socketConnection.Abort(SR.Format(SR.SocketAbortedReceiveTimedOut, socketConnection._receiveTimeout), TransferOperation.Read); - } - catch (SocketException) - { - // Guard against unhandled SocketException in timer callbacks - } + ((SocketConnection)e.UserToken).OnReceiveAsync(sender, e); } - private static void OnSendTimeout(SocketConnection socketConnection) + private static void OnSendAsyncCompleted(object sender, SocketAsyncEventArgs e) { - try - { - socketConnection.Abort(4, // TraceEventType.Warning - SR.Format(SR.SocketAbortedSendTimedOut, socketConnection._sendTimeout), TransferOperation.Write); - } - catch (SocketException) - { - // Guard against unhandled SocketException in timer callbacks - } + ((SocketConnection)e.UserToken).OnSendAsync(sender, e); } public void Abort() @@ -258,23 +279,26 @@ private void Abort(int traceEventType, string timeoutErrorString, TransferOperat _aborted = true; _closeState = CloseState.Closed; - if (!_asyncReadPending) + if (_asyncReadPending) + { + CancelReceiveTimer(); + } + else { DisposeReadEventArgs(); } - if (!_asyncWritePending) + if (_asyncWritePending) + { + CancelSendTimer(); + } + else { DisposeWriteEventArgs(); } - - DisposeReceiveTimer(); - DisposeSendTimer(); } - _socket.LingerState = new LingerOption(true, 0); - _socket.Shutdown(SocketShutdown.Both); - _socket.Dispose(); + _socket.Close(0); } private void AbortRead() @@ -326,23 +350,61 @@ private void CloseAsyncAndLinger() int bytesRead = EndRead(); - // Any NetTcp session handshake will have been completed at this point so if any data is returned, something - // very wrong has happened. if (bytesRead > 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, RemoteEndPoint))); + new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, _socket.RemoteEndPoint))); } } catch (TimeoutException timeoutException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( - SR.Format(SR.SocketCloseReadTimeout, RemoteEndPoint, _readFinTimeout), timeoutException)); + SR.Format(SR.SocketCloseReadTimeout, _socket.RemoteEndPoint, _readFinTimeout), timeoutException)); } ContinueClose(_closeTimeoutHelper.RemainingTime()); } + private static void OnWaitForFinComplete(object state) + { + SocketConnection thisPtr = (SocketConnection)state; + + try + { + int bytesRead; + + try + { + bytesRead = thisPtr.EndRead(); + + if (bytesRead > 0) + { + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( + new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, thisPtr._socket.RemoteEndPoint))); + } + } + catch (TimeoutException timeoutException) + { + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( + SR.Format(SR.SocketCloseReadTimeout, thisPtr._socket.RemoteEndPoint, thisPtr._readFinTimeout), + timeoutException)); + } + + thisPtr.ContinueClose(thisPtr._closeTimeoutHelper.RemainingTime()); + } + catch (Exception e) + { + if (Fx.IsFatal(e)) + { + throw; + } + + // The user has no opportunity to clean up the connection in the async and linger + // code path, ensure cleanup finishes. + thisPtr.Abort(); + } + } + public void Close(TimeSpan timeout, bool asyncAndLinger) { lock (ThisLock) @@ -355,15 +417,10 @@ public void Close(TimeSpan timeout, bool asyncAndLinger) _closeState = CloseState.Closing; } - _closeTimeoutHelper = new TimeoutHelper(timeout); - // first we shutdown our send-side - Shutdown(timeout); - CloseCore(asyncAndLinger); - } + _closeTimeoutHelper = new TimeoutHelper(timeout); + Shutdown(_closeTimeoutHelper.RemainingTime()); - private void CloseCore(bool asyncAndLinger) - { if (asyncAndLinger) { CloseAsyncAndLinger(); @@ -378,10 +435,7 @@ private void CloseSync() { byte[] dummy = new byte[1]; - // A FIN (shutdown) packet has already been sent to the remote host and we're waiting for the remote - // host to send a FIN back. A pending read on a socket will complete returning zero bytes when a FIN - // packet is received. - + // then we check for a FIN from the other side (i.e. read zero) int bytesRead; _readFinTimeout = _closeTimeoutHelper.RemainingTime(); @@ -389,32 +443,25 @@ private void CloseSync() { bytesRead = ReadCore(dummy, 0, 1, _readFinTimeout, true); - // Any NetTcp session handshake will have been completed at this point so if any data is returned, something - // very wrong has happened. if (bytesRead > 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, RemoteEndPoint))); + new CommunicationException(SR.Format(SR.SocketCloseReadReceivedData, _socket.RemoteEndPoint))); } } catch (TimeoutException timeoutException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new TimeoutException( - SR.Format(SR.SocketCloseReadTimeout, RemoteEndPoint, _readFinTimeout), timeoutException)); + SR.Format(SR.SocketCloseReadTimeout, _socket.RemoteEndPoint, _readFinTimeout), timeoutException)); } // finally we call Close with whatever time is remaining ContinueClose(_closeTimeoutHelper.RemainingTime()); } - private void ContinueClose(TimeSpan timeout) + public void ContinueClose(TimeSpan timeout) { - // Use linger to attempt a graceful socket shutdown. Allowing a clean shutdown handshake - // will allow the service side to close it's socket gracefully too. A hard shutdown would - // cause the server to receive an exception which affects performance and scalability. - _socket.LingerState = new LingerOption(true, (int)timeout.TotalSeconds); - _socket.Shutdown(SocketShutdown.Both); - _socket.Dispose(); + _socket.Close(TimeoutHelper.ToMilliseconds(timeout)); lock (ThisLock) { @@ -434,12 +481,10 @@ private void ContinueClose(TimeSpan timeout) } _closeState = CloseState.Closed; - DisposeReceiveTimer(); - DisposeSendTimer(); } } - private void Shutdown(TimeSpan timeout) + public void Shutdown(TimeSpan timeout) { lock (ThisLock) { @@ -451,12 +496,6 @@ private void Shutdown(TimeSpan timeout) _isShutdown = true; } - ShutdownCore(timeout); - } - - private void ShutdownCore(TimeSpan timeout) - { - // Attempt to close the socket gracefully by sending a shutdown (FIN) packet try { _socket.Shutdown(SocketShutdown.Send); @@ -464,7 +503,7 @@ private void ShutdownCore(TimeSpan timeout) catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - ConvertSendException(socketException, TimeSpan.MaxValue)); + ConvertSendException(socketException, TimeSpan.MaxValue, _socketSyncSendTimeout)); } catch (ObjectDisposedException objectDisposedException) { @@ -500,29 +539,69 @@ private void ThrowIfClosed() } } - private Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime) + private bool TryGetEndpoints(out IPEndPoint localIPEndpoint, out IPEndPoint remoteIPEndpoint) + { + localIPEndpoint = null; + remoteIPEndpoint = null; + + if (_closeState == CloseState.Open) + { + try + { + remoteIPEndpoint = _remoteEndpoint ?? (IPEndPoint)_socket.RemoteEndPoint; + localIPEndpoint = (IPEndPoint)_socket.LocalEndPoint; + } + catch (Exception exception) + { + if (Fx.IsFatal(exception)) + { + throw; + } + + } + } + + return localIPEndpoint != null && remoteIPEndpoint != null; + } + + public object GetCoreTransport() + { + return _socket; + } + + public IAsyncResult BeginValidate(Uri uri, AsyncCallback callback, object state) + { + return new CompletedAsyncResult(true, callback, state); + } + + public bool EndValidate(IAsyncResult result) + { + return CompletedAsyncResult.End(result); + } + + private Exception ConvertSendException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout) { - return ConvertTransferException(socketException, _sendTimeout, socketException, - _aborted, _timeoutErrorString, _timeoutErrorTransferOperation, this, remainingTime); + return ConvertTransferException(socketException, timeout, socketException, + TransferOperation.Write, _aborted, _timeoutErrorString, _timeoutErrorTransferOperation, this, remainingTime); } - private Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime) + private Exception ConvertReceiveException(SocketException socketException, TimeSpan remainingTime, TimeSpan timeout) { - return ConvertTransferException(socketException, _receiveTimeout, socketException, - _aborted, _timeoutErrorString, _timeoutErrorTransferOperation, this, remainingTime); + return ConvertTransferException(socketException, timeout, socketException, + TransferOperation.Read, _aborted, _timeoutErrorString, _timeoutErrorTransferOperation, this, remainingTime); } internal static Exception ConvertTransferException(SocketException socketException, TimeSpan timeout, Exception originalException) { return ConvertTransferException(socketException, timeout, originalException, - false, null, TransferOperation.Undefined, null, TimeSpan.MaxValue); + TransferOperation.Undefined, false, null, TransferOperation.Undefined, null, TimeSpan.MaxValue); } private Exception ConvertObjectDisposedException(ObjectDisposedException originalException, TransferOperation transferOperation) { if (_timeoutErrorString != null) { - return ConvertTimeoutErrorException(originalException, _timeoutErrorString, _timeoutErrorTransferOperation); + return ConvertTimeoutErrorException(originalException, transferOperation, _timeoutErrorString, _timeoutErrorTransferOperation); } else if (_aborted) { @@ -535,30 +614,30 @@ private Exception ConvertObjectDisposedException(ObjectDisposedException origina } private static Exception ConvertTransferException(SocketException socketException, TimeSpan timeout, Exception originalException, - bool aborted, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation, + TransferOperation transferOperation, bool aborted, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation, SocketConnection socketConnection, TimeSpan remainingTime) { - if ((int)socketException.SocketErrorCode == UnsafeNativeMethods.ERROR_INVALID_HANDLE) + if (socketException.ErrorCode == UnsafeNativeMethods.ERROR_INVALID_HANDLE) { return new CommunicationObjectAbortedException(socketException.Message, socketException); } if (timeoutErrorString != null) { - return ConvertTimeoutErrorException(originalException, timeoutErrorString, timeoutErrorTransferOperation); + return ConvertTimeoutErrorException(originalException, transferOperation, timeoutErrorString, timeoutErrorTransferOperation); } // 10053 can occur due to our timeout sockopt firing, so map to TimeoutException in that case - if ((int)socketException.SocketErrorCode == UnsafeNativeMethods.WSAECONNABORTED && + if (socketException.ErrorCode == UnsafeNativeMethods.WSAECONNABORTED && remainingTime <= TimeSpan.Zero) { TimeoutException timeoutException = new TimeoutException(SR.Format(SR.TcpConnectionTimedOut, timeout), originalException); return timeoutException; } - if ((int)socketException.SocketErrorCode == UnsafeNativeMethods.WSAENETRESET || - (int)socketException.SocketErrorCode == UnsafeNativeMethods.WSAECONNABORTED || - (int)socketException.SocketErrorCode == UnsafeNativeMethods.WSAECONNRESET) + if (socketException.ErrorCode == UnsafeNativeMethods.WSAENETRESET || + socketException.ErrorCode == UnsafeNativeMethods.WSAECONNABORTED || + socketException.ErrorCode == UnsafeNativeMethods.WSAECONNRESET) { if (aborted) { @@ -570,7 +649,7 @@ private static Exception ConvertTransferException(SocketException socketExceptio return communicationException; } } - else if ((int)socketException.SocketErrorCode == UnsafeNativeMethods.WSAETIMEDOUT) + else if (socketException.ErrorCode == UnsafeNativeMethods.WSAETIMEDOUT) { TimeoutException timeoutException = new TimeoutException(SR.Format(SR.TcpConnectionTimedOut, timeout), originalException); return timeoutException; @@ -579,21 +658,25 @@ private static Exception ConvertTransferException(SocketException socketExceptio { if (aborted) { - return new CommunicationObjectAbortedException(SR.Format(SR.TcpTransferError, (int)socketException.SocketErrorCode, socketException.Message), originalException); + return new CommunicationObjectAbortedException(SR.Format(SR.TcpTransferError, socketException.ErrorCode, socketException.Message), originalException); } else { - CommunicationException communicationException = new CommunicationException(SR.Format(SR.TcpTransferError, (int)socketException.SocketErrorCode, socketException.Message), originalException); + CommunicationException communicationException = new CommunicationException(SR.Format(SR.TcpTransferError, socketException.ErrorCode, socketException.Message), originalException); return communicationException; } } } - private static Exception ConvertTimeoutErrorException(Exception originalException, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation) + private static Exception ConvertTimeoutErrorException(Exception originalException, + TransferOperation transferOperation, string timeoutErrorString, TransferOperation timeoutErrorTransferOperation) { - Contract.Assert(timeoutErrorString != null, "Argument timeoutErrorString must not be null."); + if (timeoutErrorString == null) + { + Fx.Assert("Argument timeoutErrorString must not be null."); + } - if (timeoutErrorTransferOperation != TransferOperation.Undefined) + if (transferOperation == timeoutErrorTransferOperation) { return new TimeoutException(timeoutErrorString, originalException); } @@ -605,38 +688,20 @@ private static Exception ConvertTimeoutErrorException(Exception originalExceptio public AsyncCompletionResult BeginWrite(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, Action callback, object state) - { - if (WcfEventSource.Instance.SocketAsyncWriteStartIsEnabled()) - { - TraceWriteStart(size, true); - } - - return BeginWriteCore(buffer, offset, size, immediate, timeout, callback, state); - } - - private void TraceWriteStart(int size, bool async) - { - if (!async) - { - WcfEventSource.Instance.SocketWriteStart(_socket.GetHashCode(), size, RemoteEndpointAddressString); - } - else - { - WcfEventSource.Instance.SocketAsyncWriteStart(_socket.GetHashCode(), size, RemoteEndpointAddressString); - } - } - - private AsyncCompletionResult BeginWriteCore(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, - Action callback, object state) { ConnectionUtilities.ValidateBufferBounds(buffer, offset, size); bool abortWrite = true; try { + if (WcfEventSource.Instance.SocketAsyncWriteStartIsEnabled()) + { + TraceWriteStart(size, true); + } + lock (ThisLock) { - Contract.Assert(!_asyncWritePending, "Called BeginWrite twice."); + Fx.Assert(!_asyncWritePending, "Called BeginWrite twice."); ThrowIfClosed(); EnsureWriteEventArgs(); SetImmediate(immediate); @@ -662,7 +727,7 @@ private AsyncCompletionResult BeginWriteCore(byte[] buffer, int offset, int size catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - ConvertSendException(socketException, TimeSpan.MaxValue)); + ConvertSendException(socketException, TimeSpan.MaxValue, _asyncSendTimeout)); } catch (ObjectDisposedException objectDisposedException) { @@ -686,11 +751,6 @@ private AsyncCompletionResult BeginWriteCore(byte[] buffer, int offset, int size } public void EndWrite() - { - EndWriteCore(); - } - - private void EndWriteCore() { if (_asyncWriteException != null) { @@ -702,8 +762,7 @@ private void EndWriteCore() { if (!_asyncWritePending) { - Contract.Assert(false, "SocketConnection.EndWrite called with no write pending."); - throw new Exception("SocketConnection.EndWrite called with no write pending."); + throw Fx.AssertAndThrow("SocketConnection.EndWrite called with no write pending."); } SetUserToken(_asyncWriteEventArgs, null); @@ -716,6 +775,73 @@ private void EndWriteCore() } } + private void OnSendAsync(object sender, SocketAsyncEventArgs eventArgs) + { + Fx.Assert(eventArgs != null, "Argument 'eventArgs' cannot be NULL."); + CancelSendTimer(); + + try + { + HandleSendAsyncCompleted(); + Fx.Assert(eventArgs.BytesTransferred == _asyncWriteEventArgs.Count, "The socket SendAsync did not send all the bytes."); + } + catch (SocketException socketException) + { + _asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue, _asyncSendTimeout); + } + catch (Exception exception) + { + if (Fx.IsFatal(exception)) + { + throw; + } + + _asyncWriteException = exception; + } + + FinishWrite(); + } + + private void HandleSendAsyncCompleted() + { + if (_asyncWriteEventArgs.SocketError == SocketError.Success) + { + return; + } + + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SocketException((int)_asyncWriteEventArgs.SocketError)); + } + + // This method should be called inside ThisLock + private void DisposeWriteEventArgs() + { + if (_asyncWriteEventArgs != null) + { + _asyncWriteEventArgs.Completed -= s_onSocketSendCompleted; + _asyncWriteEventArgs.Dispose(); + } + } + + private void AbortWrite() + { + lock (ThisLock) + { + if (_asyncWritePending) + { + if (_closeState != CloseState.Closed) + { + SetUserToken(_asyncWriteEventArgs, null); + _asyncWritePending = false; + CancelSendTimer(); + } + else + { + DisposeWriteEventArgs(); + } + } + } + } + private void FinishWrite() { Action asyncWriteCallback = _asyncWriteCallback; @@ -728,11 +854,6 @@ private void FinishWrite() } public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout) - { - WriteCore(buffer, offset, size, immediate, timeout); - } - - private void WriteCore(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout) { // as per http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b201213 // we shouldn't write more than 64K synchronously to a socket @@ -759,7 +880,7 @@ private void WriteCore(byte[] buffer, int offset, int size, bool immediate, Time catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - ConvertSendException(socketException, timeoutHelper.RemainingTime())); + ConvertSendException(socketException, timeoutHelper.RemainingTime(), _socketSyncSendTimeout)); } catch (ObjectDisposedException objectDisposedException) { @@ -775,6 +896,18 @@ private void WriteCore(byte[] buffer, int offset, int size, bool immediate, Time } } + private void TraceWriteStart(int size, bool async) + { + if (!async) + { + WcfEventSource.Instance.SocketWriteStart(_socket.GetHashCode(), size, RemoteEndpointAddress); + } + else + { + WcfEventSource.Instance.SocketAsyncWriteStart(_socket.GetHashCode(), size, RemoteEndpointAddress); + } + } + public void Write(byte[] buffer, int offset, int size, bool immediate, TimeSpan timeout, BufferManager bufferManager) { try @@ -791,13 +924,7 @@ public int Read(byte[] buffer, int offset, int size, TimeSpan timeout) { ConnectionUtilities.ValidateBufferBounds(buffer, offset, size); ThrowIfNotOpen(); - int bytesRead = ReadCore(buffer, offset, size, timeout, false); - if (WcfEventSource.Instance.SocketReadStopIsEnabled()) - { - TraceSocketReadStop(bytesRead, false); - } - - return bytesRead; + return ReadCore(buffer, offset, size, timeout, false); } private int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool closing) @@ -812,7 +939,7 @@ private int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool catch (SocketException socketException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( - ConvertReceiveException(socketException, timeoutHelper.RemainingTime())); + ConvertReceiveException(socketException, timeoutHelper.RemainingTime(), _socketSyncReceiveTimeout)); } catch (ObjectDisposedException objectDisposedException) { @@ -830,32 +957,26 @@ private int ReadCore(byte[] buffer, int offset, int size, TimeSpan timeout, bool return bytesRead; } - public virtual AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, - Action callback, object state) - { - ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size); - ThrowIfNotOpen(); - var completionResult = BeginReadCore(offset, size, timeout, callback, state); - if (completionResult == AsyncCompletionResult.Completed && WcfEventSource.Instance.SocketReadStopIsEnabled()) - { - TraceSocketReadStop(_asyncReadSize, true); - } - - return completionResult; - } - private void TraceSocketReadStop(int bytesRead, bool async) { if (!async) { - WcfEventSource.Instance.SocketReadStop((_socket != null) ? _socket.GetHashCode() : -1, bytesRead, RemoteEndpointAddressString); + WcfEventSource.Instance.SocketReadStop((_socket != null) ? _socket.GetHashCode() : -1, bytesRead, RemoteEndpointAddress); } else { - WcfEventSource.Instance.SocketAsyncReadStop((_socket != null) ? _socket.GetHashCode() : -1, bytesRead, RemoteEndpointAddressString); + WcfEventSource.Instance.SocketAsyncReadStop((_socket != null) ? _socket.GetHashCode() : -1, bytesRead, RemoteEndpointAddress); } } + public virtual AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, + Action callback, object state) + { + ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size); + ThrowIfNotOpen(); + return BeginReadCore(offset, size, timeout, callback, state); + } + private AsyncCompletionResult BeginReadCore(int offset, int size, TimeSpan timeout, Action callback, object state) { @@ -874,27 +995,48 @@ private AsyncCompletionResult BeginReadCore(int offset, int size, TimeSpan timeo try { - if (offset != _asyncReadEventArgs.Offset || - size != _asyncReadEventArgs.Count) + if (_socket.UseOnlyOverlappedIO) { - _asyncReadEventArgs.SetBuffer(offset, size); - } + // ReceiveAsync does not respect UseOnlyOverlappedIO but BeginReceive does. + IAsyncResult result = _socket.BeginReceive(AsyncReadBuffer, offset, size, SocketFlags.None, s_onReceiveCompleted, this); + + if (!result.CompletedSynchronously) + { + abortRead = false; + return AsyncCompletionResult.Queued; + } - if (ReceiveAsync()) + _asyncReadSize = _socket.EndReceive(result); + } + else { - abortRead = false; - return AsyncCompletionResult.Queued; + if (offset != _asyncReadEventArgs.Offset || + size != _asyncReadEventArgs.Count) + { + _asyncReadEventArgs.SetBuffer(offset, size); + } + + if (ReceiveAsync()) + { + abortRead = false; + return AsyncCompletionResult.Queued; + } + + HandleReceiveAsyncCompleted(); + _asyncReadSize = _asyncReadEventArgs.BytesTransferred; } - HandleReceiveAsyncCompleted(); - _asyncReadSize = _asyncReadEventArgs.BytesTransferred; + if (WcfEventSource.Instance.SocketReadStopIsEnabled()) + { + TraceSocketReadStop(_asyncReadSize, true); + } abortRead = false; return AsyncCompletionResult.Completed; } catch (SocketException socketException) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertReceiveException(socketException, TimeSpan.MaxValue)); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertReceiveException(socketException, TimeSpan.MaxValue, _asyncReceiveTimeout)); } catch (ObjectDisposedException objectDisposedException) { @@ -922,19 +1064,61 @@ private bool ReceiveAsync() return _socket.ReceiveAsync(_asyncReadEventArgs); } + private void OnReceive(IAsyncResult result) + { + CancelReceiveTimer(); + if (result.CompletedSynchronously) + { + return; + } + + try + { + _asyncReadSize = _socket.EndReceive(result); + + if (WcfEventSource.Instance.SocketReadStopIsEnabled()) + { + TraceSocketReadStop(_asyncReadSize, true); + } + } + catch (SocketException socketException) + { + _asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, _asyncReceiveTimeout); + } + catch (ObjectDisposedException objectDisposedException) + { + _asyncReadException = ConvertObjectDisposedException(objectDisposedException, TransferOperation.Read); + } + catch (Exception exception) + { + if (Fx.IsFatal(exception)) + { + throw; + } + _asyncReadException = exception; + } + + FinishRead(); + } + private void OnReceiveAsync(object sender, SocketAsyncEventArgs eventArgs) { - Contract.Assert(eventArgs != null, "Argument 'eventArgs' cannot be NULL."); + Fx.Assert(eventArgs != null, "Argument 'eventArgs' cannot be NULL."); CancelReceiveTimer(); try { HandleReceiveAsyncCompleted(); _asyncReadSize = eventArgs.BytesTransferred; + + if (WcfEventSource.Instance.SocketReadStopIsEnabled()) + { + TraceSocketReadStop(_asyncReadSize, true); + } } catch (SocketException socketException) { - _asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue); + _asyncReadException = ConvertReceiveException(socketException, TimeSpan.MaxValue, _asyncReceiveTimeout); } catch (Exception exception) { @@ -958,14 +1142,8 @@ private void HandleReceiveAsyncCompleted() throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SocketException((int)_asyncReadEventArgs.SocketError)); } - private void FinishRead() { - if (_asyncReadException != null && WcfEventSource.Instance.SocketReadStopIsEnabled()) - { - TraceSocketReadStop(_asyncReadSize, true); - } - Action asyncReadCallback = _asyncReadCallback; object asyncReadState = _asyncReadState; @@ -977,12 +1155,6 @@ private void FinishRead() // Both BeginRead/ReadAsync paths completed themselves. EndRead's only job is to deliver the result. public int EndRead() - { - return EndReadCore(); - } - - // Both BeginRead/ReadAsync paths completed themselves. EndRead's only job is to deliver the result. - private int EndReadCore() { if (_asyncReadException != null) { @@ -994,8 +1166,7 @@ private int EndReadCore() { if (!_asyncReadPending) { - Contract.Assert(false, "SocketConnection.EndRead called with no read pending."); - throw new Exception("SocketConnection.EndRead called with no read pending."); + throw Fx.AssertAndThrow("SocketConnection.EndRead called with no read pending."); } SetUserToken(_asyncReadEventArgs, null); @@ -1023,108 +1194,15 @@ private void DisposeReadEventArgs() TryReturnReadBuffer(); } - // This method should be called inside ThisLock - private void DisposeReceiveTimer() - { - if (_receiveTimer != null) - { - _receiveTimer.Dispose(); - } - } - - private void OnSendAsync(object sender, SocketAsyncEventArgs eventArgs) - { - Contract.Assert(eventArgs != null, "Argument 'eventArgs' cannot be NULL."); - CancelSendTimer(); - - try - { - HandleSendAsyncCompleted(); - Contract.Assert(eventArgs.BytesTransferred == _asyncWriteEventArgs.Count, "The socket SendAsync did not send all the bytes."); - } - catch (SocketException socketException) - { - _asyncWriteException = ConvertSendException(socketException, TimeSpan.MaxValue); - } - catch (Exception exception) - { - if (Fx.IsFatal(exception)) - { - throw; - } - - _asyncWriteException = exception; - } - - FinishWrite(); - } - - private void HandleSendAsyncCompleted() - { - if (_asyncWriteEventArgs.SocketError == SocketError.Success) - { - return; - } - - throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SocketException((int)_asyncWriteEventArgs.SocketError)); - } - - // This method should be called inside ThisLock - private void DisposeWriteEventArgs() - { - if (_asyncWriteEventArgs != null) - { - _asyncWriteEventArgs.Completed -= s_onSocketSendCompleted; - _asyncWriteEventArgs.Dispose(); - } - } - - // This method should be called inside ThisLock - private void DisposeSendTimer() - { - if (_sendTimer != null) - { - _sendTimer.Dispose(); - } - } - - private void AbortWrite() - { - lock (ThisLock) - { - if (_asyncWritePending) - { - if (_closeState != CloseState.Closed) - { - SetUserToken(_asyncWriteEventArgs, null); - _asyncWritePending = false; - CancelSendTimer(); - } - else - { - DisposeWriteEventArgs(); - } - } - } - } - - // This method should be called inside ThisLock - private void ReturnReadBuffer() - { - // We release the buffer only if there is no outstanding I/O - TryReturnReadBuffer(); - } - - // This method should be called inside ThisLock private void TryReturnReadBuffer() { // The buffer must not be returned and nulled when an abort occurs. Since the buffer // is also accessed by higher layers, code that has not yet realized the stack is // aborted may be attempting to read from the buffer. - if (AsyncReadBuffer != null && !_aborted) + if (_readBuffer != null && !_aborted) { - _connectionBufferPool.Return(AsyncReadBuffer); - AsyncReadBuffer = null; + _connectionBufferPool.Return(_readBuffer); + _readBuffer = null; } } @@ -1164,7 +1242,7 @@ private void SetReadTimeout(TimeSpan timeout, bool synchronous, bool closing) new TimeoutException(SR.Format(SR.TcpConnectionTimedOut, timeout))); } - if (UpdateTimeout(_receiveTimeout, timeout)) + if (ShouldUpdateTimeout(_socketSyncReceiveTimeout, timeout)) { lock (ThisLock) { @@ -1174,12 +1252,12 @@ private void SetReadTimeout(TimeSpan timeout, bool synchronous, bool closing) } _socket.ReceiveTimeout = TimeoutHelper.ToMilliseconds(timeout); } - _receiveTimeout = timeout; + _socketSyncReceiveTimeout = timeout; } } else { - _receiveTimeout = timeout; + _asyncReceiveTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelReceiveTimer(); @@ -1204,19 +1282,19 @@ private void SetWriteTimeout(TimeSpan timeout, bool synchronous) new TimeoutException(SR.Format(SR.TcpConnectionTimedOut, timeout))); } - if (UpdateTimeout(_sendTimeout, timeout)) + if (ShouldUpdateTimeout(_socketSyncSendTimeout, timeout)) { lock (ThisLock) { ThrowIfNotOpen(); _socket.SendTimeout = TimeoutHelper.ToMilliseconds(timeout); } - _sendTimeout = timeout; + _socketSyncSendTimeout = timeout; } } else { - _sendTimeout = timeout; + _asyncSendTimeout = timeout; if (timeout == TimeSpan.MaxValue) { CancelSendTimer(); @@ -1228,7 +1306,7 @@ private void SetWriteTimeout(TimeSpan timeout, bool synchronous) } } - private bool UpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout) + private bool ShouldUpdateTimeout(TimeSpan oldTimeout, TimeSpan newTimeout) { if (oldTimeout == newTimeout) { @@ -1253,7 +1331,7 @@ private void EnsureReadEventArgs() } _asyncReadEventArgs = new SocketAsyncEventArgs(); - _asyncReadEventArgs.SetBuffer(AsyncReadBuffer, 0, AsyncReadBuffer.Length); + _asyncReadEventArgs.SetBuffer(_readBuffer, 0, _readBuffer.Length); _asyncReadEventArgs.Completed += s_onReceiveAsyncCompleted; } } @@ -1274,11 +1352,6 @@ private void EnsureWriteEventArgs() } } - public object GetCoreTransport() - { - return _socket; - } - private enum CloseState { Open, @@ -1313,7 +1386,7 @@ private IConnection CreateConnection(IPAddress address, int port) AddressFamily addressFamily = address.AddressFamily; socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(address, port)); - return new SocketConnection(socket, _connectionBufferPool); + return new SocketConnection(socket, _connectionBufferPool, false); } catch { @@ -1330,7 +1403,7 @@ private async Task CreateConnectionAsync(IPAddress address, int por AddressFamily addressFamily = address.AddressFamily; socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); await socket.ConnectAsync(new IPEndPoint(address, port)); - return new SocketConnection(socket, _connectionBufferPool); + return new SocketConnection(socket, _connectionBufferPool, false); } catch { diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Description/MessagePartDescription.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Description/MessagePartDescription.cs index fbebeb7267b..7a2f150fc7c 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Description/MessagePartDescription.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Description/MessagePartDescription.cs @@ -11,7 +11,7 @@ namespace System.ServiceModel.Description { - [DebuggerDisplay("Name={_name}, Namespace={_ns}, Type={Type}, Index={_index}}")] + [DebuggerDisplay("Name={XmlName}, Namespace={Namespace}, Type={Type}, Index={Index}}")] public class MessagePartDescription { private ProtectionLevel _protectionLevel; @@ -22,14 +22,14 @@ public MessagePartDescription(string name, string ns) { if (name == null) { - throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name", SR.SFxParameterNameCannotBeNull); + throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(name), SR.SFxParameterNameCannotBeNull); } XmlName = new XmlName(name, true /*isEncoded*/); if (!string.IsNullOrEmpty(ns)) { - NamingHelper.CheckUriParameter(ns, "ns"); + NamingHelper.CheckUriParameter(ns, nameof(ns)); } Namespace = ns; diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/ProxyOperationRuntime.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/ProxyOperationRuntime.cs index 2abae4ed4ee..eab1f82e87a 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/ProxyOperationRuntime.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/ProxyOperationRuntime.cs @@ -299,7 +299,7 @@ internal object[] MapSyncInputs(MethodCall methodCall, out object[] outs) return Array.Empty(); } - return methodCall.Args; + return methodCall.InArgs; } internal object[] MapAsyncBeginInputs(MethodCall methodCall, out AsyncCallback callback, out object asyncState) diff --git a/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/XmlSerializerOperationFormatter.cs b/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/XmlSerializerOperationFormatter.cs index 8b151b9f0a2..334921f2a25 100644 --- a/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/XmlSerializerOperationFormatter.cs +++ b/src/System.Private.ServiceModel/src/System/ServiceModel/Dispatcher/XmlSerializerOperationFormatter.cs @@ -20,6 +20,7 @@ internal class XmlSerializerOperationFormatter : OperationFormatter private const string soap11Encoding = "http://schemas.xmlsoap.org/soap/encoding/"; private const string soap12Encoding = "http://www.w3.org/2003/05/soap-encoding"; + private bool _isEncoded; private MessageInfo _requestMessageInfo; private MessageInfo _replyMessageInfo; @@ -27,6 +28,12 @@ public XmlSerializerOperationFormatter(OperationDescription description, XmlSeri MessageInfo requestMessageInfo, MessageInfo replyMessageInfo) : base(description, xmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc, xmlSerializerFormatAttribute.IsEncoded) { + if (xmlSerializerFormatAttribute.IsEncoded && xmlSerializerFormatAttribute.Style != OperationFormatStyle.Rpc) + { + throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.SFxDocEncodedNotSupported, description.Name))); + } + + _isEncoded = xmlSerializerFormatAttribute.IsEncoded; _requestMessageInfo = requestMessageInfo; _replyMessageInfo = replyMessageInfo; } @@ -83,13 +90,12 @@ protected override void AddHeadersToMessage(Message message, MessageDescription MemoryStream memoryStream = new MemoryStream(); XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream); bufferWriter.WriteStartElement("root"); - serializer.Serialize(bufferWriter, headerValues, null); + serializer.Serialize(bufferWriter, headerValues, null, _isEncoded ? GetEncoding(message.Version.Envelope) : null); bufferWriter.WriteEndElement(); bufferWriter.Flush(); XmlDocument doc = new XmlDocument(); memoryStream.Position = 0; doc.Load(memoryStream); - //doc.Save(Console.Out); foreach (XmlElement element in doc.DocumentElement.ChildNodes) { MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(element.LocalName, element.NamespaceURI); @@ -236,7 +242,7 @@ protected override void GetHeadersFromMessage(Message message, MessageDescriptio if (!bufferReader.IsEmptyElement) { bufferReader.ReadStartElement(); - object[] headerValues = (object[])serializer.Deserialize(bufferReader); + object[] headerValues = (object[])serializer.Deserialize(bufferReader, _isEncoded ? GetEncoding(message.Version.Envelope) : null); int headerIndex = 0; foreach (MessageHeaderDescription headerDescription in messageDescription.Headers) { @@ -285,6 +291,12 @@ private static void AddUnknownHeader(MessageHeaderDescription unknownHeaderDescr protected override void WriteBodyAttributes(XmlDictionaryWriter writer, MessageVersion version) { + if (_isEncoded && version.Envelope == EnvelopeVersion.Soap11) + { + string encoding = GetEncoding(version.Envelope); + writer.WriteAttributeString("encodingStyle", version.Envelope.Namespace, encoding); + } + writer.WriteAttributeString("xmlns", "xsi", null, XmlUtil.XmlSerializerSchemaInstanceNamespace); writer.WriteAttributeString("xmlns", "xsd", null, XmlUtil.XmlSerializerSchemaNamespace); } @@ -374,6 +386,7 @@ private void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, X bodyParameters[paramIndex++] = parameters[bodyParts[i].Index]; } + string encoding = _isEncoded ? GetEncoding(version.Envelope) : null; serializer.Serialize(writer, bodyParameters, null); } @@ -444,7 +457,7 @@ private object DeserializeBody(XmlDictionaryReader reader, MessageVersion versio return null; } - object[] bodyParameters = (object[])serializer.Deserialize(reader); + object[] bodyParameters = (object[])serializer.Deserialize(reader, _isEncoded ? GetEncoding(version.Envelope) : null); int paramIndex = 0; if (IsValidReturnValue(returnPart)) { @@ -568,7 +581,9 @@ internal void SetHeaderAttributes(MessageHeaderDescription headerDescription, bo if (_attributes[headerDescription.Index] == null) { _attributes[headerDescription.Index] = new List>(); - } ((List>)_attributes[headerDescription.Index]).Add(new MessageHeader(null, mustUnderstand, actor, relay)); + } + + ((List>)_attributes[headerDescription.Index]).Add(new MessageHeader(null, mustUnderstand, actor, relay)); } else { diff --git a/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs b/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs index 0db061e1806..270cb933cb8 100644 --- a/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs +++ b/src/System.Private.ServiceModel/tests/Common/Scenarios/ServiceInterfaces.cs @@ -495,6 +495,9 @@ public interface IServiceContractUniqueTypeOutSyncService { [OperationContract] void Request(string stringRequest, out UniqueType uniqueTypeResponse); + + [OperationContract] + void Request2(out UniqueType uniqueTypeResponse, string stringRequest); } [ServiceContract] diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Service/ServiceContractTests.4.0.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Service/ServiceContractTests.4.0.0.cs index f860466fa26..5dd31d1360f 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Contract/Service/ServiceContractTests.4.0.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Contract/Service/ServiceContractTests.4.0.0.cs @@ -225,6 +225,14 @@ public static void ServiceContract_TypedProxy_SyncOperation_UniqueTypeOutArg() // *** EXECUTE *** \\ serviceProxy.Request(message, out uniqueType); + // *** VALIDATE *** \\ + Assert.True((uniqueType.stringValue == message), + String.Format("The value of the 'stringValue' field in the UniqueType instance was not as expected. expected {0} but got {1}", message, uniqueType.stringValue)); + + // *** EXECUTE *** \\ + uniqueType = null; + serviceProxy.Request2(out uniqueType, message); + // *** VALIDATE *** \\ Assert.True((uniqueType.stringValue == message), String.Format("The value of the 'stringValue' field in the UniqueType instance was not as expected. expected {0} but got {1}", message, uniqueType.stringValue)); diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncInterfaces.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncInterfaces.cs index f4319614d64..8104ea8f2b3 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncInterfaces.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncInterfaces.cs @@ -40,6 +40,9 @@ public interface IServiceContractUniqueTypeOutSyncService { [OperationContract] void Request(string stringRequest, out UniqueType uniqueTypeResponse); + + [OperationContract] + void Request2(out UniqueType uniqueTypeResponse, string stringRequest); } [ServiceContract] diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncServices.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncServices.cs index a9066aad895..89c419ee870 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncServices.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/ServiceContractAsyncServices.cs @@ -49,6 +49,12 @@ public void Request(string stringRequest, out UniqueType uniqueTypeResponse) uniqueTypeResponse = new UniqueType(); uniqueTypeResponse.stringValue = stringRequest; } + + public void Request2(out UniqueType uniqueTypeResponse, string stringRequest) + { + uniqueTypeResponse = new UniqueType(); + uniqueTypeResponse.stringValue = stringRequest; + } } public class ServiceContractUniqueTypeRefSyncService : IServiceContractUniqueTypeRefSyncService diff --git a/src/System.ServiceModel.Duplex/ref/System.ServiceModel.Duplex.cs b/src/System.ServiceModel.Duplex/ref/System.ServiceModel.Duplex.cs index 86479316f96..9744b25fc27 100644 --- a/src/System.ServiceModel.Duplex/ref/System.ServiceModel.Duplex.cs +++ b/src/System.ServiceModel.Duplex/ref/System.ServiceModel.Duplex.cs @@ -23,7 +23,9 @@ public partial class DuplexChannelFactory : System.ServiceModel.Channe public DuplexChannelFactory(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding) : base(default(System.Type)) { } public DuplexChannelFactory(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(default(System.Type)) { } public DuplexChannelFactory(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, string remoteAddress) : base(default(System.Type)) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public DuplexChannelFactory(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) : base(default(System.Type)) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public DuplexChannelFactory(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(default(System.Type)) { } public override TChannel CreateChannel(System.ServiceModel.EndpointAddress address, System.Uri via) { return default(TChannel); } public TChannel CreateChannel(System.ServiceModel.InstanceContext callbackInstance) { return default(TChannel); } @@ -34,8 +36,11 @@ public abstract partial class DuplexClientBase : System.ServiceModel.C { protected DuplexClientBase(System.ServiceModel.InstanceContext callbackInstance) { } protected DuplexClientBase(System.ServiceModel.InstanceContext callbackInstance, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected DuplexClientBase(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected DuplexClientBase(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected DuplexClientBase(System.ServiceModel.InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress) { } } public sealed partial class InstanceContext : System.ServiceModel.Channels.CommunicationObject, System.ServiceModel.IExtensibleObject diff --git a/src/System.ServiceModel.Duplex/src/System.ServiceModel.Duplex.Facade.csproj b/src/System.ServiceModel.Duplex/src/System.ServiceModel.Duplex.Facade.csproj index b04c4af4b91..6a3b41b491c 100644 --- a/src/System.ServiceModel.Duplex/src/System.ServiceModel.Duplex.Facade.csproj +++ b/src/System.ServiceModel.Duplex/src/System.ServiceModel.Duplex.Facade.csproj @@ -13,6 +13,7 @@ $(BuildFrameworks)$(HarvestFrameworks) true true + $(Ship_WcfPackages) diff --git a/src/System.ServiceModel.Http/ref/System.ServiceModel.Http.cs b/src/System.ServiceModel.Http/ref/System.ServiceModel.Http.cs index 5ef04ebeb19..c26b3427697 100644 --- a/src/System.ServiceModel.Http/ref/System.ServiceModel.Http.cs +++ b/src/System.ServiceModel.Http/ref/System.ServiceModel.Http.cs @@ -114,6 +114,7 @@ public partial class NetHttpBinding : System.ServiceModel.HttpBindingBase { public NetHttpBinding() { } public NetHttpBinding(System.ServiceModel.BasicHttpSecurityMode securityMode) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public NetHttpBinding(string configurationName) { } [System.ComponentModel.DefaultValueAttribute((System.ServiceModel.NetHttpMessageEncoding)(0))] public System.ServiceModel.NetHttpMessageEncoding MessageEncoding { get { return default(System.ServiceModel.NetHttpMessageEncoding); } set { } } diff --git a/src/System.ServiceModel.Http/src/System.ServiceModel.Http.Facade.csproj b/src/System.ServiceModel.Http/src/System.ServiceModel.Http.Facade.csproj index 6c473e7c556..088abf7d963 100644 --- a/src/System.ServiceModel.Http/src/System.ServiceModel.Http.Facade.csproj +++ b/src/System.ServiceModel.Http/src/System.ServiceModel.Http.Facade.csproj @@ -13,6 +13,7 @@ $(BuildFrameworks)$(HarvestFrameworks) true true + $(Ship_WcfPackages) diff --git a/src/System.ServiceModel.NetTcp/ref/System.ServiceModel.NetTcp.cs b/src/System.ServiceModel.NetTcp/ref/System.ServiceModel.NetTcp.cs index 84979ca01bf..e380dea8d6c 100644 --- a/src/System.ServiceModel.NetTcp/ref/System.ServiceModel.NetTcp.cs +++ b/src/System.ServiceModel.NetTcp/ref/System.ServiceModel.NetTcp.cs @@ -17,6 +17,7 @@ public partial class NetTcpBinding : System.ServiceModel.Channels.Binding { public NetTcpBinding() { } public NetTcpBinding(System.ServiceModel.SecurityMode securityMode) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public NetTcpBinding(string configurationName) { } public System.ServiceModel.EnvelopeVersion EnvelopeVersion { get { return default(System.ServiceModel.EnvelopeVersion); } } [System.ComponentModel.DefaultValueAttribute((long)524288)] diff --git a/src/System.ServiceModel.NetTcp/src/System.ServiceModel.NetTcp.Facade.csproj b/src/System.ServiceModel.NetTcp/src/System.ServiceModel.NetTcp.Facade.csproj index bf2ebd53af2..21ec3e8bd10 100644 --- a/src/System.ServiceModel.NetTcp/src/System.ServiceModel.NetTcp.Facade.csproj +++ b/src/System.ServiceModel.NetTcp/src/System.ServiceModel.NetTcp.Facade.csproj @@ -13,6 +13,7 @@ $(BuildFrameworks)$(HarvestFrameworks) true true + $(Ship_WcfPackages) diff --git a/src/System.ServiceModel.Primitives/ref/System.ServiceModel.Primitives.cs b/src/System.ServiceModel.Primitives/ref/System.ServiceModel.Primitives.cs index 403e02123ca..e47b2cb6af5 100644 --- a/src/System.ServiceModel.Primitives/ref/System.ServiceModel.Primitives.cs +++ b/src/System.ServiceModel.Primitives/ref/System.ServiceModel.Primitives.cs @@ -94,18 +94,7 @@ protected virtual void EndCancelTokenCore(System.IAsyncResult result) { } public partial class SecurityTokenRequirement { public SecurityTokenRequirement() { } - //public static string TokenTypeProperty { get { return default(string); } } - //public static string KeyUsageProperty { get { return default(string); } } - //public static string KeyTypeProperty { get { return default(string); } } - //public static string KeySizeProperty { get { return default(string); } } - //public static string RequireCryptographicTokenProperty { get { return default(string); } } - //public static string PeerAuthenticationMode { get { return default(string); } } - //public static string IsOptionalTokenProperty { get { return default(string); } } public string TokenType { get { return default; } set { } } - //public bool RequireCryptographicToken { get { return default(System.Boolean); } set { } } - //public SecurityKeyUsage KeyUsage { get { return default(SecurityKeyUsage); } set { } } - //public SecurityKeyType KeyType { get { return default(SecurityKeyType); } set { } } - //public System.Int32 KeySize { get { return default(System.Int32); } set { } } public System.Collections.Generic.IDictionary Properties { get { return default; } } public TValue GetProperty(string propertyName) { return default; } public bool TryGetProperty(string propertyName, out TValue result) { result = default; return default; } @@ -157,11 +146,6 @@ public abstract partial class SecurityKey { internal SecurityKey() { } public abstract int KeySize { get; } - //public abstract byte[] DecryptKey(string algorithm, byte[] keyData) { return default(byte[]); } - //public abstract byte[] EncryptKey(string algorithm, byte[] keyData) { return default(byte[]); } - //public abstract bool IsAsymmetricAlgorithm(string algorithm) { return default(bool); } - //public abstract bool IsSupportedAlgorithm(string algorithm) { return default(bool); } - //public abstract bool IsSymmetricAlgorithm(string algorithm) { return default(bool); } } public class SecurityKeyIdentifier : System.Collections.Generic.IEnumerable { @@ -198,10 +182,6 @@ public abstract partial class SecurityToken public abstract System.Collections.ObjectModel.ReadOnlyCollection SecurityKeys { get; } public abstract DateTime ValidFrom { get; } public abstract DateTime ValidTo { get; } - //public virtual bool CanCreateKeyIdentifierClause() where T : System.IdentityModel.Tokens.SecurityKeyIdentifierClause { return default(bool); } - //public virtual T CreateKeyIdentifierClause() where T : System.IdentityModel.Tokens.SecurityKeyIdentifierClause { return default(T); } - //public virtual bool MatchesKeyIdentifierClause(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause) { return default(bool); } - //public virtual System.IdentityModel.Tokens.SecurityKey ResolveKeyIdentifierClause(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause) { return default(System.IdentityModel.Tokens.SecurityKey); } } public abstract partial class SymmetricSecurityKey : SecurityKey { @@ -225,6 +205,7 @@ protected ChannelFactory() { } protected override System.TimeSpan DefaultCloseTimeout { get { return default; } } protected override System.TimeSpan DefaultOpenTimeout { get { return default; } } public System.ServiceModel.Description.ServiceEndpoint Endpoint { get { return default; } } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected virtual void ApplyConfiguration(string configurationName) { } protected abstract System.ServiceModel.Description.ServiceEndpoint CreateDescription(); protected virtual System.ServiceModel.Channels.IChannelFactory CreateFactory() { return default; } @@ -232,6 +213,7 @@ protected internal void EnsureOpened() { } public T GetProperty() where T : class { return default; } protected void InitializeEndpoint(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress address) { } protected void InitializeEndpoint(System.ServiceModel.Description.ServiceEndpoint endpoint) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected void InitializeEndpoint(string configurationName, System.ServiceModel.EndpointAddress address) { } protected override void OnAbort() { } protected override System.IAsyncResult OnBeginClose(System.TimeSpan timeout, System.AsyncCallback callback, object state) { return default; } @@ -248,7 +230,9 @@ public partial class ChannelFactory : System.ServiceModel.ChannelFacto { public ChannelFactory(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) { } public ChannelFactory(System.ServiceModel.Description.ServiceEndpoint endpoint) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public ChannelFactory(string endpointConfigurationName) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public ChannelFactory(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) { } protected ChannelFactory(System.Type channelType) { } public TChannel CreateChannel() { return default; } @@ -268,8 +252,11 @@ public abstract partial class ClientBase : System.IDisposable, System. protected ClientBase() { } protected ClientBase(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) { } protected ClientBase(System.ServiceModel.Description.ServiceEndpoint endpoint) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected ClientBase(string endpointConfigurationName) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected ClientBase(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] protected ClientBase(string endpointConfigurationName, string remoteAddress) { } protected TChannel Channel { get { return default; } } public System.ServiceModel.ChannelFactory ChannelFactory { get { return default; } } @@ -340,8 +327,11 @@ void System.ServiceModel.Channels.IOutputChannel.Send(System.ServiceModel.Channe System.ServiceModel.Channels.Message System.ServiceModel.Channels.IRequestChannel.EndRequest(System.IAsyncResult result) { return default; } System.ServiceModel.Channels.Message System.ServiceModel.Channels.IRequestChannel.Request(System.ServiceModel.Channels.Message message) { return default; } System.ServiceModel.Channels.Message System.ServiceModel.Channels.IRequestChannel.Request(System.ServiceModel.Channels.Message message, System.TimeSpan timeout) { return default; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] System.IAsyncResult System.ServiceModel.IClientChannel.BeginDisplayInitializationUI(System.AsyncCallback callback, object state) { return default; } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] void System.ServiceModel.IClientChannel.DisplayInitializationUI() { } + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] void System.ServiceModel.IClientChannel.EndDisplayInitializationUI(System.IAsyncResult result) { } void System.ServiceModel.ICommunicationObject.Abort() { } System.IAsyncResult System.ServiceModel.ICommunicationObject.BeginClose(System.AsyncCallback callback, object state) { return default; } diff --git a/src/System.ServiceModel.Primitives/src/System.ServiceModel.Primitives.Facade.csproj b/src/System.ServiceModel.Primitives/src/System.ServiceModel.Primitives.Facade.csproj index 91273150c3c..745f9d8c9a4 100644 --- a/src/System.ServiceModel.Primitives/src/System.ServiceModel.Primitives.Facade.csproj +++ b/src/System.ServiceModel.Primitives/src/System.ServiceModel.Primitives.Facade.csproj @@ -13,6 +13,7 @@ $(BuildFrameworks)$(HarvestFrameworks) true true + $(Ship_WcfPackages) diff --git a/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenManagerTest.cs b/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenManagerTest.cs new file mode 100644 index 00000000000..fc1088105a6 --- /dev/null +++ b/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenManagerTest.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System.Collections.ObjectModel; +using System.IdentityModel.Policy; +using System.IdentityModel.Selectors; +using System.IdentityModel.Tokens; +using Infrastructure.Common; +using Xunit; + +public class SecurityTokenManagerTest +{ + [WcfFact] + public static void Methods_Override() + { + var tokenManager = new SecurityTokenManagerImpl(); + SecurityTokenVersionImpl tokenVersion = new SecurityTokenVersionImpl(); + SecurityTokenRequirement tokenRequirement = new SecurityTokenRequirement(); + + SecurityTokenAuthenticator authenticator = tokenManager.CreateSecurityTokenAuthenticator(tokenRequirement, out SecurityTokenResolver resolver); + SecurityTokenProvider provider = tokenManager.CreateSecurityTokenProvider(tokenRequirement); + SecurityTokenSerializer serializer = tokenManager.CreateSecurityTokenSerializer(tokenVersion); + + Assert.IsType(authenticator); + Assert.IsType(resolver); + Assert.IsType(provider); + Assert.IsType(serializer); + } +} + +public class SecurityTokenManagerImpl : SecurityTokenManager +{ + public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) + { + Assert.IsType(tokenRequirement); + outOfBandTokenResolver = new SecurityTokenResolverImpl(); + return new SecurityTokenAuthenticatorImpl(); + } + + public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) + { + Assert.IsType(tokenRequirement); + return new SecurityTokenProviderSyncImpl(); + } + + public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion tokenVersion) + { + Assert.IsType(tokenVersion); + return new SecurityTokenSerializerImpl(); + } +} + +public class SecurityTokenVersionImpl : SecurityTokenVersion +{ + public override ReadOnlyCollection GetSecuritySpecifications() + { + return null; + } +} + +public class SecurityTokenAuthenticatorImpl : SecurityTokenAuthenticator +{ + protected override bool CanValidateTokenCore(SecurityToken token) + { + return false; + } + + protected override ReadOnlyCollection ValidateTokenCore(SecurityToken token) + { + return null; + } +} + +public class SecurityTokenResolverImpl : SecurityTokenResolver +{ + protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key) + { + key = null; + return false; + } + + protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token) + { + token = null; + return false; + } + + protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token) + { + token = null; + return false; + } +} diff --git a/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenSerializerTest.cs b/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenSerializerTest.cs index f9f45f680a7..ba165678a2c 100644 --- a/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenSerializerTest.cs +++ b/src/System.ServiceModel.Primitives/tests/IdentityModel/SecurityTokenSerializerTest.cs @@ -22,8 +22,8 @@ public static void Methods_NonNullParam_InvokeAndReturn() var xmlWriter = XmlWriter.Create(new MemoryStream()); var dummyToken = new DummySecurityToken(); var keyIdentifier = new SecurityKeyIdentifier(); - var keyIdentifierClause = new SecurityKeyIdentifierClauseImp("DummyClause"); - var sts = new SecurityTokenSerializerImp(); + var keyIdentifierClause = new SecurityKeyIdentifierClauseImpl("DummyClause"); + var sts = new SecurityTokenSerializerImpl(); Assert.NotNull(sts); Assert.True(sts.CanReadKeyIdentifier(xmlReader)); @@ -38,7 +38,7 @@ public static void Methods_NonNullParam_InvokeAndReturn() SecurityKeyIdentifierClause identifierClause = sts.ReadKeyIdentifierClause(xmlReader); Assert.IsType(token); Assert.IsType(identifier); - Assert.IsType(identifierClause); + Assert.IsType(identifierClause); sts.WriteToken(xmlWriter, dummyToken); sts.WriteKeyIdentifier(xmlWriter, keyIdentifier); @@ -51,7 +51,7 @@ public static void Methods_NonNullParam_InvokeAndReturn() [WcfFact] public static void Methods_NullParam_Throws() { - var sts = new SecurityTokenSerializerImp(); + var sts = new SecurityTokenSerializerImpl(); Assert.NotNull(sts); Assert.Throws(() => sts.CanReadKeyIdentifier(null)); @@ -72,7 +72,7 @@ public static void Methods_NullParam_Throws() } } -public class SecurityTokenSerializerImp : SecurityTokenSerializer +public class SecurityTokenSerializerImpl : SecurityTokenSerializer { public bool WriteTokenCoreCalled = false; public bool WriteKeyIdentifierCoreCalled = false; @@ -110,7 +110,7 @@ protected override bool CanWriteTokenCore(SecurityToken token) protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore(XmlReader reader) { - return new SecurityKeyIdentifierClauseImp("DummyClause"); + return new SecurityKeyIdentifierClauseImpl("DummyClause"); } protected override SecurityKeyIdentifier ReadKeyIdentifierCore(XmlReader reader) @@ -139,13 +139,13 @@ protected override void WriteTokenCore(XmlWriter writer, SecurityToken token) } } -public class SecurityKeyIdentifierClauseImp : SecurityKeyIdentifierClause +public class SecurityKeyIdentifierClauseImpl : SecurityKeyIdentifierClause { - public SecurityKeyIdentifierClauseImp(string clauseType) : base(clauseType) + public SecurityKeyIdentifierClauseImpl(string clauseType) : base(clauseType) { } - public SecurityKeyIdentifierClauseImp(string clauseType, byte[] nonce, int length) : base(clauseType, nonce, length) + public SecurityKeyIdentifierClauseImpl(string clauseType, byte[] nonce, int length) : base(clauseType, nonce, length) { } } diff --git a/src/System.ServiceModel.Security/ref/System.ServiceModel.Security.cs b/src/System.ServiceModel.Security/ref/System.ServiceModel.Security.cs index 52db9badf42..f8c803677c8 100644 --- a/src/System.ServiceModel.Security/ref/System.ServiceModel.Security.cs +++ b/src/System.ServiceModel.Security/ref/System.ServiceModel.Security.cs @@ -118,17 +118,6 @@ protected SecurityAlgorithmSuite() { } public abstract string DefaultAsymmetricSignatureAlgorithm { get; } public abstract int DefaultSignatureKeyDerivationLength { get; } public abstract int DefaultSymmetricKeyLength { get; } - //public virtual bool IsCanonicalizationAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsDigestAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsEncryptionAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsEncryptionKeyDerivationAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsSymmetricKeyWrapAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsAsymmetricKeyWrapAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsSymmetricSignatureAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsAsymmetricSignatureAlgorithmSupported(string algorithm) { return default; } - //public virtual bool IsSignatureKeyDerivationAlgorithmSupported(string algorithm) { return default; } - //public abstract bool IsSymmetricKeyLengthSupported(int length); - //public abstract bool IsAsymmetricKeyLengthSupported(int length); } public abstract partial class SecurityPolicyVersion { @@ -171,28 +160,11 @@ public class IssuedSecurityTokenParameters : System.ServiceModel.Security.Tokens { protected IssuedSecurityTokenParameters(IssuedSecurityTokenParameters other) { } public IssuedSecurityTokenParameters() { } - //public IssuedSecurityTokenParameters(string tokenType) { } - //public IssuedSecurityTokenParameters(string tokenType, EndpointAddress issuerAddress) { } - //public IssuedSecurityTokenParameters(string tokenType, EndpointAddress issuerAddress, Channels.Binding issuerBinding) { } - //internal protected override bool HasAsymmetricKey { get { return default; } } - //public System.Collections.ObjectModel.Collection AdditionalRequestParameters { get { return default; } } public MessageSecurityVersion DefaultMessageSecurityVersion { get { return default; } set { } } public EndpointAddress IssuerAddress { get { return default; } set { } } - //public EndpointAddress IssuerMetadataAddress { get { return default; } set { } } public Channels.Binding IssuerBinding { get { return default; } set { } } public System.IdentityModel.Tokens.SecurityKeyType KeyType { get { return default; } set { } } - //public int KeySize { get { return default; } set { } } - //public bool UseStrTransform { get { return default; } set { } } - //public System.Collections.ObjectModel.Collection ClaimTypeRequirements { get { return default; } } public string TokenType { get { return default; } set { } } - //internal protected override bool SupportsClientAuthentication { get { return default; } } - //internal protected override bool SupportsServerAuthentication { get { return default; } } - //internal protected override bool SupportsClientWindowsIdentity { get { return default; } } - //protected override System.ServiceModel.Security.Tokens.SecurityTokenParameters CloneCore() { return default; } - //internal protected override System.IdentityModel.Tokens.SecurityKeyIdentifierClause CreateKeyIdentifierClause(System.IdentityModel.Tokens.SecurityToken token, SecurityTokenReferenceStyle referenceStyle) { return default; } - //public System.Collections.ObjectModel.Collection CreateRequestParameters(MessageSecurityVersion messageSecurityVersion, SecurityTokenSerializer securityTokenSerializer) { return default; } - //public override string ToString() { return default; } - //protected internal override void InitializeSecurityTokenRequirement(IdentityModel.Selectors.SecurityTokenRequirement requirement) { } } public partial class SecureConversationSecurityTokenParameters : System.ServiceModel.Security.Tokens.SecurityTokenParameters { @@ -210,42 +182,7 @@ internal SecurityTokenParameters() { } public abstract partial class ServiceModelSecurityTokenRequirement : System.IdentityModel.Selectors.SecurityTokenRequirement { protected ServiceModelSecurityTokenRequirement() { } - //static public string SecurityAlgorithmSuiteProperty { get { return default(string); } } - //static public string SecurityBindingElementProperty { get { return default(string); } } - //static public string IssuerAddressProperty { get { return default(string); } } - //static public string IssuerBindingProperty { get { return default(string); } } - //static public string SecureConversationSecurityBindingElementProperty { get { return default(string); } } - //static public string SupportSecurityContextCancellationProperty { get { return default(string); } } - //static public string MessageSecurityVersionProperty { get { return default(string); } } - //static public string IssuerBindingContextProperty { get { return default(string); } } - //static public string TransportSchemeProperty { get { return default(string); } } - //static public string IsInitiatorProperty { get { return default(string); } } - //static public string TargetAddressProperty { get { return default(string); } } - //static public string ViaProperty { get { return default(string); } } - //static public string ListenUriProperty { get { return default(string); } } - //static public string AuditLogLocationProperty { get { return default(string); } } - //static public string SuppressAuditFailureProperty { get { return default(string); } } - //static public string MessageAuthenticationAuditLevelProperty { get { return default(string); } } - //static public string IsOutOfBandTokenProperty { get { return default(string); } } - //static public string PreferSslCertificateAuthenticatorProperty { get { return default(string); } } - //static public string SupportingTokenAttachmentModeProperty { get { return default(string); } } - //static public string MessageDirectionProperty { get { return default(string); } } - //static public string HttpAuthenticationSchemeProperty { get { return default(string); } } - //static public string IssuedSecurityTokenParametersProperty { get { return default(string); } } - //static public string PrivacyNoticeUriProperty { get { return default(string); } } - //static public string PrivacyNoticeVersionProperty { get { return default(string); } } - //static public string DuplexClientLocalAddressProperty { get { return default(string); } } - //static public string EndpointFilterTableProperty { get { return default(string); } } static public string ChannelParametersCollectionProperty { get { return default; } } - //static public string ExtendedProtectionPolicy { get { return default(string); } } - //public bool IsInitiator { get { return default(bool); } } - //public System.ServiceModel.Security.SecurityAlgorithmSuite SecurityAlgorithmSuite { get { return default(System.ServiceModel.Security.SecurityAlgorithmSuite); } set { } } - //public System.ServiceModel.Channels.SecurityBindingElement SecurityBindingElement { get { return default(System.ServiceModel.Channels.SecurityBindingElement); } set { } } - //public System.ServiceModel.EndpointAddress IssuerAddress { get { return default(System.ServiceModel.EndpointAddress); } set { } } - //public System.ServiceModel.Channels.Binding IssuerBinding { get { return default(System.ServiceModel.Channels.Binding); } set { } } - //public System.ServiceModel.Channels.SecurityBindingElement SecureConversationSecurityBindingElement { get { return default(System.ServiceModel.Channels.SecurityBindingElement); } set { } } - //public System.IdentityModel.Selectors.SecurityTokenVersion MessageSecurityVersion { get { return default(System.IdentityModel.Selectors.SecurityTokenVersion); } set { } } - //public string TransportScheme { get { return default(string); } set { } } } public partial class SupportingTokenParameters { @@ -268,26 +205,17 @@ namespace System.IdentityModel.Tokens { public partial class GenericXmlSecurityToken : System.IdentityModel.Tokens.SecurityToken { - public GenericXmlSecurityToken(System.Xml.XmlElement tokenXml, - System.IdentityModel.Tokens.SecurityToken proofToken, - DateTime effectiveTime, - DateTime expirationTime, - SecurityKeyIdentifierClause internalTokenReference, - SecurityKeyIdentifierClause externalTokenReference, + public GenericXmlSecurityToken(System.Xml.XmlElement tokenXml, + System.IdentityModel.Tokens.SecurityToken proofToken, + DateTime effectiveTime, + DateTime expirationTime, + SecurityKeyIdentifierClause internalTokenReference, + SecurityKeyIdentifierClause externalTokenReference, System.Collections.ObjectModel.ReadOnlyCollection authorizationPolicies) {} public override string Id { get; } public override DateTime ValidFrom { get; } public override DateTime ValidTo { get; } public override System.Collections.ObjectModel.ReadOnlyCollection SecurityKeys { get; } - // public SecurityKeyIdentifierClause InternalTokenReference { get; } - // public SecurityKeyIdentifierClause ExternalTokenReference { get; } - // public XmlElement TokenXml { get; } - // public SecurityToken ProofToken { get; } - // public ReadOnlyCollection AuthorizationPolicies { get; } - // public override string ToString() {} - // public override bool CanCreateKeyIdentifierClause() {} - // public override T CreateKeyIdentifierClause() {} - // public override bool MatchesKeyIdentifierClause(.SecurityKeyIdentifierClause keyIdentifierClause) {} } public enum SecurityKeyType { diff --git a/src/System.ServiceModel.Security/src/System.ServiceModel.Security.Facade.csproj b/src/System.ServiceModel.Security/src/System.ServiceModel.Security.Facade.csproj index 352c7893b90..18e88759a61 100644 --- a/src/System.ServiceModel.Security/src/System.ServiceModel.Security.Facade.csproj +++ b/src/System.ServiceModel.Security/src/System.ServiceModel.Security.Facade.csproj @@ -13,6 +13,7 @@ $(BuildFrameworks)$(HarvestFrameworks) true true + $(Ship_WcfPackages) diff --git a/src/svcutilcore/src/dotnet-svcutil.xmlserializer.csproj b/src/svcutilcore/src/dotnet-svcutil.xmlserializer.csproj index 6154a777a29..1ed89c059df 100644 --- a/src/svcutilcore/src/dotnet-svcutil.xmlserializer.csproj +++ b/src/svcutilcore/src/dotnet-svcutil.xmlserializer.csproj @@ -12,7 +12,7 @@ true AnyCPU {EAB2959D-0A16-4F60-A453-765491E1C069} - false + $(Ship_SvcUtilXmlSerPackages)