Ejemplo n.º 1
0
        /// <summary>
        /// 异步获取响应字节集合。
        /// </summary>
        /// <param name="uri">给定的 <see cref="Uri"/>。</param>
        /// <param name="postData">给定要提交的数据(可选)。</param>
        /// <param name="enableCodec">启用字节编解码传输(可选)。</param>
        /// <param name="parameters">给定的自定义参数(可选)。</param>
        /// <param name="cancellationToken">给定的 <see cref="CancellationToken"/>(可选)。</param>
        /// <returns>返回一个包含字节数组的异步操作。</returns>
        public virtual async Task <byte[]> GetResponseBytesAsync(Uri uri, string postData = null,
                                                                 bool enableCodec         = false, RequestParameters parameters = default, CancellationToken cancellationToken = default)
        {
            var stream = await GetResponseStreamAsync(uri, postData, enableCodec, parameters, cancellationToken).ConfigureAwait();

            if (stream.IsNotNull())
            {
                var bytes = Array.Empty <byte>();

                using (var ms = new MemoryStream())
                {
                    var buffer = new byte[64 * Options.BufferSize];

                    int length;
                    while ((length = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, length);
                    }

                    bytes = ms.ToArray();
                }

                return(ByteCodec.Decode(bytes, enableCodec));
            }

            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 异步获取响应字节数组。
        /// </summary>
        /// <param name="uri">给定的 <see cref="Uri"/>。</param>
        /// <param name="postData">给定要提交的数据(可选)。</param>
        /// <param name="enableCodec">启用字节编解码传输(可选)。</param>
        /// <param name="parameters">给定的自定义参数(可选)。</param>
        /// <param name="cancellationToken">给定的 <see cref="CancellationToken"/>(可选)。</param>
        /// <returns>返回一个包含字节数组的异步操作。</returns>
        public override async Task <byte[]> GetResponseBytesAsync(Uri uri, string postData = null,
                                                                  bool enableCodec         = false, RequestParameters parameters = default, CancellationToken cancellationToken = default)
        {
            var message = await GetResponseMessage(uri, postData, enableCodec, parameters, cancellationToken).ConfigureAwait();

            var buffer = await message.Content.ReadAsByteArrayAsync().ConfigureAwait();

            if (buffer.IsNotEmpty())
            {
                return(ByteCodec.Decode(buffer, enableCodec));
            }

            return(buffer);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 异步获取响应流。
        /// </summary>
        /// <param name="uri">给定的 <see cref="Uri"/>。</param>
        /// <param name="postData">给定要提交的数据(可选)。</param>
        /// <param name="enableCodec">启用字节编解码传输(可选)。</param>
        /// <param name="parameters">给定的自定义参数(可选)。</param>
        /// <param name="cancellationToken">给定的 <see cref="CancellationToken"/>(可选)。</param>
        /// <returns>返回一个包含 <see cref="Stream"/> 的异步操作。</returns>
        public override Task <Stream> GetResponseStreamAsync(Uri uri, string postData = null,
                                                             bool enableCodec         = false, RequestParameters parameters = default, CancellationToken cancellationToken = default)
        {
            uri.NotNull(nameof(uri));

            HttpWebRequest request;

            return(cancellationToken.RunOrCancelAsync(() =>
            {
                var opts = Options.Requester;

                request = WebRequest.CreateHttp(uri);
                request.Timeout = (int)opts.Timeout.TotalMilliseconds;
                request.UserAgent = opts.UserAgent;

                if (parameters.Accept.IsNotEmpty())
                {
                    request.Accept = parameters.Accept;
                }

                if (parameters.ContentType.IsNotEmpty())
                {
                    request.ContentType = parameters.ContentType;
                }

                if (parameters.Headers.IsNotEmpty())
                {
                    parameters.Headers.ForEach(pair =>
                    {
                        request.Headers.Add(pair.Key, pair.Value);
                    });
                }

                if (postData.IsNotEmpty())
                {
                    request.ContentType = $"application/x-www-form-urlencoded; charset={Encoding.AsName()}";
                    request.Method = "POST";
                }

                return Policy
                .Handle <IOException>(exception =>
                {
                    Logger.LogError(exception, exception.AsInnerMessage());
                    return true;
                })
                .OrResult <Stream>(r => r.IsNull())
                .WaitAndRetry(opts.RetryCount, opts.SleepDurationFactory, (exception, sleepDuration, retryCount, context) =>
                {
                    Logger.LogDebug($"Retry {retryCount} times from {sleepDuration.TotalMilliseconds} milliseconds later");
                })
                .Execute(GetResponseStream);
            }));

            Stream GetResponseStream()
            {
                if (postData.IsNotEmpty())
                {
                    var buffer = ByteCodec.EncodeStringAsBytes(postData, enableCodec);
                    request.ContentLength = buffer.Length;

                    var stream = request.GetRequestStream();
                    stream.Write(buffer, 0, buffer.Length);

                    Logger.LogDebug($"Send data: {postData}");
                    Logger.LogDebug($"Enable codec: {enableCodec}");
                }

                return(request.GetResponse().GetResponseStream());
            }
        }
Ejemplo n.º 4
0
        protected virtual Task <HttpResponseMessage> GetResponseMessage(Uri uri, string postData = null,
                                                                        bool enableCodec         = false, RequestParameters parameters = default, CancellationToken cancellationToken = default)
        {
            var opts = Options.Requester;

            var client = Factory.CreateClient();

            client.Timeout = opts.Timeout;
            client.DefaultRequestHeaders.Add("User-Agent", opts.UserAgent);

            if (parameters.Accept.IsNotEmpty())
            {
                client.DefaultRequestHeaders.Add("Accept", parameters.Accept);
            }

            if (parameters.ContentType.IsNotEmpty())
            {
                client.DefaultRequestHeaders.Add("Content-Type", parameters.ContentType);
            }

            if (parameters.Headers.IsNotEmpty())
            {
                parameters.Headers.ForEach(pair =>
                {
                    client.DefaultRequestHeaders.Add(pair.Key, pair.Value);
                });
            }

            return(Policy
                   .Handle <HttpRequestException>(exception =>
            {
                Logger.LogError(exception, exception.AsInnerMessage());
                return true;
            })
                   .OrResult <HttpResponseMessage>(result =>
            {
                Logger.LogTrace(result.StatusCode.ToString());
                return result.StatusCode == HttpStatusCode.BadGateway;
            })
                   .WaitAndRetryAsync(opts.RetryCount, opts.SleepDurationFactory, (exception, sleepDuration, retryCount, context) =>
            {
                Logger.LogDebug($"Retry {retryCount} times from {sleepDuration.TotalMilliseconds} milliseconds later");
            })
                   .ExecuteAsync(GetResponseMessageAsync));

            async Task <HttpResponseMessage> GetResponseMessageAsync()
            {
                HttpResponseMessage responseMessage;

                if (postData.IsNotEmpty())
                {
                    var buffer  = ByteCodec.EncodeStringAsBytes(postData, enableCodec);
                    var content = new ByteArrayContent(buffer);

                    responseMessage = await client.PostAsync(uri, content, cancellationToken).ConfigureAwait();

                    Logger.LogDebug($"Send data: {postData}");
                    Logger.LogDebug($"Enable codec: {enableCodec}");
                }
                else
                {
                    responseMessage = await client.GetAsync(uri, cancellationToken).ConfigureAwait();
                }

                return(responseMessage);
            }
        }