Ver Fonte

2010-07-02 Atsushi Enomoto <[email protected]>

	* Message.cs, MessageImpl.cs, MessageBufferImpl.cs : remove BodyId.
	  XML attributes on s:Body are handled appropriately, not limited to
	  wsu:Id. Added several required overrides to Message and
	  MessageBuffer implementation classes.
	* SecureMessageGenerator.cs : so, don't use BodyId. Treat it as a
	  specific case but still fallback.


svn path=/trunk/mcs/; revision=159800
Atsushi Eno há 15 anos atrás
pai
commit
2cb30316fb

+ 9 - 0
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog

@@ -1,3 +1,12 @@
+2010-07-02  Atsushi Enomoto  <[email protected]>
+
+	* Message.cs, MessageImpl.cs, MessageBufferImpl.cs : remove BodyId.
+	  XML attributes on s:Body are handled appropriately, not limited to
+	  wsu:Id. Added several required overrides to Message and
+	  MessageBuffer implementation classes.
+	* SecureMessageGenerator.cs : so, don't use BodyId. Treat it as a
+	  specific case but still fallback.
+
 2010-06-24  Atsushi Enomoto  <[email protected]>
 
 	* HttpTransportBindingElement.cs :

+ 13 - 11
mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs

@@ -26,6 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Runtime.Serialization;
 using System.Xml;
@@ -45,10 +46,7 @@ namespace System.ServiceModel.Channels
 
 		public abstract MessageHeaders Headers { get; }
 
-		internal string BodyId {
-			get { return body_id; }
-			set { body_id = value; }
-		}
+		Dictionary<XmlQualifiedName,string> attributes = new Dictionary<XmlQualifiedName,string> ();
 
 		public virtual bool IsEmpty {
 			get { return false; }
@@ -185,6 +183,9 @@ namespace System.ServiceModel.Channels
 				throw new InvalidOperationException (String.Format ("The message is already at {0} state", State));
 
 			OnWriteStartBody (writer);
+
+			foreach (var a in attributes)
+				writer.WriteAttributeString (a.Key.Name, a.Key.Namespace, a.Value);
 		}
 
 		public void WriteStartBody (XmlWriter writer)
@@ -223,14 +224,15 @@ namespace System.ServiceModel.Channels
 				WriteBodyContents (w);
 			var headers = new MessageHeaders (Headers);
 			var props = new MessageProperties (Properties);
-			return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (sw.ToString (), maxBufferSize, null), false);
+			return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (sw.ToString (), maxBufferSize, null), false, attributes);
 		}
 
 		protected virtual string OnGetBodyAttribute (
 			string localName, string ns)
 		{
-			// other than XmlReaderMessage it cannot return anything
-			return null;
+			var q = new XmlQualifiedName (localName, ns);
+			string v;
+			return attributes.TryGetValue (q, out v) ? v : null;
 		}
 
 		protected virtual XmlDictionaryReader OnGetReaderAtBodyContents ()
@@ -272,8 +274,6 @@ namespace System.ServiceModel.Channels
 		{
 			var dic = Constants.SoapDictionary;
 			writer.WriteStartElement ("s", dic.Add ("Body"), dic.Add (Version.Envelope.Namespace));
-			if (BodyId != null)
-				writer.WriteAttributeString ("u", dic.Add ("Id"), dic.Add (Constants.WsuNamespace), BodyId);
 		}
 
 		protected virtual void OnWriteStartEnvelope (
@@ -334,7 +334,7 @@ namespace System.ServiceModel.Channels
 			MessageFault fault, string action)
 		{
 			return new SimpleMessage (version, action,
-				new MessageFaultBodyWriter (fault, version), true);
+				new MessageFaultBodyWriter (fault, version), true, empty_attributes);
 		}
 
 		// 4)
@@ -385,6 +385,8 @@ namespace System.ServiceModel.Channels
 
 		// Core implementations of CreateMessage.
 
+		static readonly Dictionary<XmlQualifiedName,string> empty_attributes = new Dictionary<XmlQualifiedName,string> ();
+
 		// 9)
 		public static Message CreateMessage (MessageVersion version,
 			string action, BodyWriter body)
@@ -393,7 +395,7 @@ namespace System.ServiceModel.Channels
 				throw new ArgumentNullException ("version");
 			if (body == null)
 				throw new ArgumentNullException ("body");
-			return new SimpleMessage (version, action, body, false);
+			return new SimpleMessage (version, action, body, false, empty_attributes);
 		}
 
 		// 10)

+ 10 - 5
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageBufferImpl.cs

@@ -26,6 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System;
+using System.Collections.Generic;
 using System.Runtime.Serialization;
 using System.Xml;
 using System.Xml.XPath;
@@ -39,13 +40,14 @@ namespace System.ServiceModel.Channels
 		BodyWriter body;
 		bool closed, is_fault;
 		int max_buffer_size;
+		Dictionary<XmlQualifiedName,string> attributes;
 
-		internal DefaultMessageBuffer (MessageHeaders headers, MessageProperties properties)
-			: this (0, headers, properties, null, false)
+		internal DefaultMessageBuffer (MessageHeaders headers, MessageProperties properties, Dictionary<XmlQualifiedName,string> attributes)
+			: this (0, headers, properties, null, false, attributes)
 		{
 		}
 
