예제 #1
0
    /// <summary>
    /// Grabs the issued token information out of a response from Windows Live.
    /// </summary>
    /// <param name="response">The token response</param>
    /* private */ void ProcessTokenResponse(HttpWebResponse response)
    {
        // NOTE: We're not tracing responses here because they contain the actual token information
        // from Windows Live.

        {
            // Always start fresh (nulls in all the data we're going to fill in).
            this.SecurityToken = null;

            EwsXmlReader rstResponse = new EwsXmlReader(responseStream);

            rstResponse.Read(XmlNodeType.XmlDeclaration);
            rstResponse.ReadStartElement(
                WindowsLiveSoapNamespacePrefix,
                XmlElementNames.SOAPEnvelopeElementName);

            // Process the SOAP headers from the response.
            this.ReadWindowsLiveRSTResponseHeaders(rstResponse);

            rstResponse.ReadStartElement(
                WindowsLiveSoapNamespacePrefix,
                XmlElementNames.SOAPBodyElementName);

            // Process the SOAP body from the response.
            this.ParseWindowsLiveRSTResponseBody(rstResponse);
        }
    }
        /// <summary>
        /// Read SOAP body.
        /// </summary>
        /// <param name="reader">EwsXmlReader</param>
        internal AutodiscoverResponse ReadSoapBody(EwsXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
            AutodiscoverResponse responses = this.LoadFromXml(reader);

            reader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
            return(responses);
        }
        /// <summary>
        /// Loads responses from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        internal AutodiscoverResponse LoadFromXml(EwsXmlReader reader)
        {
            string elementName = this.GetResponseXmlElementName();

            reader.ReadStartElement(XmlNamespace.Autodiscover, elementName);
            AutodiscoverResponse response = this.CreateServiceResponse();

            response.LoadFromXml(reader, elementName);
            return(response);
        }
        /// <summary>
        /// Read SOAP headers.
        /// </summary>
        /// <param name="reader">EwsXmlReader</param>
        internal void ReadSoapHeaders(EwsXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPHeaderElementName);
            do
            {
                reader.Read();

                this.ReadSoapHeader(reader);
            }while (!reader.IsEndElement(XmlNamespace.Soap, XmlElementNames.SOAPHeaderElementName));
        }
