private static void EndResponseStreamCopy <T>(ExecutionState <T> executionState) { // At this time, the response/error stream has been read. So try to parse the error if there was en exception if (executionState.RestCMD.ErrorStream != null) { executionState.RestCMD.ErrorStream.Seek(0, SeekOrigin.Begin); if (executionState.Cmd.ParseError != null) { executionState.ExceptionRef = StorageException.TranslateExceptionWithPreBufferedStream(executionState.ExceptionRef, executionState.Cmd.CurrentResult, stream => executionState.Cmd.ParseError(stream, executionState.Resp, null), executionState.RestCMD.ErrorStream); } else { executionState.ExceptionRef = StorageException.TranslateExceptionWithPreBufferedStream(executionState.ExceptionRef, executionState.Cmd.CurrentResult, null, executionState.RestCMD.ErrorStream); } // Dispose the stream and end the operation try { executionState.RestCMD.ErrorStream.Dispose(); executionState.RestCMD.ErrorStream = null; } catch (Exception) { // no-op } } // Dispose the stream and end the operation try { if (executionState.RestCMD.ResponseStream != null) { executionState.RestCMD.ResponseStream.Dispose(); executionState.RestCMD.ResponseStream = null; } } catch (Exception) { // no-op, because HttpWebResponse.Close should take care of it } executionState.CurrentOperation = ExecutorOperation.EndDownloadResponse; Executor.EndOperationWithPostProcess(executionState); }
private static void EndGetResponse <T>(IAsyncResult getResponseResult) { ExecutionState <T> executionState = (ExecutionState <T>)getResponseResult.AsyncState; executionState.CurrentOperation = ExecutorOperation.EndGetResponse; try { executionState.UpdateCompletedSynchronously(getResponseResult.CompletedSynchronously); try { executionState.Resp = executionState.Req.EndGetResponse(getResponseResult) as HttpWebResponse; } catch (WebException ex) { Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); executionState.Resp = (HttpWebResponse)ex.Response; if (ex.Status == WebExceptionStatus.Timeout || executionState.ReqTimedOut) { throw new TimeoutException(); } if (executionState.Resp == null) { throw; } else { // Store this exception for now. It will be parsed/thrown after the stream is read in step 8 executionState.ExceptionRef = ex; } } Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); Executor.FireResponseReceived(executionState); // 7. Do Response parsing (headers etc, no stream available here) if (executionState.RestCMD.PreProcessResponse != null) { executionState.CurrentOperation = ExecutorOperation.PreProcess; try { executionState.Result = executionState.RestCMD.PreProcessResponse(executionState.RestCMD, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); // clear exception executionState.ExceptionRef = null; Logger.LogInformational(executionState.OperationContext, SR.TracePreProcessDone); } catch (Exception ex) { executionState.ExceptionRef = ex; } } Executor.CheckCancellation(executionState); executionState.CurrentOperation = ExecutorOperation.GetResponseStream; executionState.RestCMD.ResponseStream = executionState.Resp.GetResponseStream(); // 8. (Potentially reads stream from server) if (executionState.ExceptionRef != null) { executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; Logger.LogInformational(executionState.OperationContext, SR.TraceDownloadError); executionState.RestCMD.ErrorStream = new MemoryStream(); executionState.RestCMD.ResponseStream.WriteToAsync(executionState.RestCMD.ErrorStream, default(IBufferManager), null /* copyLength */, null /* maxLength */, false /* calculateMd5 */, executionState, new StreamDescriptor(), EndResponseStreamCopy); } else { if (!executionState.RestCMD.RetrieveResponseStream) { executionState.RestCMD.DestinationStream = Stream.Null; } if (executionState.RestCMD.DestinationStream != null) { if (executionState.RestCMD.StreamCopyState == null) { executionState.RestCMD.StreamCopyState = new StreamDescriptor(); } executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; Logger.LogInformational(executionState.OperationContext, SR.TraceDownload); executionState.RestCMD.ResponseStream.WriteToAsync(executionState.RestCMD.DestinationStream, default(IBufferManager), null /* copyLength */, null /* maxLength */, executionState.RestCMD.CalculateMd5ForResponseStream, executionState, executionState.RestCMD.StreamCopyState, EndResponseStreamCopy); } else { // Dont want to copy stream, just want to consume it so end Executor.EndOperationWithPostProcess(executionState); } } } catch (Exception ex) { Logger.LogWarning(executionState.OperationContext, SR.TracePreProcessError, ex.Message); executionState.ExceptionRef = ExecutorBase.TranslateExceptionBasedOnParseError(ex, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseError); Executor.EndOperation(executionState); } }