Example #1
0
        /// <summary>
        /// Reads name=value pairs into a message.
        /// </summary>
        /// <param name="fields">The name=value pairs that were read in from the transport.</param>
        /// <param name="messageDictionary">The message to deserialize into.</param>
        /// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception>
        internal void Deserialize(IDictionary <string, string> fields, MessageDictionary messageDictionary)
        {
            Contract.Requires <ArgumentNullException>(fields != null);
            Contract.Requires <ArgumentNullException>(messageDictionary != null);

            var messageDescription = messageDictionary.Description;

            // Before we deserialize the message, make sure all the required parts are present.
            messageDescription.EnsureMessagePartsPassBasicValidation(fields);

            try {
                foreach (var pair in fields)
                {
                    messageDictionary[pair.Key] = pair.Value;
                }
            } catch (ArgumentException ex) {
                throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorDeserializingMessage, this.messageType.Name);
            }
            messageDictionary.Message.EnsureValidMessage();
        }
Example #2
0
        /// <summary>
        /// Processes an <see cref="HttpWebRequest"/> and converts the
        /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance.
        /// </summary>
        /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param>
        /// <param name="options">The options to apply to this web request.</param>
        /// <returns>
        /// An instance of <see cref="IncomingWebResponse"/> describing the response.
        /// </returns>
        /// <exception cref="ProtocolException">Thrown for any network error.</exception>
        /// <remarks>
        ///     <para>Implementations should catch <see cref="WebException"/> and wrap it in a
        /// <see cref="ProtocolException"/> to abstract away the transport and provide
        /// a single exception type for hosts to catch.  The <see cref="WebException.Response"/>
        /// value, if set, should be Closed before throwing.</para>
        /// </remarks>
        public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options)
        {
            // This request MAY have already been prepared by GetRequestStream, but
            // we have no guarantee, so do it just to be safe.
            PrepareRequest(request, false);

            try {
                Logger.Http.DebugFormat("HTTP {0} {1}", request.Method, request.RequestUri);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                return(new NetworkDirectWebResponse(request.RequestUri, response));
            } catch (WebException ex) {
                HttpWebResponse response = (HttpWebResponse)ex.Response;
                if (response != null && response.StatusCode == HttpStatusCode.ExpectationFailed &&
                    request.ServicePoint.Expect100Continue)
                {
                    // Some OpenID servers doesn't understand the Expect header and send 417 error back.
                    // If this server just failed from that, alter the ServicePoint for this server
                    // so that we don't send that header again next time (whenever that is).
                    // "Expect: 100-Continue" HTTP header. (see Google Code Issue 72)
                    // We don't want to blindly set all ServicePoints to not use the Expect header
                    // as that would be a security hole allowing any visitor to a web site change
                    // the web site's global behavior when calling that host.
                    Logger.Http.InfoFormat("HTTP POST to {0} resulted in 417 Expectation Failed.  Changing ServicePoint to not use Expect: Continue next time.", request.RequestUri);
                    request.ServicePoint.Expect100Continue = false;                     // TODO: investigate that CAS may throw here

                    // An alternative to ServicePoint if we don't have permission to set that,
                    // but we'd have to set it BEFORE each request.
                    ////request.Expect = "";
                }

                if ((options & DirectWebRequestOptions.AcceptAllHttpResponses) != 0 && response != null &&
                    response.StatusCode != HttpStatusCode.ExpectationFailed)
                {
                    Logger.Http.InfoFormat("The HTTP error code {0} {1} is being accepted because the {2} flag is set.", (int)response.StatusCode, response.StatusCode, DirectWebRequestOptions.AcceptAllHttpResponses);
                    return(new NetworkDirectWebResponse(request.RequestUri, response));
                }

                if (Logger.Http.IsErrorEnabled)
                {
                    if (response != null)
                    {
                        using (var reader = new StreamReader(ex.Response.GetResponseStream())) {
                            Logger.Http.ErrorFormat("WebException from {0}: {1}{2}", ex.Response.ResponseUri, Environment.NewLine, reader.ReadToEnd());
                        }
                    }
                    else
                    {
                        Logger.Http.ErrorFormat("WebException {1} from {0}, no response available.", request.RequestUri, ex.Status);
                    }
                }

                // Be sure to close the response stream to conserve resources and avoid
                // filling up all our incoming pipes and denying future requests.
                // If in the future, some callers actually want to read this response
                // we'll need to figure out how to reliably call Close on exception
                // responses at all callers.
                if (response != null)
                {
                    response.Close();
                }

                throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorInRequestReplyMessage);
            }
        }