-		internal DefaultMessageBuffer (int maxBufferSize, MessageHeaders headers, MessageProperties properties, BodyWriter body, bool isFault)
+		internal DefaultMessageBuffer (int maxBufferSize, MessageHeaders headers, MessageProperties properties, BodyWriter body, bool isFault, Dictionary<XmlQualifiedName,string> attributes)
 		{
 			this.max_buffer_size = maxBufferSize;
 			this.headers = headers;
@@ -53,6 +55,7 @@ namespace System.ServiceModel.Channels
 			this.closed = false;
 			this.is_fault = isFault;
 			this.properties = properties;
+			this.attributes = attributes;
 		}
 
 		public override void Close ()
@@ -74,7 +77,7 @@ namespace System.ServiceModel.Channels
 			if (body == null)
 				msg = new EmptyMessage (headers.MessageVersion, headers.Action);
 			else
-				msg = new SimpleMessage (headers.MessageVersion, headers.Action, body.CreateBufferedCopy (max_buffer_size), is_fault);
+				msg = new SimpleMessage (headers.MessageVersion, headers.Action, body.CreateBufferedCopy (max_buffer_size), is_fault, attributes);
 			msg.Headers.Clear ();
 			msg.Headers.CopyHeadersFrom (headers);
 			msg.Properties.CopyProperties (properties);
@@ -93,13 +96,15 @@ namespace System.ServiceModel.Channels
 		MessageVersion version;
 		int max_header_size;
 		MessageProperties properties;
+		Dictionary<XmlQualifiedName,string> attributes;
 
-		public XPathMessageBuffer (IXPathNavigable source, MessageVersion version, int maxSizeOfHeaders, MessageProperties properties)
+		public XPathMessageBuffer (IXPathNavigable source, MessageVersion version, int maxSizeOfHeaders, MessageProperties properties, Dictionary<XmlQualifiedName,string> attributes)
 		{
 			this.source = source;
 			this.version = version;
 			this.max_header_size = maxSizeOfHeaders;
 			this.properties = properties;
+			this.attributes = attributes;
 		}
 
 		public override void Close ()

+ 46 - 14
mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs

@@ -26,6 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 using System;
+using System.Collections.Generic;
 using System.Runtime.Serialization;
 using System.Xml;
 using System.IO;
@@ -40,6 +41,7 @@ namespace System.ServiceModel.Channels
 		MessageProperties properties = new MessageProperties ();
 		bool is_empty, is_fault, body_started, body_consumed;
 		int max_headers;
