public async Task GetAnonymousValue()
        {
            using (var server = TestServer.Create<Startup>())
            {
                using (var flurlClient = new FlurlClient())
                {
                    flurlClient.Settings.HttpClientFactory = new OwinTestHttpClientFactory(server);

                    var response = await "http://localhost/api/values".WithClient(flurlClient).GetAsync().ReceiveString();
                    Assert.Equal("\"hello, world\"", response);
                    OutputWindow.WriteLine(response);
                }
            }
        }
        public async Task GetSecureValue()
        {
            using (var server = TestServer.Create<Startup>())
            {
                using (var flurlClient = new FlurlClient())
                {
                    string token = null;
                    try
                    {
                        flurlClient.Settings.HttpClientFactory = new OwinTestHttpClientFactory(server);

                        var tokenResponse = await "http://localhost/connect/token"
                            .WithClient(flurlClient)
                            .PostUrlEncodedAsync(new
                            {
                                grant_type = "password",
                                client_id = "client",
                                client_secret = "secret",
                                scope = "api",
                                username = "******",
                                password = "******"
                            })
                            .ReceiveJson();

                        token = tokenResponse.access_token as string;
                        OutputWindow.WriteLine(token);
                    }
                    catch (FlurlHttpException exception)
                    {
                        OutputWindow.WriteLine(
                            $"Failed with the http request to get the tokwn using flurl.\nException: {exception.Message}\nHttpStatusCode: {exception.Call.HttpStatus}\nMessage: {exception.GetResponseString()}");
                        if (exception.InnerException != null)
                        {
                            OutputWindow.WriteLine($"Inner Exception: {exception.InnerException.Message} ({exception.InnerException.GetType().Name})");
                            if (exception.InnerException.InnerException != null)
                                OutputWindow.WriteLine($"Inner Inner Exception: {exception.InnerException.InnerException.Message} ({exception.InnerException.InnerException.GetType().Name})");
                        }
                    }
                    try
                    {
                        var response = await "http://localhost/api/values/secure".WithClient(flurlClient).WithOAuthBearerToken(token)
                            .GetAsync();
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        OutputWindow.WriteLine(await response.Content.ReadAsStringAsync());

                    }
                    catch (FlurlHttpException exception)
                    {
                        OutputWindow.WriteLine(
                            $"Failed with the http request for the secure content using flurl.\nHttpStatusCode: {exception.Call.HttpStatus}\nMessage: {exception.GetResponseString()}");
                        throw;
                    }
                }
            }
        }
예제 #3
1
		public async Task autodispose_true_creates_new_httpclients() {
			var fc = new FlurlClient("http://www.mysite.com", true);
			var x = await fc.GetAsync();
			var y = await fc.GetAsync();
			var z = await fc.GetAsync();
			Assert.AreEqual(3, _fac.NewClientCount);
		}
예제 #4
0
		public void can_provide_custom_httpclient_factory() {
			FlurlHttp.Configuration.HttpClientFactory = new SomeCustomHttpClientFactory();
			var client = new FlurlClient("http://www.api.com");

			Assert.IsInstanceOf<SomeCustomHttpClient>(client.HttpClient);
			Assert.IsInstanceOf<SomeCustomMessageHandler>(client.HttpMessageHandler);
		}
예제 #5
0
		public async Task autodispose_false_resues_httpclient() {
			var fc = new FlurlClient("http://www.mysite.com", false);
			var x = await fc.GetAsync();
			var y = await fc.GetAsync();
			var z = await fc.GetAsync();
			Assert.AreEqual(1, _fac.NewClientCount);
		}
예제 #6
0
파일: Media.cs 프로젝트: hut8/Nimbus
        public Media()
        {
            _client = new FlurlClient()
                .EnableCookies()
                .WithHeader("User-Agent", UserAgent);

            CancelDownloadToken = new CancellationToken();
        }
예제 #7
0
        public void HelloIsHello()
        {
            var client = new FlurlClient();
            client.Url = "http://localhost:80/TestWeb_deploy/test";
            var response = client.GetAsync();
            response.Result.StatusCode.Should().Be(HttpStatusCode.OK);

        }
