Example #1
0
        /// <summary>
        /// 异步执行一个 GET 请求。
        /// </summary>
        /// <param name="httpClient"></param>
        /// <param name="relativePath"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <IHttpResponse> GetTextAsync(this IHttpClient httpClient, string relativePath, CancellationToken cancellationToken = default)
        {
            IHttpRequest request = httpClient
                                   .Create(HttpMethods.GET, relativePath)
                                   .AddHeader("Accept", "text/plain");

            return(await httpClient.ExecuteAsync(request, cancellationToken));
        }
Example #2
0
        /// <summary>
        /// 以文本的数据传递方式,异步执行一个 DELETE 请求。
        /// </summary>
        /// <param name="httpClient"></param>
        /// <param name="relativePath"></param>
        /// <param name="data"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <IHttpResponse> DeleteTextAsync(this IHttpClient httpClient, string relativePath, string data = null, CancellationToken cancellationToken = default)
        {
            IHttpRequest request = httpClient
                                   .Create(HttpMethods.DELETE, relativePath)
                                   .AddHeader("Accept", "text/plain")
                                   .AddHeader("Content-Type", "text/plain")
                                   .SetBody(data);

            return(await httpClient.ExecuteAsync(request, cancellationToken));
        }
Example #3
0
        /// <summary>
        /// 以 XML 的数据传递方式,异步执行一个 PUT 请求。
        /// </summary>
        /// <param name="httpClient"></param>
        /// <param name="relativePath"></param>
        /// <param name="data"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <IHttpResponse> PutXmlAsync(this IHttpClient httpClient, string relativePath, object data = null, CancellationToken cancellationToken = default)
        {
            IHttpRequest request = httpClient
                                   .Create(HttpMethods.PUT, relativePath)
                                   .AddHeader("Accept", "application/xml")
                                   .AddHeader("Content-Type", "application/xml")
                                   .SetBody(SerializeObjectToXML(data));

            return(await httpClient.ExecuteAsync(request, cancellationToken));
        }
        /// <summary>
        /// 以 JSON 的数据传递方式,异步执行一个 PATCH 请求。
        /// </summary>
        /// <param name="httpClient"></param>
        /// <param name="relativePath"></param>
        /// <param name="data"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <IHttpResponse> PatchJsonAsync(this IHttpClient httpClient, string relativePath, object data = null, CancellationToken cancellationToken = default)
        {
            IHttpRequest request = httpClient
                                   .Create(HttpMethods.PATCH, relativePath)
                                   .AddHeader("Accept", "application/json")
                                   .AddHeader("Content-Type", "application/json")
                                   .SetJsonBody(data);

            return(await httpClient.ExecuteAsync(request, cancellationToken));
        }
Example #5
0
        public async Task HttpGetTest()
        {
            using (IHttpClient httpClient = GetHttpClient())
            {
                IHttpResponse response = await httpClient.GetTextAsync("search?q=hello+world");

                Assert.Equal(200, response.StatusCode);
            }

            using (IHttpClient httpClient = GetHttpClient())
            {
                IHttpRequest request = httpClient
                                       .Create(HttpMethods.GET, "search")
                                       .AddQueryString("q", "hello world");
                IHttpResponse response = await httpClient.ExecuteAsync(request);

                Assert.Equal(200, response.StatusCode);
            }
        }
        /// <summary>
        /// 基于指定策略执行指定的 HTTP 请求。
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="httpClient"></param>
        /// <param name="httpRequest">HTTP 请求。</param>
        /// <param name="policy">策略。</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="HttpRequestException"></exception>
        /// <exception cref="HttpTimeoutException"></exception>
        public static async Task <IHttpResponse> ExecuteAsync <TResponse>(this IHttpClient httpClient, IHttpRequest httpRequest, IAsyncPolicy <TResponse> policy, CancellationToken cancellationToken = default(CancellationToken))
            where TResponse : class, IHttpResponse
        {
            if (httpRequest == null)
            {
                throw new ArgumentNullException(nameof(httpRequest));
            }
            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            void Clone(IHttpRequest src, ref IHttpRequest dest)
            {
                dest.Method = src.Method;

                dest.Credentials = src.Credentials;

                if (src.RequestUri == null)
                {
                    dest.RequestUri = null;
                }
                else
                {
                    dest.RequestUri = new Uri(src.RequestUri.ToString(), src.RequestUri.IsAbsoluteUri ? UriKind.Absolute : UriKind.RelativeOrAbsolute);
                }

                if (src.Body == null)
                {
                    src.SetBody(string.Empty);
                }
                else
                {
                    int len = src.Body.Length;
                    dest.Body = new byte[len];
                    Buffer.BlockCopy(src.Body, 0, dest.Body, 0, len);
                }

                dest.Headers.Clear();
                foreach (HttpHeader header in src.Headers)
                {
                    dest.Headers.Add(header);
                }
            }

            IHttpRequest httpRequestCopy = httpClient.Create(httpRequest.Method);

            try
            {
                return(await policy
                       .WrapAsync(Policy.TimeoutAsync(httpClient.Timeout))
                       .ExecuteAsync((innerCancellationToken) =>
                {
                    /*
                     * 使用浅表克隆的方式,以确保在重试策略下不对原始 IHttpRequest 对象造成污染。
                     */

                    Clone(httpRequest, ref httpRequestCopy);
                    return httpClient.ExecuteAsync(httpRequestCopy, innerCancellationToken) as Task <TResponse>;
                }, cancellationToken));
            }
            catch (Polly.Timeout.TimeoutRejectedException ex)
            {
                throw new HttpTimeoutException("Time out during retry.", ex);
            }
            catch (OperationCanceledException ex)
            {
                throw new HttpTimeoutException("Time out.", ex);
            }
            finally
            {
                Clone(httpRequestCopy, ref httpRequest);
            }
        }