public async Task ExecuteAsync()

in src/AlibabaCloud.OSS.V2/Internal/ExecuteMiddleware.cs [32:153]


        public async Task<ResponseMessage> ExecuteAsync(RequestMessage request, ExecuteContext context)
        {
            using var cts = new CancellationTokenSource(context.RequestOnceTimeout);
            var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, context.ApiCallCancellationToken);

            using var httpRequest = new HttpRequestMessage(ConvertMethod(request.Method), request.RequestUri);
            HttpResponseMessage? httpResponse = null;
            var completionOption = context.HttpCompletionOption ?? HttpCompletionOption.ResponseContentRead;
            var content = NopCloseRequestContent.StreamFor(request.Content, cts, context.RequestOnceTimeout);

            // Write data to the request stream.
            // Get & Head Method does not support HttpContent
            if (!(httpRequest.Method == HttpMethod.Get ||
                    httpRequest.Method == HttpMethod.Head))
                httpRequest.Content = content != null
                    ? new StreamContent(content)
                    : new ByteArrayContent(Array.Empty<byte>());

            // Write headers
            foreach (var item in request.Headers)
            {
                if (!ContentHeadersHash.Contains(item.Key))
                {
                    httpRequest.Headers.TryAddWithoutValidation(item.Key, item.Value);
                    continue;
                }

                if (httpRequest.Content == null) continue;

                switch (item.Key.ToLower())
                {
                    case "content-disposition":
                        httpRequest.Content.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse(item.Value);
                        break;
                    case "content-encoding":
                        httpRequest.Content.Headers.ContentEncoding.Add(item.Value);
                        break;
                    case "content-language":
                        httpRequest.Content.Headers.ContentLanguage.Add(item.Value);
                        break;
                    case "content-type":
                        httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(item.Value);
                        break;
                    case "content-md5":
                        httpRequest.Content.Headers.ContentMD5 = Convert.FromBase64String(item.Value);
                        break;
                    case "content-length":
                        httpRequest.Content.Headers.ContentLength = Convert.ToInt64(item.Value);
                        break;
                    case "expires":
                        if (DateTime.TryParse(
                                item.Value,
                                CultureInfo.InvariantCulture,
                                DateTimeStyles.None,
                                out var expires
                            ))
                            httpRequest.Content.Headers.Expires = expires;
                        break;
                }
            }

            try
            {
                httpResponse = await handler.SendAsync(httpRequest, completionOption, linkedCts.Token).ConfigureAwait(false);

                Stream? contentStream = null;
                if (httpResponse.Content != null)
                {

                    contentStream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    // allways save reponse body into memroy when status code is not 2xx(not include 203)
                    var statusCode = (int)httpResponse.StatusCode;
                    if ((statusCode == 203 || statusCode / 100 != 2) && !contentStream.CanSeek)
                    {
                        try
                        {
                            if (contentStream.CanTimeout)
                            {
                                contentStream.ReadTimeout = (int)context.RequestOnceTimeout.TotalMilliseconds;
                            }
                            var stream = new MemoryStream();
#if NET5_0_OR_GREATER
                            await contentStream.CopyToAsync(stream, linkedCts.Token).ConfigureAwait(false);
#else
                            await contentStream.CopyToAsync(stream).ConfigureAwait(false);
#endif
                            contentStream = stream;
                            contentStream.Seek(0, SeekOrigin.Begin);
                        }
                        finally
                        {
                            httpResponse.Content.Dispose();
                        }
                    }
                }

                var response = new ResponseMessage((int)httpResponse.StatusCode, httpResponse.ReasonPhrase!)
                {
                    Request = request,
                    Content = contentStream
                };

                // headers
                foreach (KeyValuePair<string, IEnumerable<string>> header in httpResponse.Headers) response.Headers[header.Key] = string.Join(",", header.Value);

                if (httpResponse.Content != null)
                {
                    foreach (KeyValuePair<string, IEnumerable<string>> header in httpResponse.Content.Headers) response.Headers[header.Key] = string.Join(",", header.Value);
                }

                return response;
            }
            catch (OperationCanceledException e) when (cts.Token.IsCancellationRequested)
            {
                throw CancellationHelper.CreateRequestTimeoutException(e, context.RequestOnceTimeout);
            }
            catch (HttpRequestException e)
            {
                throw new RequestFailedException(e.Message, e);
            }
        }