예제 #8
0
		/// <summary>
		/// Sets HTTP cookies based on property names/values of the provided object, or keys/values if object is a dictionary, to be sent with all requests made with this FlurlClient.
		/// </summary>
		/// <param name="cookies">Names/values of HTTP cookies to set. Typically an anonymous object or IDictionary.</param>
		/// <param name="expires">Expiration for all cookies (optional). If excluded, cookies only live for duration of session.</param>
		/// <returns>The modified FlurlClient.</returns>
		public static FlurlClient WithCookies(this FlurlClient client, object cookies, DateTime? expires = null) {
			if (cookies == null)
				return client;

			foreach (var kv in cookies.ToKeyValuePairs())
				client.WithCookie(kv.Key, kv.Value, expires);

			return client;
		}
예제 #9
0
        /// <summary>
        /// Returns a new FlurlClient where all state (HttpClient, etc) is shared but with a different URL.
        /// Allows you to re-use the underlying HttpClient instance (such as to share cookies, etc) with
        /// different URLs in a thread-safe way.
        /// </summary>
        /// <param name="url">The Url to call.</param>
        /// <returns></returns>
        public static FlurlClient WithUrl(this FlurlClient client, Url url)
        {
            var fc = client.Clone();

            fc.Url = url;
            // prevent the new client from automatically disposing the parent's HttpClient
            fc.AutoDispose = false;
            return(fc);
        }
예제 #10
0
        /// <summary>
        /// Sets an HTTP cookie to be sent with all requests made with this FlurlClient.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="name">cookie name.</param>
        /// <param name="value">cookie value.</param>
        /// <param name="expires">cookie expiration (optional). If excluded, cookie only lives for duration of session.</param>
        /// <returns>The modified FlurlClient.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
        public static FlurlClient WithCookie(this FlurlClient client, string name, object value, DateTime?expires = null)
        {
            var cookie = new Cookie(name, value?.ToInvariantString())
            {
                Expires = expires ?? DateTime.MinValue
            };

            return(client.WithCookie(cookie));
        }
예제 #11
0
		private static CookieContainer GetCookieContainer(FlurlClient client) {
			var handler = client.HttpMessageHandler as HttpClientHandler;
			if (handler == null)
				return null;

			if (client.HttpClient.BaseAddress == null)
				client.HttpClient.BaseAddress = new Uri(Url.GetRoot(client.Url));

			return handler.CookieContainer ?? (handler.CookieContainer = new CookieContainer());
		}
예제 #12
0
        private static CookieContainer GetCookieContainer(FlurlClient client)
        {
            var handler = client.HttpMessageHandler as HttpClientHandler;

            if (handler == null)
            {
                return(null);
            }

            return(handler.CookieContainer ?? (handler.CookieContainer = new CookieContainer()));
        }
예제 #13
0
        /// <summary>
        /// Gets a collection of cookies that will be sent in calls using this client. (Use FlurlClient.WithCookie/WithCookies to set cookies.)
        /// </summary>
        public static Dictionary <string, Cookie> GetCookies(this FlurlClient client)
        {
            var jar = GetCookieContainer(client);

            if (jar == null)
            {
                return(null);
            }

            var uri = new Uri(Url.GetRoot(client.Url));

            return(jar.GetCookies(uri).Cast <Cookie>().ToDictionary(c => c.Name, c => c));
        }
예제 #14
0
        /// <summary>
        /// Sets HTTP headers based on property names/values of the provided object, or keys/values if object is a dictionary, to be sent with all requests made with this FlurlClient.
        /// </summary>
        /// <param name="headers">Names/values of HTTP headers to set. Typically an anonymous object or IDictionary.</param>
        /// <returns>The modified FlurlClient.</returns>
        public static FlurlClient WithHeaders(this FlurlClient client, object headers)
        {
            if (headers == null)
            {
                return(client);
            }

            foreach (var kv in headers.ToKeyValuePairs())
            {
                client.HttpClient.DefaultRequestHeaders.Add(kv.Key, new[] { kv.Value });
            }

            return(client);
        }
