support action parameter in SOAP 1.2 content type. Close pull request #133.
authorAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Mon, 18 Jul 2011 17:28:59 +0000 (02:28 +0900)
committerAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Mon, 18 Jul 2011 17:28:59 +0000 (02:28 +0900)
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ContentType.cs [new file with mode: 0644]
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TextMessageEncoder.cs
mcs/class/System.ServiceModel/System.ServiceModel.dll.sources
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TextMessageEncodingBindingElementTest.cs
mcs/class/System.ServiceModel/moonlight_raw_System.ServiceModel.dll.sources

diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ContentType.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ContentType.cs
new file mode 100644 (file)
index 0000000..c44c0a2
--- /dev/null
@@ -0,0 +1,94 @@
+//
+// System.Net.Mime.ContentType.cs
+//
+// Authors:
+//     Tim Coleman (tim@timcoleman.com)
+//     John Luke (john.luke@gmail.com)
+//     Atsushi Eno (atsushieno@veritas-vos-liberabit.com)
+//
+// Copyright (C) Tim Coleman, 2004
+// Copyright (C) John Luke, 2005
+// Copyright (C) Atsushi Eno, 2011
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace System.ServiceModel.Channels
+{
+       internal class ContentType
+       {
+               string mediaType;
+               Dictionary<string,string> parameters = new Dictionary<string,string> ();
+
+               public ContentType (string contentType)
+               {
+                       if (contentType == null)
+                               throw new ArgumentNullException ("contentType");
+                       if (contentType.Length == 0)
+                               throw new ArgumentException ("contentType");
+
+                       string[] split = contentType.Split (';');
+                       this.MediaType = split[0].Trim ();
+                       for (int i = 1; i < split.Length; i++)
+                               Parse (split[i].Trim ());
+               }
+
+               static char [] eq = new char [] { '=' };
+               void Parse (string pair)
+               {
+                       if (String.IsNullOrEmpty (pair))
+                               return;
+
+                       string [] split = pair.Split (eq, 2);
+                       string key = split [0].Trim ();
+                       string val =  (split.Length > 1) ? split [1].Trim () : "";
+                       int l = val.Length;
+                       if (l >= 2 && val [0] == '"' && val [l - 1] == '"')
+                               val = val.Substring (1, l - 2);
+                       parameters.Add (key, val);
+               }
+
+               public string MediaType {
+                       get { return mediaType; }
+                       set {
+                               if (value == null)
+                                       throw new ArgumentNullException ();
+                               if (value.Length < 1)
+                                       throw new ArgumentException ();
+                               if (value.IndexOf ('/') < 1)
+                                       throw new FormatException ();
+                               if (value.IndexOf (';') != -1)
+                                       throw new FormatException ();
+                               mediaType = value;
+                       }
+               }
+
+               public Dictionary<string,string> Parameters {
+                       get { return parameters; }
+               }
+       }
+}
+
index e89568fe742f119084543d1269b529e8c8cbe8b3..0ff234382a2e71750bcc894e33a008b7f56d9ab8 100644 (file)
@@ -66,7 +66,7 @@ namespace System.ServiceModel.Channels
                {
                        if (bufferManager == null)
                                throw new ArgumentNullException ("bufferManager");
-                       return Message.CreateMessage (
+                       var ret = Message.CreateMessage (
                                XmlDictionaryReader.CreateDictionaryReader (
                                        XmlReader.Create (new StreamReader (
                                                new MemoryStream (
@@ -75,6 +75,8 @@ namespace System.ServiceModel.Channels
                                // FIXME: supply max header size
                                int.MaxValue,
                                version);
+                       FillActionContentType (ret, contentType);
+                       return ret;
                }
 
                public override Message ReadMessage (Stream stream,
@@ -88,8 +90,18 @@ namespace System.ServiceModel.Channels
                                maxSizeOfHeaders,
                                version);
                        ret.Properties.Encoder = this;
+                       FillActionContentType (ret, contentType);
                        return ret;
                }
+               
+               void FillActionContentType (Message msg, string contentType)
+               {
+                       if (contentType.StartsWith ("application/soap+xml", StringComparison.Ordinal)) {
+                               var ct = new ContentType (contentType);
+                               if (ct.Parameters.ContainsKey ("action"))
+                                       msg.Headers.Action = ct.Parameters ["action"];
+                       }
+               }
 
                public override void WriteMessage (Message message, Stream stream)
                {
index b1b37d94cd4db8f2f490aca29d46c2c03eafaab4..36ce341867284718957a89edae8b690fef1f97e3 100644 (file)
@@ -161,6 +161,7 @@ System.ServiceModel.Channels/CompilationException.cs
 System.ServiceModel.Channels/CompositeDuplexBindingElement.cs
 System.ServiceModel.Channels/CompositeDuplexBindingElementImporter.cs
 System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs
+System.ServiceModel.Channels/ContentType.cs
 System.ServiceModel.Channels/CustomBinding.cs
 System.ServiceModel.Channels/DeliveryFailure.cs
 System.ServiceModel.Channels/DeliveryStatus.cs
index a4f59360ea1d467a3c07cbc70595b298c2891680..2d1651e428064c09e780eb653562429c93a439f9 100644 (file)
@@ -27,6 +27,7 @@
 //
 using System;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
@@ -137,5 +138,18 @@ namespace MonoTests.System.ServiceModel.Channels
                        var enc = new TextMessageEncodingBindingElement ().CreateMessageEncoderFactory ().Encoder;
                        enc.ReadMessage (new ArraySegment<byte> (new byte [0]), BufferManager.CreateBufferManager (1000, 1000), "text/xml");
                }
+               
+               [Test]
+               public void ActionContentTypeParameter ()
+               {
+                       var enc = new TextMessageEncodingBindingElement ().CreateMessageEncoderFactory ().Encoder;
+                       var msg = Message.CreateMessage (MessageVersion.Soap12, "urn:foo");
+                       var ms = new MemoryStream ();
+                       using (var xw = XmlWriter.Create (ms))
+                               msg.WriteMessage (xw);
+                       ms.Position = 0;
+                       msg = enc.ReadMessage (ms, 0x1000, "application/soap+xml; action=urn:bar");
+                       Assert.AreEqual ("urn:bar", msg.Headers.Action, "#1");
+               }
        }
 }
index 7a98d0aae7a8de2798776e1b8315c92e94dd979f..9ca8cd0b065756d2800bf49b6c52db64f7b5cac4 100755 (executable)
@@ -70,6 +70,7 @@ System.ServiceModel.Channels/ChannelManagerBase.cs
 System.ServiceModel.Channels/ChannelParameterCollection.cs
 System.ServiceModel.Channels/ChannelPoolSettings.cs
 System.ServiceModel.Channels/CommunicationObject.cs
+System.ServiceModel.Channels/ContentType.cs
 System.ServiceModel.Channels/CustomBinding.cs
 System.ServiceModel.Channels/FaultConverter.cs
 System.ServiceModel.Channels/HtmlizedException.cs