예제 #5
0
        /// <summary>
        /// Loads the settings from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.Autodiscover);
            reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.Response);

            do
            {
                reader.Read();

                if (reader.IsStartElement())
                {
                    if (!this.TryReadCurrentXmlElement(reader))
                    {
                        reader.SkipCurrentElement();
                    }
                }
            }while (!reader.IsEndElement(XmlNamespace.NotSpecified, XmlElementNames.Response));

            reader.ReadEndElement(XmlNamespace.NotSpecified, XmlElementNames.Autodiscover);
        }
        /// <summary>
        /// Loads the settings from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.Autodiscover);
            reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.Response);

            do
            {
                reader.Read();

                if (reader.IsStartElement())
                {
                    if (!this.TryReadCurrentXmlElement(reader))
                    {
                        reader.SkipCurrentElement();
                    }
                }
            }
            while (!reader.IsEndElement(XmlNamespace.NotSpecified, XmlElementNames.Response));

            reader.ReadEndElement(XmlNamespace.NotSpecified, XmlElementNames.Autodiscover);
        }
        /// <summary>
        /// Grabs the issued token information out of a response from Windows Live.
        /// </summary>
        /// <param name="response">The token response</param>
        private void ProcessTokenResponse(HttpWebResponse response)
        {
            // NOTE: We're not tracing responses here because they contain the actual token information
            // from Windows Live.    
            using (Stream responseStream = response.GetResponseStream())
            {
                // Always start fresh (nulls in all the data we're going to fill in).
                this.SecurityToken = null;

                EwsXmlReader rstResponse = new EwsXmlReader(responseStream);

                rstResponse.Read(XmlNodeType.XmlDeclaration);
                rstResponse.ReadStartElement(
                    WindowsLiveSoapNamespacePrefix,
                    XmlElementNames.SOAPEnvelopeElementName);

                // Process the SOAP headers from the response.
                this.ReadWindowsLiveRSTResponseHeaders(rstResponse);

                rstResponse.ReadStartElement(
                    WindowsLiveSoapNamespacePrefix,
                    XmlElementNames.SOAPBodyElementName);

                // Process the SOAP body from the response.
                this.ParseWindowsLiveRSTResponseBody(rstResponse);
            }
        }
        /// <summary>
        /// Function that parses the RSTR from Windows Live and pulls out all the important pieces
        /// of data from it.
        /// </summary>
        /// <param name="rstResponse">The RSTR, positioned at the beginning of the SOAP body.</param>
        private void ParseWindowsLiveRSTResponseBody(EwsXmlReader rstResponse)
        {
            // Read the WS-Trust RequestSecurityTokenResponseCollection node.
            rstResponse.ReadStartElement(
                XmlNamespace.WSTrustFebruary2005,
                RequestSecurityTokenResponseCollectionElementName);

            // Skip the first token - our interest is in the second token (the service token).
            rstResponse.SkipElement(
                XmlNamespace.WSTrustFebruary2005,
                RequestSecurityTokenResponseElementName);

            // Now process the second token.
            rstResponse.ReadStartElement(
                XmlNamespace.WSTrustFebruary2005,
                RequestSecurityTokenResponseElementName);

            while (!rstResponse.IsEndElement(
                       XmlNamespace.WSTrustFebruary2005,
                       RequestSecurityTokenResponseElementName))
            {
                // Watch for the EncryptedData element - when we find it, parse out the appropriate bits of data.
                //
                // Also watch for the "pp" element in the Passport SOAP fault namespace, which indicates that
                // something went wrong with the token request.  If we find it, trace and throw accordingly.
                if (rstResponse.IsStartElement() &&
                    (rstResponse.LocalName == EncryptedDataElementName) &&
                    (rstResponse.NamespaceUri == XmlEncNamespace))
                {
                    this.SecurityToken = rstResponse.ReadOuterXml();
                }
                else if (rstResponse.IsStartElement(XmlNamespace.PassportSoapFault, PpElementName))
                {
                    if (this.TraceEnabled)
                    {
                        string logMessage = string.Format(
                            "Windows Live reported an error retrieving the token - {0}",
                            rstResponse.ReadOuterXml());
                        this.traceListener.Trace("WindowsLiveResponse", logMessage);
                    }
                    throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, EncryptedDataElementName));
                }

                // Move to the next bit of data...
                rstResponse.Read();
            }

            // If we didn't find the token, throw.
            if (this.SecurityToken == null)
            {
                if (this.TraceEnabled)
                {
                    string logMessage = string.Format(
                        "Did not find all required parts of the Windows Live response - " +
                        "Security Token - {0}",
                        (this.SecurityToken == null) ? "NOT FOUND" : "found");
                    this.traceListener.Trace("WindowsLiveResponse", logMessage);
                }
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, "No security token found."));
            }
            
            // Read past the RequestSecurityTokenResponseCollection end element.
            rstResponse.Read();
        }
        /// <summary>
        /// Function that parses the SOAP headers from the response to the RST to Windows Live.
        /// </summary>
        /// <param name="rstResponse">The Windows Live response, positioned at the beginning of the SOAP headers.</param>
        private void ReadWindowsLiveRSTResponseHeaders(EwsXmlReader rstResponse)
        {
            // Read the beginning of the SOAP header, then go looking for the Passport SOAP fault section...
            rstResponse.ReadStartElement(
                WindowsLiveSoapNamespacePrefix,
                XmlElementNames.SOAPHeaderElementName);

            // Attempt to read to the psf:pp element - if at the end of the ReadToDescendant call we're at the
            // end element for the SOAP headers, we didn't find it.
            rstResponse.ReadToDescendant(XmlNamespace.PassportSoapFault, PpElementName);
            if (rstResponse.IsEndElement(WindowsLiveSoapNamespacePrefix, XmlElementNames.SOAPHeaderElementName))
            {
                // We didn't find the psf:pp element - without that, we don't know what happened -
                // something went wrong.  Trace and throw.
                if (this.TraceEnabled)
                {
                    this.traceListener.Trace(
                        "WindowsLiveResponse",
                        "Could not find Passport SOAP fault information in Windows Live response");
                }
                
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, PpElementName));
            }
            
            // Now that we've found the psf:pp element, look for the 'reqstatus' element under it.  If after
            // the ReadToDescendant call we're at the end element for the psf:pp element, we didn't find it.
            rstResponse.ReadToDescendant(XmlNamespace.PassportSoapFault, ReqstatusElementName);
            if (rstResponse.IsEndElement(XmlNamespace.PassportSoapFault, PpElementName))
            {
                // We didn't find the "reqstatus" element - without that, we don't know what happened -
                // something went wrong.  Trace and throw.
                if (this.TraceEnabled)
                {
                    this.traceListener.Trace(
                        "WindowsLiveResponse",
                        "Could not find reqstatus element in Passport SOAP fault information in Windows Live response");
                }
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ReqstatusElementName));
            }
            
            // Now that we've found the reqstatus element, get its value.
            string reqstatus = rstResponse.ReadElementValue();

            // Read to body tag in both success and failure cases, 
            // since we need to trace the fault response in failure cases
            while (!rstResponse.IsEndElement(WindowsLiveSoapNamespacePrefix, XmlElementNames.SOAPHeaderElementName))
            {
                rstResponse.Read();
            }
            
            if (!string.Equals(reqstatus, SuccessfulReqstatus))
            {
                // Our request status was non-zero - something went wrong.  Trace and throw.
                if (this.TraceEnabled)
                {
                    string logMessage = string.Format(
                        "Received status {0} from Windows Live instead of {1}.",
                        reqstatus,
                        SuccessfulReqstatus);
                    this.traceListener.Trace("WindowsLiveResponse", logMessage);

                    rstResponse.ReadStartElement(
                        WindowsLiveSoapNamespacePrefix,
                        XmlElementNames.SOAPBodyElementName);

                    // Trace Fault Information
                    this.traceListener.Trace(
                           "WindowsLiveResponse",
                           string.Format(
                           "Windows Live reported Fault : {0}",
                           rstResponse.ReadInnerXml()));
                }               
                
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ReqstatusElementName + ": " + reqstatus));
            }
        }