예제 #15
0
		public async Task can_persist_cookies() {
			using (var fc = new FlurlClient()) {
				"http://httpbin.org/cookies".WithClient(fc).WithCookie("z", 999);
				// cookie should be set
				Assert.AreEqual("999", fc.GetCookies()["z"].Value);

				await fc.HeadAsync();
				// FlurlClient should be re-used, so cookie should stick
				Assert.AreEqual("999", fc.GetCookies()["z"].Value);

				// httpbin returns json representation of cookies that were set on the server.
				var resp = await "http://httpbin.org/cookies".WithClient(fc).GetJsonAsync();
				Assert.AreEqual("999", resp.cookies.z);
			}
		}
예제 #16
0
 /// <summary>
 /// Adds a pattern representing an HTTP status code or range of codes which (in addtion to 2xx) will NOT result in a FlurlHttpException being thrown.
 /// </summary>
 /// <param name="pattern">Examples: "3xx", "100,300,600", "100-299,6xx"</param>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient AllowHttpStatus(this FlurlClient client, string pattern)
 {
     if (!string.IsNullOrWhiteSpace(pattern))
     {
         var current = client.Settings.AllowedHttpStatusRange;
         if (string.IsNullOrWhiteSpace(current))
         {
             client.Settings.AllowedHttpStatusRange = pattern;
         }
         else
         {
             client.Settings.AllowedHttpStatusRange += "," + pattern;
         }
     }
     return(client);
 }
예제 #17
0
        public static Task <T> RequestJsonAsync <T>(this FlurlClient client, object request, CancellationToken cancellationToken = default(CancellationToken), HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead)
        {
            var attributes = request.GetType().GetCustomAttributes(typeof(RequestRouteAttribute), false);

            if (attributes != null && attributes.Any())
            {
                var requestRoute = attributes.First() as RequestRouteAttribute;
                switch (requestRoute.Method.ToLower())
                {
                case "get":
                    return(client.GetJsonAsync <T>(requestRoute.RouteTemplate, request, cancellationToken, completionOption));

                default:
                    return(client.PostJsonAsync <T>(requestRoute.RouteTemplate, request, cancellationToken, completionOption));
                }
            }
            else
            {
                throw new ArgumentException("Request dto must have RequestRoute attribute to use with SendAsync.");
            }
        }
        /// <summary>
        ///     Constructor.
        /// </summary>
        /// <param name="authUrl">The base auth URL (scheme and host) for the service.</param>
        /// <param name="apiUrl">The base API URL (scheme and host) for the service.</param>
        /// <param name="existingState">Any existing state from a previous session.</param>
        /// <param name="handlerFactory">A delegate to create the http handler factory.</param>
        public AltitudeAngelClient(
            string authUrl,
            string apiUrl,
            AuthorizationState existingState,
            AltitudeAngelHttpHandlerFactory.Create handlerFactory
            )
        {
            _authUrl = authUrl;
            _apiUrl = apiUrl;
            _handlerFactory = handlerFactory(authUrl, existingState);
            _client = new FlurlClient
            {
                Settings =
                {
                    HttpClientFactory = _handlerFactory
                },
                AutoDispose = false
            };

            _disposer.Add(_client);
        }
예제 #19
0
        /// <summary>
        /// Asynchronously downloads a file at the specified URL.
        /// </summary>
        /// <param name="localFolderPath">Path of local folder where file is to be downloaded.</param>
        /// <param name="localFileName">Name of local file. If not specified, the source filename (last segment of the URL) is used.</param>
        /// <param name="bufferSize">Buffer size in bytes. Default is 4096.</param>
        /// <returns>A Task whose result is the local path of the downloaded file.</returns>
        public static async Task <string> DownloadFileAsync(this FlurlClient client, string localFolderPath, string localFileName = null, int bufferSize = 4096)
        {
            if (localFileName == null)
            {
                localFileName = client.Url.Path.Split('/').Last();
            }

            var folder = await EnsureFolderAsync(localFolderPath);

            var file = await folder.CreateFileAsync(localFileName, CreationCollisionOption.ReplaceExisting);

            // http://developer.greenbutton.com/downloading-large-files-with-the-net-httpclient
            var response = await client.HttpClient.GetAsync(client.Url, HttpCompletionOption.ResponseHeadersRead);

            // http://codereview.stackexchange.com/a/18679
            using (var httpStream = await response.Content.ReadAsStreamAsync())
                using (var fileStream = await file.OpenAsync(FileAccess.ReadAndWrite)) {
                    await httpStream.CopyToAsync(fileStream, bufferSize);
                }

            return(PortablePath.Combine(localFolderPath, localFileName));
        }
