Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        /// <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);
        }