/// <summary> /// Executes this request. /// </summary> /// <returns>Service response.</returns> internal object InternalExecute() { IEwsHttpWebRequest request; IEwsHttpWebResponse response = this.ValidateAndEmitRequest(out request); return(this.ReadResponse(response)); }
/// <summary> /// Reads the response with error handling /// </summary> /// <param name="response">The response.</param> /// <returns>Service response.</returns> private object ReadResponse(IEwsHttpWebResponse response) { object serviceResponse; try { this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, response); // If tracing is enabled, we read the entire response into a MemoryStream so that we // can pass it along to the ITraceListener. Then we parse the response from the // MemoryStream. if (this.Service.IsTraceEnabledFor(TraceFlags.EwsResponse)) { using (MemoryStream memoryStream = new MemoryStream()) { using (Stream serviceResponseStream = ServiceRequestBase.GetResponseStream(response)) { // Copy response to in-memory stream and reset position to start. EwsUtilities.CopyStream(serviceResponseStream, memoryStream); memoryStream.Position = 0; } this.TraceResponseXml(response, memoryStream); serviceResponse = this.ReadResponseXml(memoryStream, response.Headers); } } else { using (Stream responseStream = ServiceRequestBase.GetResponseStream(response)) { serviceResponse = this.ReadResponseXml(responseStream, response.Headers); } } } catch (WebException e) { if (e.Response != null) { IEwsHttpWebResponse exceptionResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(e); this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, exceptionResponse); } throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, e.Message), e); } catch (IOException e) { // Wrap exception. throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, e.Message), e); } finally { if (response != null) { response.Close(); } } return(serviceResponse); }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <param name="readTimeout">read timeout in milliseconds</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response, int readTimeout) { Stream responseStream = response.GetResponseStream(); responseStream.ReadTimeout = readTimeout; return(WrapStream(responseStream, response.ContentEncoding)); }
/// <summary> /// Determines whether response is a redirection. /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> /// <returns>True if redirection response.</returns> internal static bool IsRedirectionResponse(IEwsHttpWebResponse httpWebResponse) { return (httpWebResponse.StatusCode == HttpStatusCode.Redirect) || (httpWebResponse.StatusCode == HttpStatusCode.Moved) || (httpWebResponse.StatusCode == HttpStatusCode.RedirectKeepVerb) || (httpWebResponse.StatusCode == HttpStatusCode.RedirectMethod); }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response) { string contentEncoding = response.ContentEncoding; Stream responseStream = response.GetResponseStream(); return(WrapStream(responseStream, response.ContentEncoding)); }
/// <summary> /// Processes an HTTP error response /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> /// <param name="webException">The web exception.</param> /// <param name="responseHeadersTraceFlag">The trace flag for response headers.</param> /// <param name="responseTraceFlag">The trace flag for responses.</param> /// <remarks> /// This method doesn't handle 500 ISE errors. This is handled by the caller since /// 500 ISE typically indicates that a SOAP fault has occurred and the handling of /// a SOAP fault is currently service specific. /// </remarks> internal void InternalProcessHttpErrorResponse( IEwsHttpWebResponse httpWebResponse, WebException webException, TraceFlags responseHeadersTraceFlag, TraceFlags responseTraceFlag) { EwsUtilities.Assert( httpWebResponse.StatusCode != HttpStatusCode.InternalServerError, "ExchangeServiceBase.InternalProcessHttpErrorResponse", "InternalProcessHttpErrorResponse does not handle 500 ISE errors, the caller is supposed to handle this."); this.ProcessHttpResponseHeaders(responseHeadersTraceFlag, httpWebResponse); // Deal with new HTTP error code indicating that account is locked. // The "unlock" URL is returned as the status description in the response. if (httpWebResponse.StatusCode == ExchangeServiceBase.AccountIsLocked) { string location = httpWebResponse.StatusDescription; Uri accountUnlockUrl = null; if (Uri.IsWellFormedUriString(location, UriKind.Absolute)) { accountUnlockUrl = new Uri(location); } this.TraceMessage(responseTraceFlag, string.Format("Account is locked. Unlock URL is {0}", accountUnlockUrl)); throw new AccountIsLockedException( string.Format(Strings.AccountIsLocked, accountUnlockUrl), accountUnlockUrl, webException); } }
/// <summary> /// Determines whether response is a redirection. /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> /// <returns>True if redirection response.</returns> internal static bool IsRedirectionResponse(IEwsHttpWebResponse httpWebResponse) { return((httpWebResponse.StatusCode == HttpStatusCode.Redirect) || (httpWebResponse.StatusCode == HttpStatusCode.Moved) || (httpWebResponse.StatusCode == HttpStatusCode.RedirectKeepVerb) || (httpWebResponse.StatusCode == HttpStatusCode.RedirectMethod)); }
/// <summary> /// Executes this request. /// </summary> /// <returns>Service response.</returns> internal async Task <object> InternalExecuteAsync() { IEwsHttpWebRequest request; IEwsHttpWebResponse response = await this.ValidateAndEmitRequestAsync(out request); return(this.ReadResponse(response)); }
/// <summary> /// Exectures the request. /// </summary> internal void InternalExecute() { lock (this.lockObject) { this.response = this.ValidateAndEmitRequest(out this.request); this.InternalOnConnect(); } }
/// <summary> /// Ends executing this async request. /// </summary> /// <param name="asyncResult">The async result</param> /// <returns>Service response object.</returns> internal object EndInternalExecute(IAsyncResult asyncResult) { // We have done enough validation before AsyncRequestResult asyncRequestResult = (AsyncRequestResult)asyncResult; IEwsHttpWebResponse response = this.EndGetEwsHttpWebResponse(asyncRequestResult.WebRequest, asyncRequestResult.WebAsyncResult); return(this.ReadResponse(response)); }
/// <summary> /// Traces the HTTP response headers. /// </summary> /// <param name="traceType">Kind of trace entry.</param> /// <param name="response">The response.</param> private void TraceHttpResponseHeaders(TraceFlags traceType, IEwsHttpWebResponse response) { if (this.IsTraceEnabledFor(traceType)) { string traceTypeStr = traceType.ToString(); string headersAsString = EwsUtilities.FormatHttpResponseHeaders(response); string logMessage = EwsUtilities.FormatLogMessage(traceTypeStr, headersAsString); this.TraceListener.Trace(traceTypeStr, logMessage); } }
/// <summary> /// Exectures the request. /// </summary> internal void InternalExecute() { lock (this.lockObject) { var tuple = this.ValidateAndEmitRequest().Result; this.request = tuple.Item1; this.response = tuple.Item2; this.InternalOnConnect(); } }
/// <summary> /// Traces the response. This should only be used for synchronous requests, or synchronous situations /// (such as a WebException on an asynchrounous request). /// </summary> /// <param name="response">The response.</param> /// <param name="memoryStream">The response content in a MemoryStream.</param> protected void TraceResponseXml(IEwsHttpWebResponse response, MemoryStream memoryStream) { if (!string.IsNullOrEmpty(response.ContentType) && (response.ContentType.StartsWith("text/", StringComparison.OrdinalIgnoreCase) || response.ContentType.StartsWith("application/soap", StringComparison.OrdinalIgnoreCase))) { this.Service.TraceXml(TraceFlags.EwsResponse, memoryStream); } else { this.Service.TraceMessage(TraceFlags.EwsResponse, "Non-textual response"); } }
private async Task <IEwsHttpWebResponse> ValidateAndEmitRequestInternalAsync(IEwsHttpWebRequest request) { DateTime startTime = DateTime.UtcNow; IEwsHttpWebResponse response = null; try { response = await this.GetEwsHttpWebResponseAsync(request); } finally { if (this.service.SendClientLatencies) { int clientSideLatency = (int)(DateTime.UtcNow - startTime).TotalMilliseconds; string requestId = string.Empty; string soapAction = this.GetType().Name.Replace("Request", string.Empty); if (response != null && response.Headers != null) { foreach (string requestIdHeader in ServiceRequestBase.RequestIdResponseHeaders) { string requestIdValue = response.Headers.Get(requestIdHeader); if (!string.IsNullOrEmpty(requestIdValue)) { requestId = requestIdValue; break; } } } StringBuilder sb = new StringBuilder(); sb.Append("MessageId="); sb.Append(requestId); sb.Append(",ResponseTime="); sb.Append(clientSideLatency); sb.Append(",SoapAction="); sb.Append(soapAction); sb.Append(";"); lock (clientStatisticsCache) { clientStatisticsCache.Add(sb.ToString()); } } } return(response); }
/// <summary> /// Processes the web exception. /// </summary> /// <param name="webException">The web exception.</param> private void ProcessWebException(WebException webException) { if (webException.Response != null) { IEwsHttpWebResponse httpWebResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(webException); SoapFaultDetails soapFaultDetails; if (httpWebResponse.StatusCode == HttpStatusCode.InternalServerError) { // If tracing is enabled, we read the entire response into a MemoryStream so that we // can pass it along to the ITraceListener. Then we parse the response from the // MemoryStream. if (this.Service.IsTraceEnabledFor(TraceFlags.AutodiscoverRequest)) { using (MemoryStream memoryStream = new MemoryStream()) { using (Stream serviceResponseStream = AutodiscoverRequest.GetResponseStream(httpWebResponse)) { // Copy response to in-memory stream and reset position to start. EwsUtilities.CopyStream(serviceResponseStream, memoryStream); memoryStream.Position = 0; } this.Service.TraceResponse(httpWebResponse, memoryStream); EwsXmlReader reader = new EwsXmlReader(memoryStream); soapFaultDetails = this.ReadSoapFault(reader); } } else { using (Stream stream = AutodiscoverRequest.GetResponseStream(httpWebResponse)) { EwsXmlReader reader = new EwsXmlReader(stream); soapFaultDetails = this.ReadSoapFault(reader); } } if (soapFaultDetails != null) { throw new ServiceResponseException(new ServiceResponse(soapFaultDetails)); } } else { this.Service.ProcessHttpErrorResponse(httpWebResponse, webException); } } }
/// <summary> /// Traces the response. This should only be used for synchronous requests, or synchronous situations /// (such as a WebException on an asynchrounous request). /// </summary> /// <param name="response">The response.</param> /// <param name="memoryStream">The response content in a MemoryStream.</param> protected void TraceResponseJson(IEwsHttpWebResponse response, MemoryStream memoryStream) { JsonObject jsonResponse = new JsonParser(memoryStream).Parse(); using (MemoryStream responseStream = new MemoryStream()) { jsonResponse.SerializeToJson(responseStream, this.Service.TraceEnablePrettyPrinting); responseStream.Position = 0; using (StreamReader responseReader = new StreamReader(responseStream)) { this.Service.TraceMessage(TraceFlags.EwsResponse, responseReader.ReadToEnd()); } } memoryStream.Seek(0, SeekOrigin.Begin); }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response) { string contentEncoding = response.ContentEncoding; Stream responseStream = response.GetResponseStream(); if (contentEncoding.ToLowerInvariant().Contains("gzip")) { return(new GZipStream(responseStream, CompressionMode.Decompress)); } else if (contentEncoding.ToLowerInvariant().Contains("deflate")) { return(new DeflateStream(responseStream, CompressionMode.Decompress)); } else { return(responseStream); } }
/// <summary> /// Create a redirection response. /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> private AutodiscoverResponse CreateRedirectionResponse(IEwsHttpWebResponse httpWebResponse) { string location = httpWebResponse.Headers[HttpResponseHeader.Location]; if (!string.IsNullOrEmpty(location)) { try { Uri redirectionUri = new Uri(this.Url, location); if ((redirectionUri.Scheme == /*Uri.UriSchemeHttp*/ "http") || (redirectionUri.Scheme == /*Uri.UriSchemeHttps*/ "https")) { AutodiscoverResponse response = this.CreateServiceResponse(); response.ErrorCode = AutodiscoverErrorCode.RedirectUrl; response.RedirectionUrl = redirectionUri; return(response); } this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, string.Format("Invalid redirection URL '{0}' returned by Autodiscover service.", redirectionUri)); } catch (UriFormatException) { this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, string.Format("Invalid redirection location '{0}' returned by Autodiscover service.", location)); } } else { this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, "Redirection response returned by Autodiscover service without redirection location."); } return(null); }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response) { string contentEncoding = response.ContentEncoding; Stream responseStream = response.GetResponseStream(); if (contentEncoding.ToLowerInvariant().Contains("gzip")) { return new GZipStream(responseStream, CompressionMode.Decompress); } else if (contentEncoding.ToLowerInvariant().Contains("deflate")) { return new DeflateStream(responseStream, CompressionMode.Decompress); } else { return responseStream; } }
/// <summary> /// Processes the web exception. /// </summary> /// <param name="webException">The web exception.</param> private void ProcessWebException(WebException webException) { if (webException.Response != null) { IEwsHttpWebResponse httpWebResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(webException); SoapFaultDetails soapFaultDetails = null; if (httpWebResponse.StatusCode == HttpStatusCode.InternalServerError) { this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, httpWebResponse); // If tracing is enabled, we read the entire response into a MemoryStream so that we // can pass it along to the ITraceListener. Then we parse the response from the // MemoryStream. if (this.Service.IsTraceEnabledFor(TraceFlags.EwsResponse)) { using (MemoryStream memoryStream = new MemoryStream()) { using (Stream serviceResponseStream = ServiceRequestBase.GetResponseStream(httpWebResponse)) { // Copy response to in-memory stream and reset position to start. EwsUtilities.CopyStream(serviceResponseStream, memoryStream); memoryStream.Position = 0; } this.TraceResponseXml(httpWebResponse, memoryStream); EwsServiceXmlReader reader = new EwsServiceXmlReader(memoryStream, this.Service); soapFaultDetails = this.ReadSoapFault(reader); } } else { using (Stream stream = ServiceRequestBase.GetResponseStream(httpWebResponse)) { EwsServiceXmlReader reader = new EwsServiceXmlReader(stream, this.Service); soapFaultDetails = this.ReadSoapFault(reader); } } if (soapFaultDetails != null) { switch (soapFaultDetails.ResponseCode) { case ServiceError.ErrorInvalidServerVersion: throw new ServiceVersionException(Strings.ServerVersionNotSupported); case ServiceError.ErrorSchemaValidation: // If we're talking to an E12 server (8.00.xxxx.xxx), a schema validation error is the same as a version mismatch error. // (Which only will happen if we send a request that's not valid for E12). if ((this.Service.ServerInfo != null) && (this.Service.ServerInfo.MajorVersion == 8) && (this.Service.ServerInfo.MinorVersion == 0)) { throw new ServiceVersionException(Strings.ServerVersionNotSupported); } break; case ServiceError.ErrorIncorrectSchemaVersion: // This shouldn't happen. It indicates that a request wasn't valid for the version that was specified. EwsUtilities.Assert( false, "ServiceRequestBase.ProcessWebException", "Exchange server supports requested version but request was invalid for that version"); break; case ServiceError.ErrorServerBusy: throw new ServerBusyException(new ServiceResponse(soapFaultDetails)); default: // Other error codes will be reported as remote error break; } // General fall-through case: throw a ServiceResponseException throw new ServiceResponseException(new ServiceResponse(soapFaultDetails)); } } else { this.Service.ProcessHttpErrorResponse(httpWebResponse, webException); } } }
/// <summary> /// Validates request parameters, and emits the request to the server. /// </summary> /// <param name="request">The request.</param> /// <returns>The response returned by the server.</returns> protected IEwsHttpWebResponse ValidateAndEmitRequest(out IEwsHttpWebRequest request) { this.Validate(); request = this.BuildEwsHttpWebRequest(); if (this.service.SendClientLatencies) { string clientStatisticsToAdd = null; lock (clientStatisticsCache) { if (clientStatisticsCache.Count > 0) { clientStatisticsToAdd = clientStatisticsCache[0]; clientStatisticsCache.RemoveAt(0); } } if (!string.IsNullOrEmpty(clientStatisticsToAdd)) { if (request.Headers[ClientStatisticsRequestHeader] != null) { request.Headers[ClientStatisticsRequestHeader] = request.Headers[ClientStatisticsRequestHeader] + clientStatisticsToAdd; } else { request.Headers.Add( ClientStatisticsRequestHeader, clientStatisticsToAdd); } } } DateTime startTime = DateTime.UtcNow; IEwsHttpWebResponse response = null; try { response = this.GetEwsHttpWebResponse(request); } finally { if (this.service.SendClientLatencies) { int clientSideLatency = (int)(DateTime.UtcNow - startTime).TotalMilliseconds; string requestId = string.Empty; string soapAction = this.GetType().Name.Replace("Request", string.Empty); if (response != null && response.Headers != null) { foreach (string requestIdHeader in ServiceRequestBase.RequestIdResponseHeaders) { string requestIdValue = response.Headers.Get(requestIdHeader); if (!string.IsNullOrEmpty(requestIdValue)) { requestId = requestIdValue; break; } } } StringBuilder sb = new StringBuilder(); sb.Append("MessageId="); sb.Append(requestId); sb.Append(",ResponseTime="); sb.Append(clientSideLatency); sb.Append(",SoapAction="); sb.Append(soapAction); sb.Append(";"); lock (clientStatisticsCache) { clientStatisticsCache.Add(sb.ToString()); } } } return(response); }
/// <summary> /// Processes an HTTP error response. /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> /// <param name="webException">The web exception.</param> internal abstract void ProcessHttpErrorResponse(IEwsHttpWebResponse httpWebResponse, WebException webException);
/// <summary> /// Traces the HTTP response headers. /// </summary> /// <param name="traceType">Kind of trace entry.</param> /// <param name="response">The response.</param> internal void ProcessHttpResponseHeaders(TraceFlags traceType, IEwsHttpWebResponse response) { this.TraceHttpResponseHeaders(traceType, response); this.SaveHttpResponseHeaders(response.Headers); }
/// <summary> /// Create a redirection response. /// </summary> /// <param name="httpWebResponse">The HTTP web response.</param> private AutodiscoverResponse CreateRedirectionResponse(IEwsHttpWebResponse httpWebResponse) { string location = httpWebResponse.Headers[HttpResponseHeader.Location]; if (!string.IsNullOrEmpty(location)) { try { Uri redirectionUri = new Uri(this.Url, location); if ((redirectionUri.Scheme == Uri.UriSchemeHttp) || (redirectionUri.Scheme == Uri.UriSchemeHttps)) { AutodiscoverResponse response = this.CreateServiceResponse(); response.ErrorCode = AutodiscoverErrorCode.RedirectUrl; response.RedirectionUrl = redirectionUri; return response; } this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, string.Format("Invalid redirection URL '{0}' returned by Autodiscover service.", redirectionUri)); } catch (UriFormatException) { this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, string.Format("Invalid redirection location '{0}' returned by Autodiscover service.", location)); } } else { this.Service.TraceMessage( TraceFlags.AutodiscoverConfiguration, "Redirection response returned by Autodiscover service without redirection location."); } return null; }
/// <summary> /// Reads the response with error handling /// </summary> /// <param name="response">The response.</param> /// <returns>Service response.</returns> private object ReadResponse(IEwsHttpWebResponse response) { object serviceResponse; try { this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, response); // If tracing is enabled, we read the entire response into a MemoryStream so that we // can pass it along to the ITraceListener. Then we parse the response from the // MemoryStream. if (this.Service.IsTraceEnabledFor(TraceFlags.EwsResponse)) { using (MemoryStream memoryStream = new MemoryStream()) { using (Stream serviceResponseStream = ServiceRequestBase.GetResponseStream(response)) { // Copy response to in-memory stream and reset position to start. EwsUtilities.CopyStream(serviceResponseStream, memoryStream); memoryStream.Position = 0; } this.TraceResponseXml(response, memoryStream); serviceResponse = this.ReadResponseXml(memoryStream, response.Headers); } } else { using (Stream responseStream = ServiceRequestBase.GetResponseStream(response)) { serviceResponse = this.ReadResponseXml(responseStream, response.Headers); } } } catch (WebException e) { if (e.Response != null) { IEwsHttpWebResponse exceptionResponse = this.Service.HttpWebRequestFactory.CreateExceptionResponse(e); this.Service.ProcessHttpResponseHeaders(TraceFlags.EwsResponseHttpHeaders, exceptionResponse); } throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, e.Message), e); } catch (IOException e) { // Wrap exception. throw new ServiceRequestException(string.Format(Strings.ServiceRequestFailed, e.Message), e); } finally { if (response != null) { response.Close(); } } return serviceResponse; }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <param name="readTimeout">read timeout in milliseconds</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response, int readTimeout) { Stream responseStream = response.GetResponseStream(); responseStream.ReadTimeout = readTimeout; return WrapStream(responseStream, response.ContentEncoding); }
/// <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> /// Validates request parameters, and emits the request to the server. /// </summary> /// <param name="request">The request.</param> /// <returns>The response returned by the server.</returns> protected async Task <Tuple <IEwsHttpWebRequest, IEwsHttpWebResponse> > ValidateAndEmitRequest(CancellationToken token) { this.Validate(); var request = await this.BuildEwsHttpWebRequest().ConfigureAwait(false); try { if (this.service.config.sendClientLatencies) { string clientStatisticsToAdd = null; lock (clientStatisticsCache) { if (clientStatisticsCache.Count > 0) { clientStatisticsToAdd = clientStatisticsCache[0]; clientStatisticsCache.RemoveAt(0); } } if (!string.IsNullOrEmpty(clientStatisticsToAdd)) { request.AdditionalMessageHeaders.Add(new KeyValuePair <string, IEnumerable <string> >(ClientStatisticsRequestHeader, new string[] { clientStatisticsToAdd })); } } DateTime startTime = DateTime.UtcNow; IEwsHttpWebResponse response = null; try { response = await this.GetEwsHttpWebResponse(request, token).ConfigureAwait(false); } finally { if (this.service.config.sendClientLatencies) { int clientSideLatency = (int)(DateTime.UtcNow - startTime).TotalMilliseconds; string requestId = string.Empty; string soapAction = this.GetType().Name.Replace("Request", string.Empty); if (response != null && response.Headers != null) { foreach (string requestIdHeader in ServiceRequestBase.RequestIdResponseHeaders) { if (response.Headers.TryGetValues(requestIdHeader, out IEnumerable <string> values)) { requestId = values.First(); break; } } } StringBuilder sb = new StringBuilder(); sb.Append("MessageId="); sb.Append(requestId); sb.Append(",ResponseTime="); sb.Append(clientSideLatency); sb.Append(",SoapAction="); sb.Append(soapAction); sb.Append(";"); lock (clientStatisticsCache) { clientStatisticsCache.Add(sb.ToString()); } } } return(Tuple.Create(request, response)); } catch (Exception) { request.Dispose(); throw; } }
/// <summary> /// Gets the response stream (may be wrapped with GZip/Deflate stream to decompress content) /// </summary> /// <param name="response">HttpWebResponse.</param> /// <returns>ResponseStream</returns> protected static Stream GetResponseStream(IEwsHttpWebResponse response) { string contentEncoding = response.ContentEncoding; Stream responseStream = response.GetResponseStream(); return WrapStream(responseStream, response.ContentEncoding); }