예제 #20
0
        /// <summary>
        /// Asynchronously downloads a file at the specified URL.
        /// </summary>
        /// <param name="localFolderPath">Path of local folder where file is to be downloaded.</param>
        /// <param name="localFileName">Name of local file. If not specified, the source filename (last segment of the URL) is used.</param>
        /// <param name="bufferSize">Buffer size in bytes. Default is 4096.</param>
        /// <returns>A Task whose result is the local path of the downloaded file.</returns>
        public static async Task <string> DownloadFileAsync(this FlurlClient client, string localFolderPath, string localFileName = null, int bufferSize = 4096)
        {
            if (localFileName == null)
            {
                localFileName = client.Url.Path.Split('/').Last();
            }

            if (!Directory.Exists(localFolderPath))
            {
                Directory.CreateDirectory(localFolderPath);
            }

            var filePath = Path.Combine(localFolderPath, localFileName);

            // need to temporarily disable autodispose if set, otherwise reading from stream will fail
            var autoDispose = client.AutoDispose;

            client.AutoDispose = false;

            try {
                var response = await client.SendAsync(HttpMethod.Get, completionOption : HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);

                // http://codereview.stackexchange.com/a/18679
                using (var httpStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var filestream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true)) {
                        await httpStream.CopyToAsync(filestream, bufferSize).ConfigureAwait(false);
                    }

                return(filePath);
            }
            finally {
                client.AutoDispose = autoDispose;
                if (client.AutoDispose)
                {
                    client.Dispose();
                }
            }
        }
예제 #21
0
 /// <summary>
 /// Sets the client timout to the specified timespan.
 /// </summary>
 /// <param name="timespan">Time to wait before the request times out.</param>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient WithTimeout(this FlurlClient client, TimeSpan timespan)
 {
     client.HttpClient.Timeout = timespan;
     return(client);
 }
예제 #22
0
 /// <summary>
 /// Sends an asynchronous POST request of specified data (usually an anonymous object or dictionary) serialized as URL-encoded key/value pair (simulating a form post).
 /// </summary>
 /// <param name="data">Data to be serialized and posted.</param>
 /// <returns>A Task whose result is the received HttpResponseMessage.</returns>
 public static Task <HttpResponseMessage> PostUrlEncodedAsync(this FlurlClient client, object data)
 {
     return(client.HttpClient.PostAsync(client.Url, new CapturedFormUrlEncodedContent(data)));
 }
예제 #23
0
 /// <summary>
 /// Sends an asynchronous PUT request of specified data (usually an anonymous object or dictionary) formatted as JSON.
 /// </summary>
 /// <param name="data">Data to be serialized and putted.</param>
 /// <returns>A Task whose result is the received HttpResponseMessage.</returns>
 public static Task <HttpResponseMessage> PutJsonAsync(this FlurlClient client, object data)
 {
     return(client.HttpClient.PutAsync(client.Url, new CapturedJsonContent(data)));
 }
예제 #24
0
 /// <summary>
 /// Sends an asynchronous GET request and deserializes the JSON-formatted response body to an object of type T.
 /// </summary>
 /// <typeparam name="T">A type whose structure matches the expected JSON response.</typeparam>
 /// <returns>A Task whose result is an object containing data in the response body.</returns>
 public static Task <T> GetJsonAsync <T>(this FlurlClient client)
 {
     return(client.GetAsync().ReceiveJson <T>());
 }