+		Dictionary<XmlQualifiedName,string> attributes;
 
 		public XmlReaderMessage (MessageVersion version, XmlDictionaryReader reader, int maxSizeOfHeaders)
 		{
@@ -86,23 +88,21 @@ namespace System.ServiceModel.Channels
 			ReadBodyStart ();
 			var headers = new MessageHeaders (Headers);
 			var props = new MessageProperties (Properties);
-			return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (reader), IsFault);
+			return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (reader), IsFault, attributes);
 		}
 
 		protected override string OnGetBodyAttribute (
 			string localName, string ns)
 		{
-			if (headers == null)
-				ReadHeaders ();
-			return reader.GetAttribute (localName, ns);
+			ReadBodyStart ();
+			string v;
+			return attributes.TryGetValue (new XmlQualifiedName (localName, ns), out v) ? v : null;
 		}
 
 		protected override XmlDictionaryReader OnGetReaderAtBodyContents ()
 		{
 			if (reader.ReadState == ReadState.Closed)
 				return reader; // silly, but that's what our test expects.
-			if (body_consumed)
-				throw new InvalidOperationException ("The message body XmlReader is already consumed.");
 			ReadBodyStart ();
 			if (is_empty)
 				throw new InvalidOperationException ("The message body is empty.");
@@ -166,6 +166,9 @@ namespace System.ServiceModel.Channels
 
 		void ReadBodyStart ()
 		{
+			if (body_consumed)
+				throw new InvalidOperationException ("The message body XmlReader is already consumed.");
+
 			if (body_started)
 				return;
 
@@ -176,8 +179,12 @@ namespace System.ServiceModel.Channels
 			// SOAP Body
 			body_started = true;
 			is_empty = reader.IsEmptyElement;
-			if (reader.MoveToAttribute ("Id", Constants.WsuNamespace)) {
-				BodyId = reader.Value;
+			attributes = new Dictionary<XmlQualifiedName,string> ();
+			reader.MoveToContent ();
+			if (reader.MoveToFirstAttribute ()) {
+				do {
+					attributes [new XmlQualifiedName (reader.LocalName, reader.NamespaceURI)] = reader.Value;
+				} while (reader.MoveToNextAttribute ());
 				reader.MoveToElement ();
 			}
 			reader.ReadStartElement ("Body", Version.Envelope.Namespace);
@@ -198,12 +205,18 @@ namespace System.ServiceModel.Channels
 	{
 		MessageHeaders headers;
 		MessageProperties properties = new MessageProperties ();
+		Dictionary<XmlQualifiedName,string> attributes;
 
-		public MessageImplBase (MessageVersion version, string action)
+		public MessageImplBase (MessageVersion version, string action, Dictionary<XmlQualifiedName,string> attributes)
 		{
 			headers = new MessageHeaders (version);
 			if (action != null)
 				headers.Action = action;
+			this.attributes = attributes;
+		}
+
+		internal Dictionary<XmlQualifiedName,string> Attributes {
+			get { return attributes; }
 		}
 
 		public override MessageHeaders Headers {
@@ -217,12 +230,30 @@ namespace System.ServiceModel.Channels
 		public override MessageVersion Version {
 			get { return Headers.MessageVersion; }
 		}
+
+		protected override string OnGetBodyAttribute (
+			string localName, string ns)
+		{
+			string v;
+			return attributes.TryGetValue (new XmlQualifiedName (localName, ns), out v) ? v : null;
+		}
+
+		protected override void OnWriteStartBody (
+			XmlDictionaryWriter writer)
+		{
+			var dic = Constants.SoapDictionary;
+			writer.WriteStartElement ("s", dic.Add ("Body"), dic.Add (Version.Envelope.Namespace));
+			foreach (var p in Attributes)
+				writer.WriteAttributeString (p.Key.Name, p.Key.Namespace, p.Value);
+		}
 	}
 
 	internal class EmptyMessage : MessageImplBase
 	{
+		static readonly Dictionary<XmlQualifiedName,string> empty_attributes = new Dictionary<XmlQualifiedName,string> ();
+
 		public EmptyMessage (MessageVersion version, string action)
-			: base (version, action)
+			: base (version, action, empty_attributes)
 		{
 		}
 
@@ -238,7 +269,7 @@ namespace System.ServiceModel.Channels
 		protected override MessageBuffer OnCreateBufferedCopy (
 			int maxBufferSize)
 		{
-			return new DefaultMessageBuffer (Headers, Properties);
+			return new DefaultMessageBuffer (Headers, Properties, Attributes);
 		}
 	}
 
@@ -248,8 +279,8 @@ namespace System.ServiceModel.Channels
 		bool is_fault;
 
 		public SimpleMessage (MessageVersion version,
-			string action, BodyWriter body, bool isFault)
-			: base (version, action)
+			string action, BodyWriter body, bool isFault, Dictionary<XmlQualifiedName,string> attributes)
+			: base (version, action, attributes)
 		{
 			this.body = body;
 			this.is_fault = isFault;
@@ -274,7 +305,8 @@ namespace System.ServiceModel.Channels
 		{
 			var headers = new MessageHeaders (Headers);
 			var props = new MessageProperties (Properties);
-			return new DefaultMessageBuffer (maxBufferSize, headers, props, body.CreateBufferedCopy (maxBufferSize), IsFault);
+			var atts = new Dictionary<XmlQualifiedName,string> (Attributes);
+			return new DefaultMessageBuffer (maxBufferSize, headers, props, body.CreateBufferedCopy (maxBufferSize), IsFault, atts);
 		}
 	}
 }

+ 46 - 2
mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs

@@ -577,10 +577,9 @@ else
 				break;
 			}
 
-			Message ret = Message.CreateMessage (msg.Version, msg.Headers.Action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement));
+			Message ret = new WSSecurityMessage (Message.CreateMessage (msg.Version, msg.Headers.Action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement)), bodyId);
 			ret.Properties.Security = (SecurityMessageProperty) secprop.CreateCopy ();
 			ret.Properties.Security.EncryptionKey = masterKey.Key;
-			ret.BodyId = bodyId;
 
 			// FIXME: can we support TransportToken here?
 			if (element is AsymmetricSecurityBindingElement) {
@@ -708,4 +707,49 @@ else
 			return ret;
 		}
 	}
+
+	internal class WSSecurityMessage : Message
+	{
+		Message msg;
+		string body_id;
+
+		public WSSecurityMessage (Message msg, string bodyId)
+		{
+			this.msg = msg;
+			this.body_id = bodyId;
+		}
+
+		public override MessageVersion Version {
+			get { return msg.Version; }
+		}
+
+		public override MessageHeaders Headers {
+			get { return msg.Headers; }
+		}
+
+		public override MessageProperties Properties {
+			get { return msg.Properties; }
+		}
+
+		protected override string OnGetBodyAttribute (string localName, string ns)
+		{
+			if (localName == "Id" && ns == Constants.WsuNamespace)
+				return body_id;
+			return msg.GetBodyAttribute (localName, ns);
+		}
+
+		protected override void OnWriteStartBody (
+			XmlDictionaryWriter writer)
+		{
+			var dic = Constants.SoapDictionary;
+			writer.WriteStartElement ("s", dic.Add ("Body"), dic.Add (Version.Envelope.Namespace));
+			if (body_id != null)
+				writer.WriteAttributeString ("Id", Constants.WsuNamespace, body_id);
+		}
+
+		protected override void OnWriteBodyContents (XmlDictionaryWriter w)
+		{
+			msg.WriteBodyContents (w);
+		}
+	}
 }