private static void EndGetRequestStream <T>(IAsyncResult getRequestStreamResult) { ExecutionState <T> executionState = (ExecutionState <T>)getRequestStreamResult.AsyncState; executionState.CurrentOperation = ExecutorOperation.EndGetRequestStream; try { executionState.UpdateCompletedSynchronously(getRequestStreamResult.CompletedSynchronously); executionState.ReqStream = executionState.Req.EndGetRequestStream(getRequestStreamResult); executionState.CurrentOperation = ExecutorOperation.BeginUploadRequest; Logger.LogInformational(executionState.OperationContext, SR.TraceUpload); MultiBufferMemoryStream multiBufferMemoryStream = executionState.RestCMD.SendStream as MultiBufferMemoryStream; if (multiBufferMemoryStream != null && !executionState.RestCMD.SendStreamLength.HasValue) { multiBufferMemoryStream.BeginFastCopyTo(executionState.ReqStream, executionState.OperationExpiryTime, EndFastCopyTo <T>, executionState); } else { // don't calculate md5 here as we should have already set this for auth purposes executionState.RestCMD.SendStream.WriteToAsync(executionState.ReqStream, executionState.RestCMD.SendStreamLength, null /* maxLength */, false, executionState, null /* streamCopyState */, EndSendStreamCopy); } } catch (Exception ex) { Logger.LogWarning(executionState.OperationContext, SR.TraceUploadError, ex.Message); executionState.ExceptionRef = ExecutorBase.TranslateExceptionBasedOnParseError(ex, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseError); Executor.EndOperation(executionState); } }
public static void InitRequest <T>(ExecutionState <T> executionState) { try { executionState.Init(); // 0. Begin Request Executor.StartRequestAttempt(executionState); // Steps 1 - 4 Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestAsync, executionState.Cmd.Uri); Executor.ProcessStartOfRequest(executionState); if (Executor.CheckTimeout <T>(executionState, false)) { Executor.EndOperation(executionState); return; } lock (executionState.CancellationLockerObject) { if (Executor.CheckCancellation(executionState)) { Executor.EndOperation(executionState); return; } // 5. potentially upload data if (executionState.RestCMD.SendStream != null) { Executor.BeginGetRequestStream(executionState); } else { Executor.BeginGetResponse(executionState); } } } catch (Exception ex) { Logger.LogError(executionState.OperationContext, SR.TraceInitRequestError, ex.Message); // Store exception and invoke callback here. All operations in this try would be non-retryable by default StorageException storageEx = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); storageEx.IsRetryable = false; executionState.ExceptionRef = storageEx; executionState.OnComplete(); } }
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.EndOperation(executionState); }
private static void EndResponseStreamCopy <T>(ExecutionState <T> executionState) { 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.EndOperation(executionState); }
private static void EndFastCopyTo <T>(IAsyncResult fastCopyToResult) { ExecutionState <T> executionState = (ExecutionState <T>)fastCopyToResult.AsyncState; try { executionState.UpdateCompletedSynchronously(fastCopyToResult.CompletedSynchronously); MultiBufferMemoryStream multiBufferMemoryStream = (MultiBufferMemoryStream)executionState.RestCMD.SendStream; multiBufferMemoryStream.EndFastCopyTo(fastCopyToResult); Executor.EndSendStreamCopy(executionState); } catch (Exception ex) { Logger.LogWarning(executionState.OperationContext, SR.TraceUploadError, ex.Message); executionState.ExceptionRef = ExecutorBase.TranslateExceptionBasedOnParseError(ex, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseError); Executor.EndOperation(executionState); } }
private static void BeginGetResponse <T>(ExecutionState <T> executionState) { executionState.CurrentOperation = ExecutorOperation.BeginGetResponse; Logger.LogInformational(executionState.OperationContext, SR.TraceGetResponse); try { APMWithTimeout.RunWithTimeout( executionState.Req.BeginGetResponse, Executor.EndGetResponse <T>, Executor.AbortRequest <T>, executionState, executionState.RemainingTimeout); } catch (Exception ex) { Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); executionState.ExceptionRef = ExecutorBase.TranslateExceptionBasedOnParseError(ex, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseError); Executor.EndOperation(executionState); } }
private static void BeginGetRequestStream <T>(ExecutionState <T> executionState) { executionState.CurrentOperation = ExecutorOperation.BeginGetRequestStream; Logger.LogInformational(executionState.OperationContext, SR.TracePrepareUpload); try { APMWithTimeout.RunWithTimeout( executionState.Req.BeginGetRequestStream, Executor.EndGetRequestStream <T>, Executor.AbortRequest <T>, executionState, executionState.RemainingTimeout); } catch (Exception ex) { Logger.LogWarning(executionState.OperationContext, SR.TracePrepareUploadError, ex.Message); executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); Executor.EndOperation(executionState); } }
private static void EndSendStreamCopy <T>(ExecutionState <T> executionState) { executionState.CurrentOperation = ExecutorOperation.EndUploadRequest; lock (executionState.CancellationLockerObject) { Executor.CheckCancellation(executionState); if (executionState.ExceptionRef != null) { try { executionState.Req.Abort(); } catch (Exception) { // No op } Executor.EndOperation(executionState); } else { try { executionState.ReqStream.Flush(); executionState.ReqStream.Dispose(); executionState.ReqStream = null; } catch (Exception) { // If we could not flush/dispose the request stream properly, // BeginGetResponse will fail with a more meaningful error anyway. } Executor.BeginGetResponse(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, 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, 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.EndOperation(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); } }