예제 #25
0
        /// <summary>
        /// Adds an <see cref="HttpStatusCode"/> which (in addtion to 2xx) will NOT result in a FlurlHttpException being thrown.
        /// </summary>
        /// <param name="statusCodes">Examples: HttpStatusCode.NotFound</param>
        /// <returns>The modified FlurlClient.</returns>
        public static FlurlClient AllowHttpStatus(this FlurlClient client, params HttpStatusCode[] statusCodes)
        {
            var pattern = string.Join(",", statusCodes.Select(c => (int)c));

            return(AllowHttpStatus(client, pattern));
        }
예제 #26
0
 /// <summary>
 /// Sets HTTP authorization header with acquired bearer token according to OAuth 2.0 specification to be sent with all requests made with this FlurlClient.
 /// </summary>
 /// <param name="token">The acquired bearer token to pass.</param>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient WithOAuthBearerToken(this FlurlClient client, string token)
 {
     client.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
     return(client);
 }
예제 #27
0
 /// <summary>
 /// Prevents a FlurlHttpException from being thrown on any completed response, regardless of the HTTP status code.
 /// </summary>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient AllowAnyHttpStatus(this FlurlClient client)
 {
     client.AllowedHttpStatusRanges.Clear();
     client.AllowedHttpStatusRanges.Add("*");
     return(client);
 }
예제 #28
0
 /// <summary>
 /// Adds a pattern representing an HTTP status code or range of codes which (in addtion to 2xx) will NOT result in a FlurlHttpException being thrown.
 /// </summary>
 /// <param name="pattern">Examples: "3xx", "100,300,600", "100-299,6xx"</param>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient AllowHttpStatus(this FlurlClient client, string pattern)
 {
     client.AllowedHttpStatusRanges.Add(pattern);
     return(client);
 }
예제 #29
0
		private static CookieContainer GetCookieContainer(FlurlClient client) {
			var handler = client.HttpMessageHandler as HttpClientHandler;
			if (handler == null)
				return null;

			return handler.CookieContainer ?? (handler.CookieContainer = new CookieContainer());
		}
예제 #30
0
 /// <summary>
 /// Sends an asynchronous GET request and deserializes the JSON-formatted response body to a list of dynamic objects.
 /// </summary>
 /// <returns>A Task whose result is a list of dynamic objects containing data in the response body.</returns>
 public static Task <IList <dynamic> > GetJsonListAsync(this FlurlClient client)
 {
     return(client.GetAsync().ReceiveJsonList());
 }
예제 #31
0
 /// <summary>
 /// Sets the client timout to the specified number of seconds.
 /// </summary>
 /// <param name="seconds">Number of seconds to wait before the request times out.</param>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient WithTimeout(this FlurlClient client, int seconds)
 {
     return(client.WithTimeout(TimeSpan.FromSeconds(seconds)));
 }
예제 #32
0
 /// <summary>
 /// Fluently specify that an existing FlurlClient should be used to call the Url, rather than creating a new one.
 /// Enables re-using the underlying HttpClient.
 /// </summary>
 /// <param name="client">The FlurlClient to use in calling the Url</param>
 /// <returns></returns>
 public static FlurlClient WithClient(this string url, FlurlClient client)
 {
     return(client.WithUrl(url));
 }
예제 #33
0
 /// <summary>
 /// Provides access to modifying the underlying HttpClient.
 /// </summary>
 /// <param name="action">Action to perform on the HttpClient.</param>
 /// <returns>The FlurlClient with the modified HttpClient</returns>
 public static FlurlClient ConfigureHttpClient(this FlurlClient client, Action <HttpClient> action)
 {
     action(client.HttpClient);
     return(client);
 }
예제 #34
0
		public async Task client_can_override_global_settings() {
			var overridden = false;
			using (new HttpTest()) {
				FlurlHttp.GlobalSettings.AfterCall = _ => overridden = false;
				var fc = new FlurlClient("http://www.api.com");
				fc.Settings.AfterCall = _ => overridden = true;
				await fc.GetAsync();
				Assert.True(overridden);
			}
		}
