using System.Net.Security;
using System.ServiceModel;
using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
using System.ServiceModel.Security;
using System.Text;
internal class HttpSimpleChannelListener<TChannel> : HttpChannelListenerBase<TChannel>
where TChannel : class, IChannel
{
- HttpListenerManager<TChannel> httpChannelManager;
-
public HttpSimpleChannelListener (HttpTransportBindingElement source,
BindingContext context)
: base (source, context)
{
}
- public HttpListener Http {
- get { return httpChannelManager.HttpListener; }
- }
-
object creator_lock = new object ();
protected override TChannel CreateChannel (TimeSpan timeout)
{
if (typeof (TChannel) == typeof (IReplyChannel))
return (TChannel) (object) new HttpSimpleReplyChannel ((HttpSimpleChannelListener<IReplyChannel>) (object) this);
- // FIXME: session channel support
- if (typeof (TChannel) == typeof (IReplySessionChannel))
- throw new NotImplementedException ();
throw new NotSupportedException (String.Format ("Channel type {0} is not supported", typeof (TChannel)));
}
- protected override void OnOpen (TimeSpan timeout)
- {
- base.OnOpen (timeout);
- StartListening (timeout);
- }
-
- protected override void OnAbort ()
- {
- httpChannelManager.Stop (true);
- }
-
- protected override void OnClose (TimeSpan timeout)
- {
- if (State == CommunicationState.Closed)
- return;
- base.OnClose (timeout);
- // FIXME: it is said that channels are not closed
- // when the channel listener is closed.
- // http://blogs.msdn.com/drnick/archive/2006/03/22/557642.aspx
- httpChannelManager.Stop (false);
- }
-
- void StartListening (TimeSpan timeout)
+ protected override HttpListenerManager CreateListenerManager ()
{
- httpChannelManager = new HttpListenerManager<TChannel> (this);
- httpChannelManager.Open (timeout);
+ return new HttpSimpleListenerManager (this, Source, SecurityTokenManager, ChannelDispatcher);
}
}
{
}
- SvcHttpHandler http_handler;
- internal SvcHttpHandler HttpHandler {
- get {
- if (http_handler == null)
- http_handler = SvcHttpHandlerFactory.GetHandlerForListener (this);
- return http_handler;
- }
- }
-
protected override TChannel CreateChannel (TimeSpan timeout)
{
if (typeof (TChannel) == typeof (IReplyChannel))
return (TChannel) (object) new AspNetReplyChannel ((AspNetChannelListener<IReplyChannel>) (object) this);
- // FIXME: session channel support
- if (typeof (TChannel) == typeof (IReplySessionChannel))
- throw new NotImplementedException ();
throw new NotSupportedException (String.Format ("Channel type {0} is not supported", typeof (TChannel)));
}
- protected override void OnAbort ()
- {
- HttpHandler.UnregisterListener (this);
- }
-
- protected override void OnOpen (TimeSpan timeout)
+ protected override HttpListenerManager CreateListenerManager ()
{
- base.OnOpen (timeout);
- HttpHandler.RegisterListener (this);
- }
-
- protected override void OnClose (TimeSpan timeout)
- {
- HttpHandler.UnregisterListener (this);
- base.OnClose (timeout);
+ return new AspNetListenerManager (this, Source, SecurityTokenManager, ChannelDispatcher);
}
}
internal abstract class HttpChannelListenerBase<TChannel> : InternalChannelListenerBase<TChannel>
where TChannel : class, IChannel
{
- HttpTransportBindingElement source;
- BindingContext context;
List<TChannel> channels = new List<TChannel> ();
MessageEncoder encoder;
+ HttpListenerManager httpChannelManager;
+
+ internal static HttpChannelListenerBase<TChannel>CurrentHttpChannelListener;
public HttpChannelListenerBase (HttpTransportBindingElement source,
BindingContext context)
: base (context)
{
+ if (ServiceHostBase.CurrentServiceHostHack != null)
+ DispatcherBuilder.ChannelDispatcherSetter = delegate (ChannelDispatcher cd) { this.ChannelDispatcher = cd; };
+
+ this.Source = source;
+ // The null Uri check looks weird, but it seems the listener can be built without it.
+ // See HttpTransportBindingElementTest.BuildChannelListenerWithoutListenUri().
+ if (Uri != null && source.Scheme != Uri.Scheme)
+ throw new ArgumentException (String.Format ("Requested listen uri scheme must be {0}, but was {1}.", source.Scheme, Uri.Scheme));
+
foreach (BindingElement be in context.RemainingBindingElements) {
MessageEncodingBindingElement mbe = be as MessageEncodingBindingElement;
if (mbe != null) {
}
if (encoder == null)
encoder = new TextMessageEncoder (MessageVersion.Default, Encoding.UTF8);
+
+ if (context.BindingParameters.Contains (typeof (ServiceCredentials)))
+ SecurityTokenManager = new ServiceCredentialsSecurityTokenManager ((ServiceCredentials) context.BindingParameters [typeof (ServiceCredentials)]);
+ }
+
+ internal ChannelDispatcher ChannelDispatcher { get; set; }
+
+ public HttpTransportBindingElement Source { get; private set; }
+
+ public HttpListenerManager ListenerManager {
+ get { return httpChannelManager; }
}
public MessageEncoder MessageEncoder {
get { return encoder; }
}
+ public ServiceCredentialsSecurityTokenManager SecurityTokenManager { get; private set; }
+
protected override TChannel OnAcceptChannel (TimeSpan timeout)
{
TChannel ch = CreateChannel (timeout);
throw new NotImplementedException ();
}
- protected override void OnAbort ()
+ protected abstract HttpListenerManager CreateListenerManager ();
+
+ protected override void OnOpen (TimeSpan timeout)
{
- OnClose (TimeSpan.Zero);
+ httpChannelManager = CreateListenerManager ();
+ Properties.Add (httpChannelManager);
+ httpChannelManager.Open (timeout);
}
- protected override void OnOpen (TimeSpan timeout)
+ protected override void OnAbort ()
{
+ httpChannelManager.Stop (true);
}
protected override void OnClose (TimeSpan timeout)
{
- DateTime start = DateTime.Now;
- base.OnClose (timeout - (DateTime.Now - start));
+ if (State == CommunicationState.Closed)
+ return;
+ base.OnClose (timeout);
+ // The channels are kept open when the creator channel listener is closed.
+ // http://blogs.msdn.com/drnick/archive/2006/03/22/557642.aspx
+ httpChannelManager.Stop (false);
}
}
}