2009-10-06 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / HttpChannelListener.cs
index a1aeca44f00113d3e74ace38cf850cca39dacc0d..0bb1223be40b1543fa442fad6ae91fb72a96748e 100644 (file)
@@ -28,6 +28,7 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.Linq;
 using System.Net;
 using System.Net.Security;
 using System.ServiceModel;
@@ -52,13 +53,24 @@ namespace System.ServiceModel.Channels
                        get {  return httpChannelManager.HttpListener; }
                }
 
+               object creator_lock = new object ();
+
                protected override TChannel CreateChannel (TimeSpan timeout)
+               {
+                       lock (creator_lock) {
+                               return CreateChannelCore (timeout);
+                       }
+               }
+
+               TChannel CreateChannelCore (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 ();
 
-                       // FIXME: implement more
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException (String.Format ("Channel type {0} is not supported", typeof (TChannel)));
                }
 
                protected override void OnOpen (TimeSpan timeout)
@@ -67,10 +79,20 @@ namespace System.ServiceModel.Channels
                        StartListening (timeout);
                }
 
+               protected override void OnAbort ()
+               {
+                       httpChannelManager.Stop (true);
+               }
+
                protected override void OnClose (TimeSpan timeout)
                {
+                       if (State == CommunicationState.Closed)
+                               return;
                        base.OnClose (timeout);
-                       httpChannelManager.Stop ();
+                       // 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)
@@ -89,13 +111,35 @@ namespace System.ServiceModel.Channels
                {
                }
 
+               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 ();
 
-                       // FIXME: implement more
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException (String.Format ("Channel type {0} is not supported", typeof (TChannel)));
+               }
+
+               protected override void OnAbort ()
+               {
+                       HttpHandler.CloseServiceChannel ();
+               }
+
+               protected override void OnClose (TimeSpan timeout)
+               {
+                       HttpHandler.CloseServiceChannel ();
+                       base.OnClose (timeout);
                }
        }
 
@@ -104,19 +148,13 @@ namespace System.ServiceModel.Channels
        {
                HttpTransportBindingElement source;
                BindingContext context;
-               Uri listen_uri;
                List<TChannel> channels = new List<TChannel> ();
                MessageEncoder encoder;
 
                public HttpChannelListenerBase (HttpTransportBindingElement source,
                        BindingContext context)
-                       : base (context.Binding)
+                       : base (context)
                {
-
-                       // FIXME: consider ListenUriMode
-                       // FIXME: there should be some way to post-provide Uri in case of null listenerUri in context.
-                       listen_uri = context.ListenUriBaseAddress != null ?
-                               new Uri (context.ListenUriBaseAddress, context.ListenUriRelativeAddress) : null;
                        foreach (BindingElement be in context.RemainingBindingElements) {
                                MessageEncodingBindingElement mbe = be as MessageEncodingBindingElement;
                                if (mbe != null) {
@@ -132,18 +170,9 @@ namespace System.ServiceModel.Channels
                        get { return encoder; }
                }
 
-               public override Uri Uri {
-                       get { return listen_uri; }
-               }
-
-               protected IList<TChannel> Channels {
-                       get { return channels; }
-               }
-
                protected override TChannel OnAcceptChannel (TimeSpan timeout)
                {
                        TChannel ch = CreateChannel (timeout);
-                       Channels.Add (ch);
                        return ch;
                }
 
@@ -154,9 +183,9 @@ namespace System.ServiceModel.Channels
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO ("find out what to do here.")]
                protected override void OnAbort ()
                {
+                       OnClose (TimeSpan.Zero);
                }
 
                protected override void OnOpen (TimeSpan timeout)
@@ -165,8 +194,8 @@ namespace System.ServiceModel.Channels
 
                protected override void OnClose (TimeSpan timeout)
                {
-                       foreach (TChannel ch in Channels)
-                               ch.Close(timeout);
+                       DateTime start = DateTime.Now;
+                       base.OnClose (timeout - (DateTime.Now - start));
                }
        }
 }