예제 #10
0
    /// <summary>
    /// Function that parses the RSTR from Windows Live and pulls out all the important pieces
    /// of data from it.
    /// </summary>
    /// <param name="rstResponse">The RSTR, positioned at the beginning of the SOAP body.</param>
    /* private */ void ParseWindowsLiveRSTResponseBody(EwsXmlReader rstResponse)
    {
        // Read the WS-Trust RequestSecurityTokenResponseCollection node.
        rstResponse.ReadStartElement(
            XmlNamespace.WSTrustFebruary2005,
            RequestSecurityTokenResponseCollectionElementName);

        // Skip the first token - our interest is in the second token (the service token).
        rstResponse.SkipElement(
            XmlNamespace.WSTrustFebruary2005,
            RequestSecurityTokenResponseElementName);

        // Now process the second token.
        rstResponse.ReadStartElement(
            XmlNamespace.WSTrustFebruary2005,
            RequestSecurityTokenResponseElementName);

        while (!rstResponse.IsEndElement(
                   XmlNamespace.WSTrustFebruary2005,
                   RequestSecurityTokenResponseElementName))
        {
            // Watch for the EncryptedData element - when we find it, parse out the appropriate bits of data.
            //
            // Also watch for the "pp" element in the Passport SOAP fault namespace, which indicates that
            // something went wrong with the token request.  If we find it, trace and throw accordingly.
            if (rstResponse.IsStartElement() &&
                (rstResponse.LocalName == EncryptedDataElementName) &&
                (rstResponse.NamespaceUri == XmlEncNamespace))
            {
                this.SecurityToken = rstResponse.ReadOuterXml();
            }
            else if (rstResponse.IsStartElement(XmlNamespace.PassportSoapFault, PpElementName))
            {
                if (this.TraceEnabled)
                {
                    String logMessage = string.Format(
                        "Windows Live reported an error retrieving the token - {0}",
                        rstResponse.ReadOuterXml());
                    this.traceListener.Trace("WindowsLiveResponse", logMessage);
                }
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, EncryptedDataElementName));
            }

            // Move to the next bit of data...
            rstResponse.Read();
        }

        // If we didn't find the token, throw.
        if (this.SecurityToken == null)
        {
            if (this.TraceEnabled)
            {
                String logMessage = string.Format(
                    "Did not find all required parts of the Windows Live response - " +
                    "Security Token - {0}",
                    (this.SecurityToken == null) ? "NOT FOUND" : "found");
                this.traceListener.Trace("WindowsLiveResponse", logMessage);
            }
            throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, "No security token found."));
        }

        // Read past the RequestSecurityTokenResponseCollection end element.
        rstResponse.Read();
    }
