Jelajahi Sumber

support action parameter in SOAP 1.2 content type. Close pull request #133.

Atsushi Eno 14 tahun lalu
induk
melakukan
e8cc6770c2

+ 94 - 0
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ContentType.cs

@@ -0,0 +1,94 @@
+//
+// System.Net.Mime.ContentType.cs
+//
+// Authors:
+//	Tim Coleman ([email protected])
+//	John Luke ([email protected])
+//	Atsushi Eno ([email protected])
+//
+// 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; }
+		}
+	}
+}
+

+ 13 - 1
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TextMessageEncoder.cs

@@ -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)
 		{

+ 1 - 0
mcs/class/System.ServiceModel/System.ServiceModel.dll.sources

@@ -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

+ 14 - 0
mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TextMessageEncodingBindingElementTest.cs

@@ -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");
+		}
 	}
 }

+ 1 - 0
mcs/class/System.ServiceModel/moonlight_raw_System.ServiceModel.dll.sources

@@ -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