1// +build go1.13 2 3// Copyright (c) Microsoft Corporation. All rights reserved. 4// Licensed under the MIT License. 5 6package azcore 7 8import "io" 9 10// ********** The following is common between the request body AND the response body. 11 12// ProgressReceiver defines the signature of a callback function invoked as progress is reported. 13type ProgressReceiver func(bytesTransferred int64) 14 15// ********** The following are specific to the request body (a ReadSeekCloser) 16 17// This struct is used when sending a body to the network 18type requestBodyProgress struct { 19 requestBody ReadSeekCloser // Seeking is required to support retries 20 pr ProgressReceiver 21} 22 23// NewRequestBodyProgress adds progress reporting to an HTTP request's body stream. 24func NewRequestBodyProgress(requestBody ReadSeekCloser, pr ProgressReceiver) ReadSeekCloser { 25 return &requestBodyProgress{requestBody: requestBody, pr: pr} 26} 27 28// Read reads a block of data from an inner stream and reports progress 29func (rbp *requestBodyProgress) Read(p []byte) (n int, err error) { 30 n, err = rbp.requestBody.Read(p) 31 if err != nil { 32 return 33 } 34 // Invokes the user's callback method to report progress 35 position, err := rbp.requestBody.Seek(0, io.SeekCurrent) 36 if err != nil { 37 return 38 } 39 rbp.pr(position) 40 return 41} 42 43func (rbp *requestBodyProgress) Seek(offset int64, whence int) (offsetFromStart int64, err error) { 44 return rbp.requestBody.Seek(offset, whence) 45} 46 47// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it. 48func (rbp *requestBodyProgress) Close() error { 49 return rbp.requestBody.Close() 50} 51 52// ********** The following are specific to the response body (a ReadCloser) 53 54// This struct is used when sending a body to the network 55type responseBodyProgress struct { 56 responseBody io.ReadCloser 57 pr ProgressReceiver 58 offset int64 59} 60 61// NewResponseBodyProgress adds progress reporting to an HTTP response's body stream. 62func NewResponseBodyProgress(responseBody io.ReadCloser, pr ProgressReceiver) io.ReadCloser { 63 return &responseBodyProgress{responseBody: responseBody, pr: pr, offset: 0} 64} 65 66// Read reads a block of data from an inner stream and reports progress 67func (rbp *responseBodyProgress) Read(p []byte) (n int, err error) { 68 n, err = rbp.responseBody.Read(p) 69 rbp.offset += int64(n) 70 71 // Invokes the user's callback method to report progress 72 rbp.pr(rbp.offset) 73 return 74} 75 76func (rbp *responseBodyProgress) Close() error { 77 return rbp.responseBody.Close() 78} 79