예제 #11
0
    /// <summary>
    /// Function that parses the SOAP headers from the response to the RST to Windows Live.
    /// </summary>
    /// <param name="rstResponse">The Windows Live response, positioned at the beginning of the SOAP headers.</param>
    /* private */ void ReadWindowsLiveRSTResponseHeaders(EwsXmlReader rstResponse)
    {
        // Read the beginning of the SOAP header, then go looking for the Passport SOAP fault section...
        rstResponse.ReadStartElement(
            WindowsLiveSoapNamespacePrefix,
            XmlElementNames.SOAPHeaderElementName);

        // Attempt to read to the psf:pp element - if at the end of the ReadToDescendant call we're at the
        // end element for the SOAP headers, we didn't find it.
        rstResponse.ReadToDescendant(XmlNamespace.PassportSoapFault, PpElementName);
        if (rstResponse.IsEndElement(WindowsLiveSoapNamespacePrefix, XmlElementNames.SOAPHeaderElementName))
        {
            // We didn't find the psf:pp element - without that, we don't know what happened -
            // something went wrong.  Trace and throw.
            if (this.TraceEnabled)
            {
                this.traceListener.Trace(
                    "WindowsLiveResponse",
                    "Could not find Passport SOAP fault information in Windows Live response");
            }

            throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, PpElementName));
        }

        // Now that we've found the psf:pp element, look for the 'reqstatus' element under it.  If after
        // the ReadToDescendant call we're at the end element for the psf:pp element, we didn't find it.
        rstResponse.ReadToDescendant(XmlNamespace.PassportSoapFault, ReqstatusElementName);
        if (rstResponse.IsEndElement(XmlNamespace.PassportSoapFault, PpElementName))
        {
            // We didn't find the "reqstatus" element - without that, we don't know what happened -
            // something went wrong.  Trace and throw.
            if (this.TraceEnabled)
            {
                this.traceListener.Trace(
                    "WindowsLiveResponse",
                    "Could not find reqstatus element in Passport SOAP fault information in Windows Live response");
            }
            throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ReqstatusElementName));
        }

        // Now that we've found the reqstatus element, get its value.
        String reqstatus = rstResponse.ReadElementValue();

        // Read to body tag in both success and failure cases,
        // since we need to trace the fault response in failure cases
        while (!rstResponse.IsEndElement(WindowsLiveSoapNamespacePrefix, XmlElementNames.SOAPHeaderElementName))
        {
            rstResponse.Read();
        }

        if (!string.Equals(reqstatus, SuccessfulReqstatus))
        {
            // Our request status was non-zero - something went wrong.  Trace and throw.
            if (this.TraceEnabled)
            {
                String logMessage = string.Format(
                    "Received status {0} from Windows Live instead of {1}.",
                    reqstatus,
                    SuccessfulReqstatus);
                this.traceListener.Trace("WindowsLiveResponse", logMessage);

                rstResponse.ReadStartElement(
                    WindowsLiveSoapNamespacePrefix,
                    XmlElementNames.SOAPBodyElementName);

                // Trace Fault Information
                this.traceListener.Trace(
                    "WindowsLiveResponse",
                    string.Format(
                        "Windows Live reported Fault : {0}",
                        rstResponse.ReadInnerXml()));
            }

            throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ReqstatusElementName + ": " + reqstatus));
        }
    }
        /// <summary>
        /// Executes this instance.
        /// </summary>
        /// <returns></returns>
        internal AutodiscoverResponse InternalExecute()
        {
            this.Validate();

            try
            {
                IEwsHttpWebRequest request = this.Service.PrepareHttpWebRequestForUrl(this.Url);

                this.Service.TraceHttpRequestHeaders(TraceFlags.AutodiscoverRequestHttpHeaders, request);

                bool needSignature = this.Service.Credentials != null && this.Service.Credentials.NeedSignature;
                bool needTrace     = this.Service.IsTraceEnabledFor(TraceFlags.AutodiscoverRequest);

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.Service, memoryStream))
                    {
                        writer.RequireWSSecurityUtilityNamespace = needSignature;
                        this.WriteSoapRequest(
                            this.Url,
                            writer);
                    }

                    if (needSignature)
                    {
                        this.service.Credentials.Sign(memoryStream);
                    }

                    if (needTrace)
                    {
                        memoryStream.Position = 0;
                        this.Service.TraceXml(TraceFlags.AutodiscoverRequest, memoryStream);
                    }

                    request.SetRequestStream(memoryStream);
                }


                using (IEwsHttpWebResponse webResponse = request.GetResponse())
                {
                    if (AutodiscoverRequest.IsRedirectionResponse(webResponse))
                    {
                        AutodiscoverResponse response = this.CreateRedirectionResponse(webResponse);
                        if (response != null)
                        {
                            return(response);
                        }
                        else
                        {
                            throw new ServiceRemoteException(Strings.InvalidRedirectionResponseReturned);
                        }
                    }

                    using (Stream responseStream = AutodiscoverRequest.GetResponseStream(webResponse))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            // Copy response stream to in-memory stream and reset to start
                            EwsUtilities.CopyStream(responseStream, memoryStream);
                            memoryStream.Position = 0;

                            this.Service.TraceResponse(webResponse, memoryStream);

                            EwsXmlReader ewsXmlReader = new EwsXmlReader(memoryStream);

                            // WCF may not generate an XML declaration.
                            ewsXmlReader.Read();
                            if (ewsXmlReader.NodeType == XmlNodeType.XmlDeclaration)
                            {
                                ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
                            }
                            else if ((ewsXmlReader.NodeType != XmlNodeType.Element) || (ewsXmlReader.LocalName != XmlElementNames.SOAPEnvelopeElementName) || (ewsXmlReader.NamespaceUri != EwsUtilities.GetNamespaceUri(XmlNamespace.Soap)))
                            {
                                throw new ServiceXmlDeserializationException(Strings.InvalidAutodiscoverServiceResponse);
                            }

                            this.ReadSoapHeaders(ewsXmlReader);

                            AutodiscoverResponse response = this.ReadSoapBody(ewsXmlReader);

                            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);

                            if (response.ErrorCode == AutodiscoverErrorCode.NoError)
                            {
                                return(response);
                            }
                            else
                            {
                                throw new AutodiscoverResponseException(response.ErrorCode, response.ErrorMessage);
                            }
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
                {
                    IEwsHttpWebResponse httpWebResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(ex);

                    if (AutodiscoverRequest.IsRedirectionResponse(httpWebResponse))
                    {
                        this.Service.ProcessHttpResponseHeaders(
                            TraceFlags.AutodiscoverResponseHttpHeaders,
                            httpWebResponse);

                        AutodiscoverResponse response = this.CreateRedirectionResponse(httpWebResponse);
                        if (response != null)
                        {
                            return(response);
                        }
                    }
                    else
                    {
                        this.ProcessWebException(ex);
                    }
                }

                // Wrap exception if the above code block didn't throw
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
            catch (XmlException ex)
            {
                this.Service.TraceMessage(
                    TraceFlags.AutodiscoverConfiguration,
                    string.Format("XML parsing error: {0}", ex.Message));

                // Wrap exception
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
            catch (IOException ex)
            {
                this.Service.TraceMessage(
                    TraceFlags.AutodiscoverConfiguration,
                    string.Format("I/O error: {0}", ex.Message));

                // Wrap exception
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
        }
        /// <summary>
        /// Executes this instance.
        /// </summary>
        /// <returns></returns>
        internal AutodiscoverResponse InternalExecute()
        {
            this.Validate();

            try
            {
                IEwsHttpWebRequest request = this.Service.PrepareHttpWebRequestForUrl(this.Url);

                this.Service.TraceHttpRequestHeaders(TraceFlags.AutodiscoverRequestHttpHeaders, request);

                bool needSignature = this.Service.Credentials != null && this.Service.Credentials.NeedSignature;
                bool needTrace = this.Service.IsTraceEnabledFor(TraceFlags.AutodiscoverRequest);

                using (Stream requestStream = request.GetRequestStream())
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.Service, memoryStream))
                        {
                            writer.RequireWSSecurityUtilityNamespace = needSignature;
                            this.WriteSoapRequest(
                                this.Url, 
                                writer);
                        }

                        if (needSignature)
                        {
                            this.service.Credentials.Sign(memoryStream);
                        }

                        if (needTrace)
                        {
                            memoryStream.Position = 0;
                            this.Service.TraceXml(TraceFlags.AutodiscoverRequest, memoryStream);
                        }

                        EwsUtilities.CopyStream(memoryStream, requestStream);
                    }
                }

                using (IEwsHttpWebResponse webResponse = request.GetResponse())
                {
                    if (AutodiscoverRequest.IsRedirectionResponse(webResponse))
                    {
                        AutodiscoverResponse response = this.CreateRedirectionResponse(webResponse);
                        if (response != null)
                        {
                            return response;
                        }
                        else
                        {
                            throw new ServiceRemoteException(Strings.InvalidRedirectionResponseReturned);
                        }
                    }

                    using (Stream responseStream = AutodiscoverRequest.GetResponseStream(webResponse))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            // Copy response stream to in-memory stream and reset to start
                            EwsUtilities.CopyStream(responseStream, memoryStream);
                            memoryStream.Position = 0;

                            this.Service.TraceResponse(webResponse, memoryStream);                           

                            EwsXmlReader ewsXmlReader = new EwsXmlReader(memoryStream);

                            // WCF may not generate an XML declaration.
                            ewsXmlReader.Read();
                            if (ewsXmlReader.NodeType == XmlNodeType.XmlDeclaration)
                            {
                                ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
                            }
                            else if ((ewsXmlReader.NodeType != XmlNodeType.Element) || (ewsXmlReader.LocalName != XmlElementNames.SOAPEnvelopeElementName) || (ewsXmlReader.NamespaceUri != EwsUtilities.GetNamespaceUri(XmlNamespace.Soap)))
                            {
                                throw new ServiceXmlDeserializationException(Strings.InvalidAutodiscoverServiceResponse);
                            }

                            this.ReadSoapHeaders(ewsXmlReader);

                            AutodiscoverResponse response = this.ReadSoapBody(ewsXmlReader);

                            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);

                            if (response.ErrorCode == AutodiscoverErrorCode.NoError)
                            {
                                return response;
                            }
                            else
                            {
                                throw new AutodiscoverResponseException(response.ErrorCode, response.ErrorMessage);
                            }
                        }
                    }
                }
            }
            catch (WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null)
                {
                    IEwsHttpWebResponse httpWebResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(ex);

                    if (AutodiscoverRequest.IsRedirectionResponse(httpWebResponse))
                    {
                        this.Service.ProcessHttpResponseHeaders(
                            TraceFlags.AutodiscoverResponseHttpHeaders,
                            httpWebResponse);

                        AutodiscoverResponse response = this.CreateRedirectionResponse(httpWebResponse);
                        if (response != null)
                        {
                            return response;
                        }
                    }
                    else
                    {
                        this.ProcessWebException(ex);
                    }
                }

                // Wrap exception if the above code block didn't throw
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
            catch (XmlException ex)
            {
                this.Service.TraceMessage(
                    TraceFlags.AutodiscoverConfiguration,
                    string.Format("XML parsing error: {0}", ex.Message));

                // Wrap exception
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
            catch (IOException ex)
            {
                this.Service.TraceMessage(
                    TraceFlags.AutodiscoverConfiguration,
                    string.Format("I/O error: {0}", ex.Message));

                // Wrap exception
                throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, ex.Message), ex);
            }
        }
 /// <summary>
 /// Loads responses from XML.
 /// </summary>
 /// <param name="reader">The reader.</param>
 /// <returns></returns>
 internal AutodiscoverResponse LoadFromXml(EwsXmlReader reader)
 {
     string elementName = this.GetResponseXmlElementName();
     reader.ReadStartElement(XmlNamespace.Autodiscover, elementName);
     AutodiscoverResponse response = this.CreateServiceResponse();
     response.LoadFromXml(reader, elementName);
     return response;
 }
 /// <summary>
 /// Read SOAP body.
 /// </summary>
 /// <param name="reader">EwsXmlReader</param>
 internal AutodiscoverResponse ReadSoapBody(EwsXmlReader reader)
 {
     reader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
     AutodiscoverResponse responses = this.LoadFromXml(reader);
     reader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
     return responses;
 }
        /// <summary>
        /// Read SOAP headers.
        /// </summary>
        /// <param name="reader">EwsXmlReader</param>
        internal void ReadSoapHeaders(EwsXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPHeaderElementName);
            do
            {
                reader.Read();

                this.ReadSoapHeader(reader);
            }
            while (!reader.IsEndElement(XmlNamespace.Soap, XmlElementNames.SOAPHeaderElementName));
        }