예제 #35
0
 /// <summary>
 /// Sets an HTTP cookie to be sent with all requests made with this FlurlClient.
 /// </summary>
 /// <param name="client">The client.</param>
 /// <param name="cookie">The cookie to set.</param>
 /// <returns>The modified FlurlClient.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="cookie" /> is null.</exception>
 public static FlurlClient WithCookie(this FlurlClient client, Cookie cookie)
 {
     client.Settings.CookiesEnabled = true;
     client.Cookies[cookie.Name]    = cookie;
     return(client);
 }
예제 #36
0
 /// <summary>
 /// Fluently specify that an existing FlurlClient should be used to call the Url, rather than creating a new one.
 /// Enables re-using the underlying HttpClient.
 /// </summary>
 /// <param name="fc">The FlurlClient to use in calling the Url</param>
 /// <returns></returns>
 public static FlurlClient WithClient(this Url url, FlurlClient fc)
 {
     fc.Url = url;
     return fc;
 }
예제 #37
0
 /// <summary>
 /// Prevents a FlurlHttpException from being thrown on any completed response, regardless of the HTTP status code.
 /// </summary>
 /// <returns>The modified FlurlClient.</returns>
 public static FlurlClient AllowAnyHttpStatus(this FlurlClient client)
 {
     client.Settings.AllowedHttpStatusRange = "*";
     return(client);
 }
예제 #38
0
		public void ResetDefaults() {
			GetSettings().ResetDefaults();
			_client = null;
		}
예제 #39
0
 /// <summary>
 /// Change FlurlHttpSettings for this client instance.
 /// </summary>
 /// <param name="action">Action defining the settings changes.</param>
 /// <returns>The FlurlClient with the modified HttpClient</returns>
 public static FlurlClient ConfigureClient(this FlurlClient client, Action <FlurlHttpSettings> action)
 {
     action(client.Settings);
     return(client);
 }
예제 #40
0
 /// <summary>
 /// Fluently specify that an existing FlurlClient should be used to call the Url, rather than creating a new one.
 /// Enables re-using the underlying HttpClient.
 /// </summary>
 /// <param name="fc">The FlurlClient to use in calling the Url</param>
 /// <returns></returns>
 public static FlurlClient WithClient(this string url, FlurlClient fc)
 {
     return new Url(url).WithClient(fc);
 }
예제 #41
0
 /// <summary>
 /// Allows cookies to be sent and received in calls made with this client. Not necessary to call when setting cookies via WithCookie/WithCookies.
 /// </summary>
 public static FlurlClient EnableCookies(this FlurlClient client)
 {
     client.Settings.CookiesEnabled = true;
     return(client);
 }
예제 #42
0
 /// <summary>
 /// Fluently specify that an existing FlurlClient should be used to call the Url, rather than creating a new one.
 /// Enables re-using the underlying HttpClient.
 /// </summary>
 /// <param name="fc">The FlurlClient to use in calling the Url</param>
 /// <returns></returns>
 public static FlurlClient WithClient(this Url url, FlurlClient fc)
 {
     fc.Url = url;
     return(fc);
 }
예제 #43
0
 /// <summary>
 /// Fluently specify that an existing FlurlClient should be used to call the Url, rather than creating a new one.
 /// Enables re-using the underlying HttpClient.
 /// </summary>
 /// <param name="fc">The FlurlClient to use in calling the Url</param>
 /// <returns></returns>
 public static FlurlClient WithClient(this string url, FlurlClient fc)
 {
     return(new Url(url).WithClient(fc));
 }
예제 #44
0
 /// <summary>
 /// Fluently specify the URL to be called with the current FlurlClient instance.
 /// </summary>
 /// <param name="url">The Url to call.</param>
 /// <returns></returns>
 public static FlurlClient WithUrl(this FlurlClient client, Url url)
 {
     client.Url = url;
     return(client);
 }
예제 #45
0
 public static FlurlClient Authenticate(this Url url, IAuthenticationProvider authenticationProvider)
 {
     var client = new FlurlClient(url, autoDispose: true);
     return client.Authenticate(authenticationProvider);
 }
예제 #46
0
		protected FlurlClient GetClient() {
			if (_client == null)
				_client = new FlurlClient("http://www.api.com");
			return _client;
		}