/// <summary> /// Encodes an HTTP response that will instruct the user agent to forward a message to /// some remote third party using a form POST method. /// </summary> /// <param name="message">The message to forward.</param> /// <param name="fields">The pre-serialized fields from the message.</param> /// <returns>The encoded HTTP response.</returns> protected virtual UserAgentResponse CreateFormPostResponse(IDirectedProtocolMessage message, IDictionary <string, string> fields) { ErrorUtilities.VerifyArgumentNotNull(message, "message"); ErrorUtilities.VerifyArgumentNamed(message.Recipient != null, "message", MessagingStrings.DirectedMessageMissingRecipient); ErrorUtilities.VerifyArgumentNotNull(fields, "fields"); WebHeaderCollection headers = new WebHeaderCollection(); StringWriter bodyWriter = new StringWriter(CultureInfo.InvariantCulture); StringBuilder hiddenFields = new StringBuilder(); foreach (var field in fields) { hiddenFields.AppendFormat( "\t<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />\r\n", HttpUtility.HtmlEncode(field.Key), HttpUtility.HtmlEncode(field.Value)); } bodyWriter.WriteLine( indirectMessageFormPostFormat, HttpUtility.HtmlEncode(message.Recipient.AbsoluteUri), hiddenFields); bodyWriter.Flush(); UserAgentResponse response = new UserAgentResponse { Status = HttpStatusCode.OK, Headers = headers, Body = bodyWriter.ToString(), OriginalMessage = message }; return(response); }
/// <summary> /// Encodes an HTTP response that will instruct the user agent to forward a message to /// some remote third party using a 301 Redirect GET method. /// </summary> /// <param name="message">The message to forward.</param> /// <param name="fields">The pre-serialized fields from the message.</param> /// <returns>The encoded HTTP response.</returns> protected virtual UserAgentResponse Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary <string, string> fields) { ErrorUtilities.VerifyArgumentNotNull(message, "message"); ErrorUtilities.VerifyArgumentNamed(message.Recipient != null, "message", MessagingStrings.DirectedMessageMissingRecipient); ErrorUtilities.VerifyArgumentNotNull(fields, "fields"); WebHeaderCollection headers = new WebHeaderCollection(); UriBuilder builder = new UriBuilder(message.Recipient); MessagingUtilities.AppendQueryArgs(builder, fields); headers.Add(HttpResponseHeader.Location, builder.Uri.AbsoluteUri); Logger.DebugFormat("Redirecting to {0}", builder.Uri.AbsoluteUri); UserAgentResponse response = new UserAgentResponse { Status = HttpStatusCode.Redirect, Headers = headers, Body = null, OriginalMessage = message }; return(response); }
/// <summary> /// Ensures a consistent and secure set of binding elements and /// sorts them as necessary for a valid sequence of operations. /// </summary> /// <param name="elements">The binding elements provided to the channel.</param> /// <returns>The properly ordered list of elements.</returns> /// <exception cref="ProtocolException">Thrown when the binding elements are incomplete or inconsistent with each other.</exception> private static IEnumerable <IChannelBindingElement> ValidateAndPrepareBindingElements(IEnumerable <IChannelBindingElement> elements) { if (elements == null) { return(new IChannelBindingElement[0]); } ErrorUtilities.VerifyArgumentNamed(!elements.Contains(null), "elements", MessagingStrings.SequenceContainsNullElement); // Filter the elements between the mere transforming ones and the protection ones. var transformationElements = new List <IChannelBindingElement>( elements.Where(element => element.Protection == MessageProtections.None)); var protectionElements = new List <IChannelBindingElement>( elements.Where(element => element.Protection != MessageProtections.None)); bool wasLastProtectionPresent = true; foreach (MessageProtections protectionKind in Enum.GetValues(typeof(MessageProtections))) { if (protectionKind == MessageProtections.None) { continue; } int countProtectionsOfThisKind = protectionElements.Count(element => (element.Protection & protectionKind) == protectionKind); // Each protection binding element is backed by the presence of its dependent protection(s). ErrorUtilities.VerifyProtocol(!(countProtectionsOfThisKind > 0 && !wasLastProtectionPresent), MessagingStrings.RequiredProtectionMissing, protectionKind); wasLastProtectionPresent = countProtectionsOfThisKind > 0; } // Put the binding elements in order so they are correctly applied to outgoing messages. // Start with the transforming (non-protecting) binding elements first and preserve their original order. var orderedList = new List <IChannelBindingElement>(transformationElements); // Now sort the protection binding elements among themselves and add them to the list. orderedList.AddRange(protectionElements.OrderBy(element => element.Protection, BindingElementOutgoingMessageApplicationOrder)); return(orderedList); }