2010-07-05 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Mon, 5 Jul 2010 09:31:51 +0000 (09:31 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Mon, 5 Jul 2010 09:31:51 +0000 (09:31 -0000)
* HttpStandaloneReplyChannel.cs
  HttpContextInfo.cs
  HttpListenerManager.cs
  HttpStandaloneRequestContext.cs
  HttpListenerManagerTable.cs : revert previous changes, regression
  on wsdl support.

svn path=/trunk/mcs/; revision=159881

mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpContextInfo.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpListenerManager.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpListenerManagerTable.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpStandaloneReplyChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpStandaloneRequestContext.cs

index 5b798d7c81874cd3bc47231726867b9d6d6b756a..0304e07b866cd48381e0b9a3b2f363518d54a99d 100644 (file)
@@ -1,3 +1,12 @@
+2010-07-05  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * HttpStandaloneReplyChannel.cs
+         HttpContextInfo.cs
+         HttpListenerManager.cs
+         HttpStandaloneRequestContext.cs
+         HttpListenerManagerTable.cs : revert previous changes, regression
+         on wsdl support.
+
 2010-07-02  Atsushi Enomoto  <atsushi@ximian.com>
 
        * HttpStandaloneReplyChannel.cs, HttpStandaloneRequestContext.cs:
index 8d014afcefc8721d7b3faac49d863fc8481296ac..219812f0f462e0d952fc18fa7987e21b6f6752df 100644 (file)
@@ -30,11 +30,9 @@ using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.IO;
 using System.Net;
-using System.Security.Principal;
 using System.ServiceModel;
 using System.Text;
 using System.Threading;
-using System.Web;
 
 namespace System.ServiceModel.Channels.Http
 {
@@ -90,47 +88,4 @@ namespace System.ServiceModel.Channels.Http
                        ctx.Response.StatusCode = 401;
                }
        }
-
-       class AspNetHttpContextInfo : HttpContextInfo
-       {
-               public AspNetHttpContextInfo (HttpContext ctx)
-               {
-                       this.ctx = ctx;
-               }
-               
-               HttpContext ctx;
-
-               public HttpContext Source {
-                       get { return ctx; }
-               }
-
-               public override NameValueCollection QueryString {
-                       get { return ctx.Request.QueryString; }
-               }
-               public override Uri RequestUrl {
-                       get { return ctx.Request.Url; }
-               }
-               public override string HttpMethod {
-                       get { return ctx.Request.HttpMethod; }
-               }
-
-               public override void Abort ()
-               {
-                       ctx.Response.Close ();
-               }
-
-               public override string User {
-                       get { return ctx.User != null ? ((GenericIdentity) ctx.User.Identity).Name : null; }
-               }
-
-               // FIXME: how to acquire this?
-               public override string Password {
-                       get { return null; }
-               }
-
-               public override void ReturnUnauthorized ()
-               {
-                       ctx.Response.StatusCode = 401;
-               }
-       }
 }
