1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.IO; 5 using System.Runtime.Serialization; 6 using System.ServiceModel; 7 using System.ServiceModel.Channels; 8 using System.Text; 9 using System.Xml; 10 using NUnit.Framework; 11 12 namespace MonoTests.System.ServiceModel.Channels 13 { 14 [TestFixture] 15 public class MessageHeadersTest 16 { 17 string wsa1 = "http://www.w3.org/2005/08/addressing"; 18 19 [Test] // it is somehow allowed ... AddDuplicate()20 public void AddDuplicate () 21 { 22 MessageHeaders headers = new MessageHeaders (MessageVersion.Default); 23 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:foo")); 24 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:bar")); 25 } 26 27 [Test] AddDuplicate2()28 public void AddDuplicate2 () 29 { 30 MessageHeaders headers = new MessageHeaders (MessageVersion.Default); 31 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:foo", true, "whoa")); 32 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:bar", true, "whee")); 33 } 34 35 [Test] TestConstructor()36 public void TestConstructor () 37 { 38 MessageHeaders headers = new MessageHeaders (MessageVersion.Soap12WSAddressing10); 39 Assert.AreEqual (0, headers.Count); 40 41 headers = new MessageHeaders (MessageVersion.Default); 42 Assert.AreEqual (0, headers.Count); 43 } 44 45 [Test] TestFindHeader()46 public void TestFindHeader () 47 { 48 // <a:Action mU="true">test</a:Action> 49 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 50 Assert.AreEqual (1, m.Headers.Count, "#0"); 51 52 // <MyHeader xmlns="bar">1</MyHeader> 53 m.Headers.Add (MessageHeader.CreateHeader ("MyHeader", "bar", 1)); 54 // <MyHeader xmlns="baz" role="john">1</MyHeader> 55 m.Headers.Add (MessageHeader.CreateHeader ("MyHeader", "baz", 1, false, "john")); 56 57 MessageHeaders headers = m.Headers; 58 // The first header is at 0 59 Assert.AreEqual (0, headers.FindHeader ("Action", wsa1), "#1"); 60 61 // The return value of FindHeader maps to its places in the headers 62 Assert.AreEqual (1, headers.FindHeader ("MyHeader", "bar"), "#2"); 63 64 // If a header has actor (role) specified, then it must be provided 65 Assert.AreEqual (-1, headers.FindHeader ("MyHeader", "baz"), "#3"); 66 Assert.AreEqual (2, headers.FindHeader ("MyHeader", "baz", "john"), "#4"); 67 } 68 69 [Test] TestFindHeaderWithMultipleIdenticalHeaders()70 public void TestFindHeaderWithMultipleIdenticalHeaders () 71 { 72 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 73 m.Headers.Add (MessageHeader.CreateHeader ( 74 "Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing", 1)); 75 76 MessageHeaders headers = m.Headers; 77 78 headers.FindHeader ("Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing"); 79 } 80 81 [Test] TestGetHeader()82 public void TestGetHeader () 83 { 84 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 85 MessageHeaders headers = m.Headers; 86 87 Assert.AreEqual ("test", headers.GetHeader<string> (0)); 88 } 89 90 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))] TestGetHeaderOutOfRange()91 public void TestGetHeaderOutOfRange () 92 { 93 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 94 MessageHeaders headers = m.Headers; 95 96 Assert.AreEqual ("test", headers.GetHeader<int> (1)); 97 } 98 99 [Test] 100 [ExpectedException (typeof (ArgumentNullException))] GetHeaderNullSerializer()101 public void GetHeaderNullSerializer () 102 { 103 MessageHeaders headers = new MessageHeaders (MessageVersion.Default); 104 string ns = "http://schemas.xmlsoap.org/ws/2004/08/addressing"; 105 headers.Add (MessageHeader.CreateHeader ("Action", ns, "urn:foo")); 106 headers.GetHeader<string> (0, null); 107 } 108 109 [Test] 110 [ExpectedException (typeof (ArgumentNullException))] GetHeaderNullSerializer2()111 public void GetHeaderNullSerializer2 () 112 { 113 MessageHeaders headers = new MessageHeaders (MessageVersion.Default); 114 string ns = "http://schemas.xmlsoap.org/ws/2004/08/addressing"; 115 headers.Add (MessageHeader.CreateHeader ("Action", ns, "urn:foo")); 116 headers.GetHeader<string> ("Action", ns, (XmlObjectSerializer) null); 117 } 118 119 [Test, ExpectedException (typeof (MessageHeaderException))] TestGetHeaderNonexistent()120 public void TestGetHeaderNonexistent () 121 { 122 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 123 MessageHeaders headers = m.Headers; 124 125 headers.GetHeader<string>("name", "namespace"); 126 } 127 128 [Test] SetWSAddressingHeadersNullToNonSoap()129 public void SetWSAddressingHeadersNullToNonSoap () 130 { 131 Message m = Message.CreateMessage (MessageVersion.None, "test", 1); 132 m.Headers.From = null; 133 m.Headers.MessageId = null; 134 m.Headers.ReplyTo = null; 135 m.Headers.FaultTo = null; 136 m.Headers.RelatesTo = null; 137 } 138 139 [Test] TestInsert()140 public void TestInsert () 141 { 142 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 143 144 m.Headers.Add (MessageHeader.CreateHeader ("FirstHeader", "ns", "first")); 145 Assert.AreEqual (1, m.Headers.FindHeader ("FirstHeader", "ns")); 146 147 m.Headers.Insert (1, MessageHeader.CreateHeader ("InsertedHeader", "ns", "insert")); 148 149 Assert.AreEqual (1, m.Headers.FindHeader ("InsertedHeader", "ns")); 150 Assert.AreEqual (2, m.Headers.FindHeader ("FirstHeader", "ns")); 151 } 152 153 [Test] TestWriteStartHeaderSimple()154 public void TestWriteStartHeaderSimple () 155 { 156 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 157 MessageHeader h = MessageHeader.CreateHeader ("FirstHeader", "ns", "first"); 158 m.Headers.Add (h); 159 160 StringBuilder sb = new StringBuilder (); 161 XmlWriterSettings s = new XmlWriterSettings (); 162 s.ConformanceLevel = ConformanceLevel.Fragment; 163 XmlWriter w = XmlWriter.Create (sb, s); 164 XmlDictionaryWriter dw = XmlDictionaryWriter.CreateDictionaryWriter (w); 165 m.Headers.WriteStartHeader (1, dw); 166 dw.Close (); 167 w.Close (); 168 string actual = sb.ToString (); 169 170 sb = new StringBuilder (); 171 w = XmlWriter.Create (sb, s); 172 dw = XmlDictionaryWriter.CreateDictionaryWriter (w); 173 h.WriteStartHeader (dw, MessageVersion.Soap12WSAddressing10); 174 dw.Close (); 175 w.Close (); 176 string expected = sb.ToString (); 177 178 179 Assert.AreEqual (expected, actual); 180 } 181 182 [Test] TestWriteStartHeaderWithActor()183 public void TestWriteStartHeaderWithActor () 184 { 185 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 186 MessageHeader h = MessageHeader.CreateHeader ("FirstHeader", "ns", "first", true, "actor"); 187 m.Headers.Add (h); 188 189 StringBuilder sb = new StringBuilder (); 190 XmlWriterSettings s = new XmlWriterSettings (); 191 s.ConformanceLevel = ConformanceLevel.Fragment; 192 XmlWriter w = XmlWriter.Create (sb, s); 193 XmlDictionaryWriter dw = XmlDictionaryWriter.CreateDictionaryWriter (w); 194 m.Headers.WriteStartHeader (1, dw); 195 dw.Close (); 196 w.Close (); 197 string actual = sb.ToString (); 198 199 sb = new StringBuilder (); 200 w = XmlWriter.Create (sb, s); 201 dw = XmlDictionaryWriter.CreateDictionaryWriter (w); 202 h.WriteStartHeader (dw, MessageVersion.Soap12WSAddressing10); 203 dw.Close (); 204 w.Close (); 205 string expected = sb.ToString (); 206 207 Assert.AreEqual (expected, actual); 208 } 209 210 [Test] TestWriteHeaderContents()211 public void TestWriteHeaderContents () 212 { 213 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 214 215 m.Headers.Add (MessageHeader.CreateHeader ("FirstHeader", "ns", "first")); 216 Assert.AreEqual (1, m.Headers.FindHeader ("FirstHeader", "ns")); 217 218 m.Headers.Add (MessageHeader.CreateHeader ("SecondHeader", "ns", 2)); 219 220 StringBuilder sb = new StringBuilder (); 221 // Even if XmlWriter is allowed to write fragment, 222 // DataContractSerializer never allows it to write 223 // content in contentOnly mode. 224 XmlWriterSettings settings = new XmlWriterSettings (); 225 settings.OmitXmlDeclaration = true; 226 //settings.ConformanceLevel = ConformanceLevel.Fragment; 227 XmlWriter w = XmlWriter.Create (sb, settings); 228 w.WriteStartElement ("root"); 229 w.WriteStartElement ("HEADER1"); 230 m.Headers.WriteHeaderContents (1, w); 231 w.WriteEndElement (); 232 w.WriteStartElement ("HEADER2"); 233 m.Headers.WriteHeaderContents (2, w); 234 w.WriteEndElement (); 235 w.WriteEndElement (); 236 w.Close (); 237 238 Assert.AreEqual ("<root><HEADER1>first</HEADER1><HEADER2>2</HEADER2></root>", sb.ToString ()); 239 } 240 241 [Test] 242 [Ignore ("I believe that with AddressingVersion.None it should not output any mustUnderstand addressing headers.")] WriteHeaderContentsAddressingNone()243 public void WriteHeaderContentsAddressingNone () 244 { 245 // This Action header is IMO extraneous. 246 string xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?><s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header><Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">Echo</Action></s:Header><s:Body><z:anyType i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:z=\"http://schemas.microsoft.com/2003/10/Serialization/\"/></s:Body></s:Envelope>"; 247 Message m = Message.CreateMessage (MessageVersion.Soap12, "Echo", (object) null); 248 StringWriter sw = new StringWriter (); 249 using (XmlWriter w = XmlWriter.Create (sw)) { 250 m.WriteMessage (w); 251 } 252 Assert.AreEqual (xml, sw.ToString ()); 253 } 254 255 [Test] TestAction()256 public void TestAction () 257 { 258 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 259 m.Headers.Add (MessageHeader.CreateHeader ("FirstHeader", "ns", "first")); 260 Assert.AreEqual ("test", m.Headers.Action, "#1"); 261 262 MessageHeaders headers = new MessageHeaders (MessageVersion.Default, 1); 263 Assert.AreEqual (null, headers.Action, "#2"); 264 headers.Add (MessageHeader.CreateHeader ("Action", "http://www.w3.org/2005/08/addressing", "test")); 265 266 MessageHeaderInfo info = headers [0]; 267 Assert.AreEqual ("Action", info.Name, "#2-1"); 268 Assert.AreEqual ("http://www.w3.org/2005/08/addressing", info.Namespace, "#2-2"); 269 Assert.AreEqual (false, info.MustUnderstand, "#2-3"); 270 Assert.AreEqual (String.Empty, info.Actor, "#2-4"); 271 272 Assert.AreEqual ("test", headers.Action, "#3"); 273 headers.Clear (); 274 Assert.AreEqual (null, headers.Action, "#4"); 275 } 276 277 [Test] MessageCreateAddsAction()278 public void MessageCreateAddsAction () 279 { 280 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 281 MessageHeaderInfo info = m.Headers [0]; 282 Assert.AreEqual ("Action", info.Name, "#1"); 283 Assert.AreEqual ("http://www.w3.org/2005/08/addressing", info.Namespace, "#2"); 284 Assert.AreEqual (true, info.MustUnderstand, "#3"); 285 Assert.AreEqual (String.Empty, info.Actor, "#4"); 286 } 287 288 [Test] GetReaderAtHeader()289 public void GetReaderAtHeader () 290 { 291 Message m = Message.CreateMessage (MessageVersion.Default, "test", 1); 292 XmlDictionaryReader r = m.Headers.GetReaderAtHeader (0); 293 294 XmlDictionaryReader r2 = m.Headers.GetReaderAtHeader (0); 295 using (XmlWriter x = XmlWriter.Create (TextWriter.Null)) { 296 r2.MoveToContent (); 297 while (!r2.EOF) 298 x.WriteNode (r2, false); 299 } 300 301 /* 302 // Seems like there is some attribute order differences 303 // in XmlDictionaryReader or XmlWriter, so don't compare 304 // XML in raw strings. 305 306 StringWriter sw = new StringWriter (); 307 XmlWriterSettings settings = new XmlWriterSettings (); 308 settings.OmitXmlDeclaration = true; 309 settings.ConformanceLevel = ConformanceLevel.Fragment; 310 XmlWriter w = XmlWriter.Create (sw, settings); 311 Assert.AreEqual (ReadState.Interactive, r.ReadState, "#1-1"); 312 Assert.AreEqual (XmlNodeType.Element, r.NodeType, "#1-2"); 313 while (!r.EOF) 314 w.WriteNode (r, false); 315 w.Flush (); 316 Assert.AreEqual ("<Action a:mustUnderstand=\"1\" xmlns=\"http://www.w3.org/2005/08/addressing\" xmlns:a=\"http://www.w3.org/2003/05/soap-envelope\">test</Action>", sw.ToString (), "#2"); 317 */ 318 Assert.AreEqual (ReadState.Interactive, r.ReadState, "#1-1"); 319 Assert.AreEqual (XmlNodeType.Element, r.NodeType, "#1-2"); 320 Assert.AreEqual ("Action", r.LocalName, "#1-3"); 321 Assert.AreEqual ("http://www.w3.org/2005/08/addressing", r.NamespaceURI, "#1-4"); 322 Assert.AreEqual ("1", r.GetAttribute ("mustUnderstand", "http://www.w3.org/2003/05/soap-envelope"), "#1-5"); 323 Assert.AreEqual ("test", r.ReadElementContentAsString (), "#1-6"); 324 } 325 326 [Test] 327 [ExpectedException (typeof (ArgumentOutOfRangeException))] GetReaderAtHeaderOutOfRange()328 public void GetReaderAtHeaderOutOfRange () 329 { 330 MessageHeaders h = new MessageHeaders (MessageVersion.Default, 1); 331 h.GetReaderAtHeader (0); 332 } 333 334 [Test] 335 [ExpectedException (typeof (MessageHeaderException))] // multiple headers: "Action" CopyHeadersFrom()336 public void CopyHeadersFrom () 337 { 338 Message msg = Message.CreateMessage (MessageVersion.Default, "urn:myaction"); 339 Message msg2 = Message.CreateMessage (MessageVersion.Default, "urn:myaction2"); 340 msg2.Headers.CopyHeadersFrom (msg); 341 Assert.AreEqual ("urn:myaction2", msg2.Headers.Action); 342 } 343 344 [Test] CopyHeadersFrom2()345 public void CopyHeadersFrom2 () 346 { 347 Message msg = Message.CreateMessage (MessageVersion.Default, "urn:myaction"); 348 Message msg2 = Message.CreateMessage (MessageVersion.Default, "urn:myaction2"); 349 msg2.Headers.Action = null; 350 msg2.Headers.CopyHeadersFrom (msg); 351 Assert.AreEqual ("urn:myaction", msg2.Headers.Action); 352 } 353 354 [Test] AddressingNoneAndAction()355 public void AddressingNoneAndAction () 356 { 357 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 358 h.Action = "urn:foo"; 359 } 360 361 [Test] 362 [ExpectedException (typeof (InvalidOperationException))] AddressingNoneAndFrom()363 public void AddressingNoneAndFrom () 364 { 365 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 366 h.From = new EndpointAddress ("http://localhost:8080"); 367 } 368 369 [Test] 370 [ExpectedException (typeof (InvalidOperationException))] AddressingNoneAndFaultTo()371 public void AddressingNoneAndFaultTo () 372 { 373 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 374 h.FaultTo = new EndpointAddress ("http://localhost:8080"); 375 } 376 377 [Test] 378 [ExpectedException (typeof (InvalidOperationException))] AddressingNoneAndMessageId()379 public void AddressingNoneAndMessageId () 380 { 381 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 382 h.MessageId = new UniqueId (Guid.NewGuid ()); 383 } 384 385 [Test] 386 [ExpectedException (typeof (InvalidOperationException))] AddressingNoneAndRelatesTo()387 public void AddressingNoneAndRelatesTo () 388 { 389 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 390 h.RelatesTo = new UniqueId (Guid.NewGuid ()); 391 } 392 393 [Test] 394 [ExpectedException (typeof (InvalidOperationException))] AddressingNoneAndReplyTo()395 public void AddressingNoneAndReplyTo () 396 { 397 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 398 h.ReplyTo = new EndpointAddress ("http://localhost:8080"); 399 } 400 401 [Test] AddressingNoneAndTo()402 public void AddressingNoneAndTo () 403 { 404 MessageHeaders h = new MessageHeaders (MessageVersion.Soap12); 405 h.To = new Uri ("http://localhost:8080"); 406 } 407 408 [Test] 409 [ExpectedException (typeof (MessageHeaderException))] DuplicateActionFindError()410 public void DuplicateActionFindError () 411 { 412 MessageHeaders headers = new MessageHeaders (MessageVersion.Default); 413 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:foo")); 414 headers.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:bar")); 415 Assert.Fail (String.Format ("Action should not be caught", headers.Action)); // access to Action results in an error. If it does not, then simply assert fail. 416 } 417 418 [Test] 419 [ExpectedException (typeof (MessageHeaderException))] CopyHeadersFrom_Merge()420 public void CopyHeadersFrom_Merge () 421 { 422 var h1 = new MessageHeaders (MessageVersion.Default); 423 var h2 = new MessageHeaders (MessageVersion.Default); 424 h1.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:foo")); 425 h2.Add (MessageHeader.CreateHeader ("Action", wsa1, "urn:bar")); 426 h1.CopyHeadersFrom (h2); // it somehow allow dups! 427 Assert.Fail (String.Format ("Action should not be caught", h1.Action)); // access to Action results in an error. If it does not, then simply assert fail. 428 } 429 430 } 431 } 432