CreateSequence.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Runtime;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Security;
  9. using System.Xml;
  10. sealed class CreateSequence : BodyWriter
  11. {
  12. AddressingVersion addressingVersion;
  13. IClientReliableChannelBinder binder;
  14. UniqueId offerIdentifier;
  15. bool ordered;
  16. ReliableMessagingVersion reliableMessagingVersion;
  17. CreateSequence()
  18. : base(true)
  19. {
  20. }
  21. public CreateSequence(AddressingVersion addressingVersion, ReliableMessagingVersion reliableMessagingVersion,
  22. bool ordered, IClientReliableChannelBinder binder, UniqueId offerIdentifier)
  23. : base(true)
  24. {
  25. this.addressingVersion = addressingVersion;
  26. this.reliableMessagingVersion = reliableMessagingVersion;
  27. this.ordered = ordered;
  28. this.binder = binder;
  29. this.offerIdentifier = offerIdentifier;
  30. }
  31. public static CreateSequenceInfo Create(MessageVersion messageVersion,
  32. ReliableMessagingVersion reliableMessagingVersion, ISecureConversationSession securitySession,
  33. XmlDictionaryReader reader)
  34. {
  35. if (reader == null)
  36. {
  37. Fx.Assert("Argument reader cannot be null.");
  38. }
  39. try
  40. {
  41. CreateSequenceInfo info = new CreateSequenceInfo();
  42. WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
  43. XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(reliableMessagingVersion);
  44. reader.ReadStartElement(wsrmFeb2005Dictionary.CreateSequence, wsrmNs);
  45. info.AcksTo = EndpointAddress.ReadFrom(messageVersion.Addressing, reader, wsrmFeb2005Dictionary.AcksTo, wsrmNs);
  46. if (reader.IsStartElement(wsrmFeb2005Dictionary.Expires, wsrmNs))
  47. {
  48. info.Expires = reader.ReadElementContentAsTimeSpan();
  49. }
  50. if (reader.IsStartElement(wsrmFeb2005Dictionary.Offer, wsrmNs))
  51. {
  52. reader.ReadStartElement();
  53. reader.ReadStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
  54. info.OfferIdentifier = reader.ReadContentAsUniqueId();
  55. reader.ReadEndElement();
  56. bool wsrm11 = reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11;
  57. Wsrm11Dictionary wsrm11Dictionary = wsrm11 ? DXD.Wsrm11Dictionary : null;
  58. if (wsrm11)
  59. {
  60. EndpointAddress endpoint = EndpointAddress.ReadFrom(messageVersion.Addressing, reader,
  61. wsrm11Dictionary.Endpoint, wsrmNs);
  62. if (endpoint.Uri != info.AcksTo.Uri)
  63. {
  64. string reason = SR.GetString(SR.CSRefusedAcksToMustEqualEndpoint);
  65. Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
  66. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason)));
  67. }
  68. }
  69. if (reader.IsStartElement(wsrmFeb2005Dictionary.Expires, wsrmNs))
  70. {
  71. info.OfferExpires = reader.ReadElementContentAsTimeSpan();
  72. }
  73. if (wsrm11)
  74. {
  75. if (reader.IsStartElement(wsrm11Dictionary.IncompleteSequenceBehavior, wsrmNs))
  76. {
  77. string incompleteSequenceBehavior = reader.ReadElementContentAsString();
  78. if ((incompleteSequenceBehavior != Wsrm11Strings.DiscardEntireSequence)
  79. && (incompleteSequenceBehavior != Wsrm11Strings.DiscardFollowingFirstGap)
  80. && (incompleteSequenceBehavior != Wsrm11Strings.NoDiscard))
  81. {
  82. string reason = SR.GetString(SR.CSRefusedInvalidIncompleteSequenceBehavior);
  83. Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
  84. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
  85. WsrmMessageInfo.CreateInternalFaultException(faultReply, reason,
  86. new ProtocolException(reason)));
  87. }
  88. // Otherwise ignore the value.
  89. }
  90. }
  91. while (reader.IsStartElement())
  92. {
  93. reader.Skip();
  94. }
  95. reader.ReadEndElement();
  96. }
  97. // Check for security only if we expect a soap security session.
  98. if (securitySession != null)
  99. {
  100. bool hasValidToken = false;
  101. // Since the security element is amongst the extensible elements (i.e. there is no
  102. // gaurantee of ordering or placement), a loop is required to attempt to parse the
  103. // security element.
  104. while (reader.IsStartElement())
  105. {
  106. if (securitySession.TryReadSessionTokenIdentifier(reader))
  107. {
  108. hasValidToken = true;
  109. break;
  110. }
  111. reader.Skip();
  112. }
  113. if (!hasValidToken)
  114. {
  115. string reason = SR.GetString(SR.CSRefusedRequiredSecurityElementMissing);
  116. Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
  117. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason)));
  118. }
  119. }
  120. while (reader.IsStartElement())
  121. {
  122. reader.Skip();
  123. }
  124. reader.ReadEndElement();
  125. if (reader.IsStartElement())
  126. {
  127. string reason = SR.GetString(SR.CSRefusedUnexpectedElementAtEndOfCSMessage);
  128. Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
  129. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason)));
  130. }
  131. return info;
  132. }
  133. catch (XmlException e)
  134. {
  135. string reason = SR.GetString(SR.CouldNotParseWithAction, WsrmIndex.GetCreateSequenceActionString(reliableMessagingVersion));
  136. Message faultReply = WsrmUtilities.CreateCSRefusedProtocolFault(messageVersion, reliableMessagingVersion, reason);
  137. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(WsrmMessageInfo.CreateInternalFaultException(faultReply, reason, new ProtocolException(reason, e)));
  138. }
  139. }
  140. protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
  141. {
  142. WsrmFeb2005Dictionary wsrmFeb2005Dictionary = XD.WsrmFeb2005Dictionary;
  143. XmlDictionaryString wsrmNs = WsrmIndex.GetNamespace(this.reliableMessagingVersion);
  144. writer.WriteStartElement(wsrmFeb2005Dictionary.CreateSequence, wsrmNs);
  145. EndpointAddress localAddress = this.binder.LocalAddress;
  146. localAddress.WriteTo(this.addressingVersion, writer, wsrmFeb2005Dictionary.AcksTo, wsrmNs);
  147. if (this.offerIdentifier != null)
  148. {
  149. writer.WriteStartElement(wsrmFeb2005Dictionary.Offer, wsrmNs);
  150. writer.WriteStartElement(wsrmFeb2005Dictionary.Identifier, wsrmNs);
  151. writer.WriteValue(this.offerIdentifier);
  152. writer.WriteEndElement();
  153. if (this.reliableMessagingVersion == ReliableMessagingVersion.WSReliableMessaging11)
  154. {
  155. Wsrm11Dictionary wsrm11Dictionary = DXD.Wsrm11Dictionary;
  156. localAddress.WriteTo(this.addressingVersion, writer, wsrm11Dictionary.Endpoint, wsrmNs);
  157. writer.WriteStartElement(wsrm11Dictionary.IncompleteSequenceBehavior, wsrmNs);
  158. writer.WriteValue(
  159. this.ordered ? wsrm11Dictionary.DiscardFollowingFirstGap : wsrm11Dictionary.NoDiscard);
  160. writer.WriteEndElement();
  161. }
  162. writer.WriteEndElement();
  163. }
  164. ISecureConversationSession securitySession = this.binder.GetInnerSession() as ISecureConversationSession;
  165. if (securitySession != null)
  166. securitySession.WriteSessionTokenIdentifier(writer);
  167. writer.WriteEndElement();
  168. }
  169. }
  170. }