index 3bae51bd5fbfbca49cbeab7060adc0b3fab2166e..f40b96b8b5a8fee74df71f32c94138735516ce5a 100644 (file)
@@ -41,71 +41,9 @@ using System.Threading;
 
 namespace System.ServiceModel.Channels.Http
 {
-       internal abstract class HttpListenerManager
+       internal class HttpListenerManager
        {
-               protected HttpListenerManager ()
-               {
-                       Entries = new List<HttpChannelListenerEntry> ();
-               }
-
-               public List<HttpChannelListenerEntry> Entries { get; private set; }
-
-               public abstract void RegisterListener (ChannelDispatcher channel, TimeSpan timeout);
-               public abstract void UnregisterListener (ChannelDispatcher channel, TimeSpan timeout);
-
-               protected void RegisterListenerCommon (ChannelDispatcher channel, TimeSpan timeout)
-               {
-                       Entries.Add (new HttpChannelListenerEntry (channel, new AutoResetEvent (false)));
-
-                       Entries.Sort (HttpChannelListenerEntry.CompareEntries);
-               }
-
-               protected void UnregisterListenerCommon (ChannelDispatcher channel, TimeSpan timeout)
-               {
-                       var entry = Entries.First (e => e.ChannelDispatcher == channel);
-                       Entries.Remove (entry);
-
-                       entry.WaitHandle.Set (); // make sure to finish pending requests.
-               }
-
-               public void ProcessNewContext (HttpContextInfo ctxi)
-               {
-                       var ce = SelectChannel (ctxi);
-                       if (ce == null)
-                               throw new InvalidOperationException ("HttpListenerContext does not match any of the registered channels");
-                       ce.ContextQueue.Enqueue (ctxi);
-                       ce.WaitHandle.Set ();
-               }
-
-               HttpChannelListenerEntry SelectChannel (HttpContextInfo ctx)
-               {
-                       foreach (var e in Entries)
-                               if (e.FilterHttpContext (ctx))
-                                       return e;
-                       return null;
-               }
-
-               public bool TryDequeueRequest (ChannelDispatcher channel, TimeSpan timeout, out HttpContextInfo context)
-               {
-                       DateTime start = DateTime.Now;
-
-                       context = null;
-                       var ce = Entries.First (e => e.ChannelDispatcher == channel);
-                       lock (ce.RetrieverLock) {
-                               var q = ce.ContextQueue;
-                               if (q.Count == 0) {
-                                       bool ret = ce.WaitHandle.WaitOne (timeout);
-                                       return ret && TryDequeueRequest (channel, timeout - (DateTime.Now - start), out context); // recurse, am lazy :/
-                               }
-                               context = q.Dequeue ();
-                               return true;
-                       }
-               }
-       }
-
-       internal class HttpStandaloneListenerManager : HttpListenerManager
-       {
-               public HttpStandaloneListenerManager (Uri uri)
+               public HttpListenerManager (Uri uri)
                {
                        var l = new HttpListener ();
 
@@ -119,15 +57,18 @@ namespace System.ServiceModel.Channels.Http
                }
                
                HttpListener listener;
+               List<HttpChannelListenerEntry> entries = new List<HttpChannelListenerEntry> ();
 
                Thread loop;
 
                // FIXME: use timeout
-               public override void RegisterListener (ChannelDispatcher channel, TimeSpan timeout)
+               public void RegisterListener (ChannelDispatcher channel, TimeSpan timeout)
                {
-                       RegisterListenerCommon (channel, timeout);
+                       entries.Add (new HttpChannelListenerEntry (channel, new AutoResetEvent (false)));
+
+                       entries.Sort (HttpChannelListenerEntry.CompareEntries);
 
-                       if (Entries.Count != 1)
+                       if (entries.Count != 1)
                                return;
 
                        // Start here. It is shared between channel listeners
@@ -150,12 +91,15 @@ namespace System.ServiceModel.Channels.Http
                }
 
                // FIXME: use timeout
-               public override void UnregisterListener (ChannelDispatcher channel, TimeSpan timeout)
+               public void UnregisterListener (ChannelDispatcher channel, TimeSpan timeout)
                {
-                       UnregisterListenerCommon (channel, timeout);
+                       var entry = entries.First (e => e.ChannelDispatcher == channel);
+                       entries.Remove (entry);
+
+                       entry.WaitHandle.Set (); // make sure to finish pending requests.
 
                        // stop the server if there is no more registered listener.
-                       if (Entries.Count > 0)
+                       if (entries.Count > 0)
                                return;
 
 #if true
@@ -177,24 +121,38 @@ namespace System.ServiceModel.Channels.Http
                {
                        if (ctx == null)
                                return;
-                       ProcessNewContext (new HttpStandaloneContextInfo (ctx));
-               }
-       }
 
-       internal class AspNetHttpListenerManager : HttpListenerManager
-       {
-               public AspNetHttpListenerManager (Uri uri)
-               {
+                       var ctxi = new HttpStandaloneContextInfo (ctx);
+                       var ce = SelectChannel (ctxi);
+                       if (ce == null)
+                               throw new InvalidOperationException ("HttpListenerContext does not match any of the registered channels");
+                       ce.ContextQueue.Enqueue (ctxi);
+                       ce.WaitHandle.Set ();
                }
 
-               public override void RegisterListener (ChannelDispatcher channel, TimeSpan timeout)
+               HttpChannelListenerEntry SelectChannel (HttpContextInfo ctx)
                {
-                       RegisterListenerCommon (channel, timeout);
+                       foreach (var e in entries)
+                               if (e.FilterHttpContext (ctx))
+                                       return e;
+                       return null;
                }
 
-               public override void UnregisterListener (ChannelDispatcher channel, TimeSpan timeout)
+               public bool TryDequeueRequest (ChannelDispatcher channel, TimeSpan timeout, out HttpContextInfo context)
                {
-                       UnregisterListenerCommon (channel, timeout);
+                       DateTime start = DateTime.Now;
+
+                       context = null;
+                       var ce = entries.First (e => e.ChannelDispatcher == channel);
+                       lock (ce.RetrieverLock) {
+                               var q = ce.ContextQueue;
+                               if (q.Count == 0) {
+                                       bool ret = ce.WaitHandle.WaitOne (timeout);
+                                       return ret && TryDequeueRequest (channel, timeout - (DateTime.Now - start), out context); // recurse, am lazy :/
+                               }
+                               context = q.Dequeue ();
+                               return true;
+                       }
                }
        }
 }
index 6c6a7e737664450a2c4d4bfd8b030e925da7ec34..11514d28e2fdad50e6ccc09d6a961233fda34399 100644 (file)
@@ -74,10 +74,7 @@ namespace System.ServiceModel.Channels.Http
                {
                        var m = listeners.FirstOrDefault (p => p.Key.Equals (uri)).Value;
                        if (m == null) {
-                               if (ServiceHostingEnvironment.InAspNet)
-                                       m = new AspNetHttpListenerManager (uri);
-                               else
-                                       m = new HttpStandaloneListenerManager (uri);
+                               m = new HttpListenerManager (uri);
                                listeners [uri] = m;
                        }
                        return m;
index b21eebd3b10685267dc0d12fcf593e26091c3e38..92e96e5a6f8bd17e2bdfa20f71aa6cce95d0d667 100644 (file)
@@ -39,6 +39,7 @@ namespace System.ServiceModel.Channels.Http
        internal class HttpStandaloneReplyChannel : HttpReplyChannel
        {
                HttpStandaloneChannelListener<IReplyChannel> source;
+               RequestContext reqctx;
 
                public HttpStandaloneReplyChannel (HttpStandaloneChannelListener<IReplyChannel> listener)
                        : base (listener)
@@ -46,75 +47,95 @@ namespace System.ServiceModel.Channels.Http
                        this.source = listener;
                }
 
-               protected override RequestContext CreateRequestContext (HttpContextInfo ctxi, Message msg)
+               protected override void OnAbort ()
                {
-                       var ctx = ((HttpStandaloneContextInfo) ctxi).Source;
-                       return new HttpStandaloneRequestContext (this, msg, ctx);
+                       AbortConnections (TimeSpan.Zero);
+                       base.OnAbort (); // FIXME: remove it. The base is wrong. But it is somehow required to not block some tests.
                }
 
-               protected override Message CreatePostMessage (HttpContextInfo ctxi)
+               public override bool CancelAsync (TimeSpan timeout)
                {
-                       var ctx = ((HttpStandaloneContextInfo) ctxi).Source;
+                       AbortConnections (timeout);
+                       // FIXME: this wait is sort of hack (because it should not be required), but without it some tests are blocked.
+                       // This hack even had better be moved to base.CancelAsync().
+                       if (CurrentAsyncResult != null)
+                               CurrentAsyncResult.AsyncWaitHandle.WaitOne (TimeSpan.FromMilliseconds (300));
+                       return base.CancelAsync (timeout);
+               }
 
-                       if (ctx.Response.StatusCode != 200) { // it's already invalid.
-                               ctx.Response.Close ();
-                               return null;
-                       }
+               void AbortConnections (TimeSpan timeout)
+               {
+                       if (reqctx != null)
+                               reqctx.Close (timeout);
+               }
 
-                       if (!Encoder.IsContentTypeSupported (ctx.Request.ContentType)) {
-                               ctx.Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType;
-                               ctx.Response.StatusDescription = String.Format (
-                                               "Expected content-type '{0}' but got '{1}'", Encoder.ContentType, ctx.Request.ContentType);
-                               ctx.Response.Close ();
+               bool close_started;
+
+               protected override void OnClose (TimeSpan timeout)
+               {
+                       if (close_started)
+                               return;
+                       close_started = true;
+                       DateTime start = DateTime.Now;
+
+                       // FIXME: consider timeout
+                       AbortConnections (timeout - (DateTime.Now - start));
 
-                               return null;
+                       base.OnClose (timeout - (DateTime.Now - start));
+               }
+
+               public override bool TryReceiveRequest (TimeSpan timeout, out RequestContext context)
+               {
+                       context = null;
+                       HttpContextInfo ctxi;
+                       if (!source.ListenerManager.TryDequeueRequest (source.ChannelDispatcher, timeout, out ctxi))
+                               return false;
+                       if (ctxi == null)
+                               return true; // returning true, yet context is null. This happens at closing phase.
+
+                       var ctx = ((HttpStandaloneContextInfo) ctxi).Source;
+                       if (ctx.Response.StatusCode != 200) { // it's already invalid.
+                               ctx.Response.Close ();
+                               return false;
                        }
 
                        // FIXME: supply maxSizeOfHeaders.
                        int maxSizeOfHeaders = 0x10000;
 
-                       var msg = Encoder.ReadMessage (
-                               ctx.Request.InputStream, maxSizeOfHeaders);
+                       Message msg = null;
+
+                       if (ctx.Request.HttpMethod == "POST") {
+                               if (!Encoder.IsContentTypeSupported (ctx.Request.ContentType)) {
+                                       ctx.Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType;
+                                       ctx.Response.StatusDescription = String.Format (
+                                                       "Expected content-type '{0}' but got '{1}'", Encoder.ContentType, ctx.Request.ContentType);
+                                       ctx.Response.Close ();
 
-                       if (MessageVersion.Envelope.Equals (EnvelopeVersion.Soap11) ||
-                           MessageVersion.Addressing.Equals (AddressingVersion.None)) {
-                               string action = GetHeaderItem (ctx.Request.Headers ["SOAPAction"]);
-                               if (action != null) {
-                                       if (action.Length > 2 && action [0] == '"' && action [action.Length] == '"')
-                                               action = action.Substring (1, action.Length - 2);
-                                       msg.Headers.Action = action;
+                                       return false;
                                }
-                       }
 
+                               msg = Encoder.ReadMessage (
+                                       ctx.Request.InputStream, maxSizeOfHeaders);
+
+                               if (MessageVersion.Envelope.Equals (EnvelopeVersion.Soap11) ||
+                                   MessageVersion.Addressing.Equals (AddressingVersion.None)) {
+                                       string action = GetHeaderItem (ctx.Request.Headers ["SOAPAction"]);
+                                       if (action != null) {
+                                               if (action.Length > 2 && action [0] == '"' && action [action.Length] == '"')
+                                                       action = action.Substring (1, action.Length - 2);
+                                               msg.Headers.Action = action;
+                                       }
+                               }
+                       } else if (ctx.Request.HttpMethod == "GET") {
+                               msg = Message.CreateMessage (MessageVersion.None, null); // HTTP GET-based request
+                       }
                        if (msg.Headers.To == null)
                                msg.Headers.To = ctx.Request.Url;
                        msg.Properties.Add ("Via", LocalAddress.Uri);
-                       msg.Properties.Add (HttpRequestMessageProperty.Name, CreateRequestProperty (ctxi.HttpMethod, ctx.Request.Url.Query, ctx.Request.Headers));
-
-                       return msg;
-               }
-
-               public override bool WaitForRequest (TimeSpan timeout)
-               {
-                       throw new NotImplementedException ();
-               }
-       }
-
-       internal class AspNetReplyChannel : HttpReplyChannel
-       {
-               public AspNetReplyChannel (HttpStandaloneChannelListener<IReplyChannel> listener)
-                       : base (listener)
-               {
-               }
-
-               protected override RequestContext CreateRequestContext (HttpContextInfo ctxi, Message msg)
-               {
-                       return new AspNetRequestContext (this, ctxi, msg);
-               }
-
-               protected override Message CreatePostMessage (HttpContextInfo ctxi)
-               {
-                       throw new NotImplementedException ();
+                       msg.Properties.Add (HttpRequestMessageProperty.Name, CreateRequestProperty (ctx.Request.HttpMethod, ctx.Request.Url.Query, ctx.Request.Headers));
+                       context = new HttpStandaloneRequestContext (this, msg, ctx);
+                       reqctx = context;
+                       return true;
                }
 
                public override bool WaitForRequest (TimeSpan timeout)
@@ -126,7 +147,6 @@ namespace System.ServiceModel.Channels.Http
        internal abstract class HttpReplyChannel : InternalReplyChannelBase
        {
                HttpStandaloneChannelListener<IReplyChannel> source;
-               RequestContext reqctx;
 
                protected HttpReplyChannel (HttpStandaloneChannelListener<IReplyChannel> listener)
                        : base (listener)
@@ -154,43 +174,6 @@ namespace System.ServiceModel.Channels.Http
                {
                }
 
-               protected override void OnAbort ()
-               {
-                       AbortConnections (TimeSpan.Zero);
-                       base.OnAbort (); // FIXME: remove it. The base is wrong. But it is somehow required to not block some tests.
-               }
-
-               public override bool CancelAsync (TimeSpan timeout)
-               {
-                       AbortConnections (timeout);
-                       // FIXME: this wait is sort of hack (because it should not be required), but without it some tests are blocked.
-                       // This hack even had better be moved to base.CancelAsync().
-                       if (CurrentAsyncResult != null)
-                               CurrentAsyncResult.AsyncWaitHandle.WaitOne (TimeSpan.FromMilliseconds (300));
-                       return base.CancelAsync (timeout);
-               }
-
-               void AbortConnections (TimeSpan timeout)
-               {
-                       if (reqctx != null)
-                               reqctx.Close (timeout);
-               }
-
-               bool close_started;
-
-               protected override void OnClose (TimeSpan timeout)
-               {
-                       if (close_started)
-                               return;
-                       close_started = true;
-                       DateTime start = DateTime.Now;
-
-                       // FIXME: consider timeout
-                       AbortConnections (timeout - (DateTime.Now - start));
-
-                       base.OnClose (timeout - (DateTime.Now - start));
-               }
-
                protected string GetHeaderItem (string raw)
                {
                        if (raw == null || raw.Length == 0)
@@ -215,31 +198,5 @@ namespace System.ServiceModel.Channels.Http
                        prop.Headers.Add (headers);
                        return prop;
                }
-
-               protected abstract RequestContext CreateRequestContext (HttpContextInfo ctxi, Message msg);
-               protected abstract Message CreatePostMessage (HttpContextInfo ctxi);
-
-               public override bool TryReceiveRequest (TimeSpan timeout, out RequestContext context)
-               {
-                       context = null;
-                       HttpContextInfo ctxi;
-                       if (!source.ListenerManager.TryDequeueRequest (source.ChannelDispatcher, timeout, out ctxi))
-                               return false;
-                       if (ctxi == null)
-                               return true; // returning true, yet context is null. This happens at closing phase.
-
-                       Message msg = null;
-
-                       if (ctxi.HttpMethod == "POST") {
-                               msg = CreatePostMessage (ctxi);
-                               if (msg == null)
-                                       return false;
-                       } else if (ctxi.HttpMethod == "GET")
-                               msg = Message.CreateMessage (MessageVersion.None, null); // HTTP GET-based request
-
-                       context = CreateRequestContext (ctxi, msg);
-                       reqctx = context;
-                       return true;
-               }
        }
 }
index d42cb3183fa1a59bb07eb8be7f83647d5e779c1e..f45cd2a051d7422b7940fa5333d3b474a8083877 100644 (file)
@@ -32,11 +32,13 @@ using System.Threading;
 
 namespace System.ServiceModel.Channels.Http
 {
-       internal class HttpStandaloneRequestContext : HttpRequestContextBase
+       internal class HttpStandaloneRequestContext : HttpStandaloneRequestContextBase
        {
                HttpListenerContext ctx;
 
-               public HttpStandaloneRequestContext (HttpReplyChannel channel, Message msg, HttpListenerContext ctx)
+               public HttpStandaloneRequestContext (
+                       HttpStandaloneReplyChannel channel,
+                       Message msg, HttpListenerContext ctx)
                        : base (channel, msg)
                {
                        if (ctx == null)
@@ -98,37 +100,13 @@ namespace System.ServiceModel.Channels.Http
                }
        }
 
-       internal class AspNetRequestContext : HttpRequestContextBase
-       {
-               public AspNetRequestContext (AspNetReplyChannel channel, HttpContextInfo ctxi, Message request)
-                       : base (channel, request)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override void Abort ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override void ProcessReply (Message msg, TimeSpan timeout)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               public override void Close (TimeSpan timeout)
-               {
-                       throw new NotImplementedException ();
-               }
-       }
-
-       internal abstract class HttpRequestContextBase : RequestContext
+       internal abstract class HttpStandaloneRequestContextBase : RequestContext
        {
                Message request;
-               HttpReplyChannel channel;
+               HttpStandaloneReplyChannel channel;
 
-               public HttpRequestContextBase (
-                       HttpReplyChannel channel,
+               public HttpStandaloneRequestContextBase (
+                       HttpStandaloneReplyChannel channel,
                        Message request)
                {
                        if (channel == null)
@@ -143,7 +121,7 @@ namespace System.ServiceModel.Channels.Http
                        get { return request; }
                }
 
-               public HttpReplyChannel Channel {
+               public HttpStandaloneReplyChannel Channel {
                        get { return channel; }
                }