2009-10-02 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 2 Oct 2009 05:37:15 +0000 (05:37 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 2 Oct 2009 05:37:15 +0000 (05:37 -0000)
* HttpReplyChannel.cs, AspNetReplyChannel.cs, AspNetRequestContext.cs:
  asp.net response was not written correctly.
  Fill HttpRequestMessageProperty to get handle WSDL requests
  processed in ServiceMetadataExtension without NRE.
  Remove wrong HttpListenerContext iteration at Abort and Close in
  common base class and move it to non-asp derived channel.

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

mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetReplyChannel.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetRequestContext.cs
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpReplyChannel.cs

index 16886db4b35bbbaf16d896644a30aad9ed40fd73..38faae768d519d7c4420a4eddfdfbde9b9e89ccc 100644 (file)
@@ -75,31 +75,28 @@ namespace System.ServiceModel.Channels
                        if (!WaitForRequest (timeout))
                                return false;
 
-Console.WriteLine ("Received HTTP request {0} on channel {1}", http_context.Request.Url, LocalAddress);
                        Message msg;
-                       // FIXME: remove this hack
-                       if (http_context.Request.HttpMethod == "GET") {
-                               if (http_context.Request.QueryString ["wsdl"] != null) {
-                                       msg = Message.CreateMessage (Encoder.MessageVersion,
-                                               "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
-                                       msg.Headers.To = http_context.Request.Url;
-                               } else {
-                                       msg = Message.CreateMessage (Encoder.MessageVersion, null);
-                                       msg.Headers.To = http_context.Request.Url;
-                               }
+                       var req = http_context.Request;
+                       if (req.HttpMethod == "GET") {
+                               msg = Message.CreateMessage (Encoder.MessageVersion, null);
+                               msg.Headers.To = req.Url;
                        } else {
                                //FIXME: Do above stuff for HttpContext ?
                                int maxSizeOfHeaders = 0x10000;
 
                                msg = Encoder.ReadMessage (
-                                       http_context.Request.InputStream, maxSizeOfHeaders);
+                                       req.InputStream, maxSizeOfHeaders);
 
                                if (Encoder.MessageVersion.Envelope == EnvelopeVersion.Soap11) {
-                                       string action = GetHeaderItem (http_context.Request.Headers ["SOAPAction"]);
+                                       string action = GetHeaderItem (req.Headers ["SOAPAction"]);
                                        if (action != null)
                                                msg.Headers.Action = action;
                                }
                        }
+
+                       // FIXME: prop.SuppressEntityBody
+                       msg.Properties.Add (HttpRequestMessageProperty.Name, CreateRequestProperty (req.HttpMethod, req.Url.Query, req.Headers));
+
                        context = new AspNetRequestContext (this, msg, http_context);
 
                        return true;
index 0955b92793dae9e9b8b90294c1f51ada45b0898b..9cbb4bf3c5812f05c5adee308633377e650b190f 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Globalization;
 using System.IO;
+using System.Net;
 using System.Web;
 
 namespace System.ServiceModel.Channels {
 
        class AspNetRequestContext : HttpRequestContextBase
        {
-               AspNetReplyChannel owner;
+               AspNetReplyChannel channel;
                HttpContext ctx;
 
                public AspNetRequestContext (
@@ -41,7 +43,7 @@ namespace System.ServiceModel.Channels {
                        Message msg, HttpContext ctx)
                        : base (channel, msg)
                {
-                       this.owner = owner;
+                       this.channel = channel;
                        this.ctx = ctx;
                }
 
@@ -49,7 +51,7 @@ namespace System.ServiceModel.Channels {
                {
                        //ctx.Response.Abort ();
                        ctx = null;
-                       owner.CloseContext ();
+                       channel.CloseContext ();
                }
 
                protected override void ProcessReply (Message msg, TimeSpan timeout)
@@ -57,20 +59,34 @@ namespace System.ServiceModel.Channels {
                        ctx.Response.ContentType = Channel.Encoder.ContentType;
                        MemoryStream ms = new MemoryStream ();
                        Channel.Encoder.WriteMessage (msg, ms);
-                       //ctx.Response.ContentLength64 = ms.Length;
-                       ctx.Response.OutputStream.Write (ms.GetBuffer (), 0, (int) ms.Length);
-                       ctx.Response.OutputStream.Flush ();
+
+                       string pname = HttpResponseMessageProperty.Name;
+                       bool suppressEntityBody = false;
+                       if (msg.Properties.ContainsKey (pname)) {
+                               HttpResponseMessageProperty hp = (HttpResponseMessageProperty) msg.Properties [pname];
+                               string contentType = hp.Headers ["Content-Type"];
+                               if (contentType != null)
+                                       ctx.Response.ContentType = contentType;
+                               ctx.Response.Headers.Add (hp.Headers);
+                               if (hp.StatusCode != default (HttpStatusCode))
+                                       ctx.Response.StatusCode = (int) hp.StatusCode;
+                               ctx.Response.StatusDescription = hp.StatusDescription;
+                               if (hp.SuppressEntityBody)
+                                       suppressEntityBody = true;
+                       }
+                       if (!suppressEntityBody) {
+                               ctx.Response.AddHeader ("Content-Length", ms.Length.ToString (CultureInfo.InvariantCulture));
+                               ctx.Response.OutputStream.Write (ms.GetBuffer (), 0, (int) ms.Length);
+                               ctx.Response.OutputStream.Flush ();
+                       }
+                       else
+                               ctx.Response.SuppressContent = true;
                }
 
                public override void Close (TimeSpan timeout)
                {
-                       // FIXME: use timeout
-                       try {
-                               ctx.Response.Close ();
-                       } finally {
-                               ctx = null;
-                               owner.CloseContext ();
-                       }
+                       ctx = null;
+                       channel.CloseContext ();
                }
        }
 }
index 7d6e1f8f7ab8d1d674c73bdd6335b1001ddccee6..ba9bae77f0a0237dd9268cb21911ff115e3b361f 100755 (executable)
@@ -1,3 +1,12 @@
+2009-10-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * HttpReplyChannel.cs, AspNetReplyChannel.cs, AspNetRequestContext.cs:
+         asp.net response was not written correctly.
+         Fill HttpRequestMessageProperty to get handle WSDL requests
+         processed in ServiceMetadataExtension without NRE.
+         Remove wrong HttpListenerContext iteration at Abort and Close in
+         common base class and move it to non-asp derived channel.
+
 2009-10-02  Atsushi Enomoto  <atsushi@ximian.com>
 
        * SvcHttpHandler.cs : remove unused code.
index ea3bade78475423bfde03147c2cd7db0d645f54a..dc396e395ee65aa95e1ad5c34fc56d5c7d7626fc 100644 (file)
@@ -27,6 +27,7 @@
 //
 using System;
 using System.Collections.Generic;
+using System.Collections.Specialized;
 using System.IO;
 using System.Net;
 using System.ServiceModel;
@@ -47,11 +48,24 @@ namespace System.ServiceModel.Channels
                        this.source = listener;
                }
 
+               protected override void OnAbort ()
+               {
+                       foreach (HttpListenerContext ctx in waiting)
+                               ctx.Response.Abort ();
+
+                       base.OnAbort ();
+               }
+
                protected override void OnClose (TimeSpan timeout)
                {
                        DateTime start = DateTime.Now;
                        if (reqctx != null)
                                reqctx.Close (timeout);
+
+                       // FIXME: consider timeout
+                       foreach (HttpListenerContext ctx in waiting)
+                               ctx.Response.Close ();
+
                        base.OnClose (timeout - (DateTime.Now - start));
                }
 
@@ -109,15 +123,7 @@ namespace System.ServiceModel.Channels
                        }
                        msg.Headers.To = ctx.Request.Url;
                        
-                       HttpRequestMessageProperty prop =
-                               new HttpRequestMessageProperty ();
-                       prop.Method = ctx.Request.HttpMethod;
-                       prop.QueryString = ctx.Request.Url.Query;
-                       if (prop.QueryString.StartsWith ("?"))
-                               prop.QueryString = prop.QueryString.Substring (1);
-                       // FIXME: prop.SuppressEntityBody
-                       prop.Headers.Add (ctx.Request.Headers);
-                       msg.Properties.Add (HttpRequestMessageProperty.Name, prop);
+                       msg.Properties.Add (HttpRequestMessageProperty.Name, CreateRequestProperty (ctx.Request.HttpMethod, ctx.Request.Url.Query, ctx.Request.Headers));
 /*
 MessageBuffer buf = msg.CreateBufferedCopy (0x10000);
 msg = buf.CreateMessage ();
@@ -164,7 +170,6 @@ w.Close ();
        internal abstract class HttpReplyChannel : InternalReplyChannelBase
        {
                HttpChannelListenerBase<IReplyChannel> source;
-               List<HttpListenerContext> waiting = new List<HttpListenerContext> ();
 
                public HttpReplyChannel (HttpChannelListenerBase<IReplyChannel> listener)
                        : base (listener)
@@ -187,21 +192,6 @@ w.Close ();
                        return ctx;
                }
 
-               protected override void OnAbort ()
-               {
-                       base.OnAbort ();
-                       foreach (HttpListenerContext ctx in waiting)
-                               ctx.Request.InputStream.Close ();
-               }
-
-               protected override void OnClose (TimeSpan timeout)
-               {
-                       base.OnClose (timeout);
-                       // FIXME: consider timeout
-                       foreach (HttpListenerContext ctx in waiting)
-                               ctx.Request.InputStream.Close ();
-               }
-
                protected override void OnOpen (TimeSpan timeout)
                {
                }
@@ -220,5 +210,15 @@ w.Close ();
                        }
                        return raw;
                }
+
+               protected HttpRequestMessageProperty CreateRequestProperty (string method, string query, NameValueCollection headers)
+               {
+                       var prop = new HttpRequestMessageProperty ();
+                       prop.Method = method;
+                       prop.QueryString = query.StartsWith ("?") ? query.Substring (1) : query;
+                       // FIXME: prop.SuppressEntityBody
+                       prop.Headers.Add (headers);
+                       return prop;
+               }
        }
 }