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; } } } }
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); }
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); }
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); }
public Media() { _client = new FlurlClient() .EnableCookies() .WithHeader("User-Agent", UserAgent); CancelDownloadToken = new CancellationToken(); }
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); }
/// <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; }
/// <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); }
/// <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)); }
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()); }
private static CookieContainer GetCookieContainer(FlurlClient client) { var handler = client.HttpMessageHandler as HttpClientHandler; if (handler == null) { return(null); } return(handler.CookieContainer ?? (handler.CookieContainer = new CookieContainer())); }
/// <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)); }
/// <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); }
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); } }
/// <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); }
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); }
/// <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)); }
/// <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(); } } }
/// <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); }
/// <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))); }
/// <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))); }
/// <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>()); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
private static CookieContainer GetCookieContainer(FlurlClient client) { var handler = client.HttpMessageHandler as HttpClientHandler; if (handler == null) return null; return handler.CookieContainer ?? (handler.CookieContainer = new CookieContainer()); }
/// <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()); }
/// <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))); }
/// <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)); }
/// <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); }
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); } }
/// <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); }
/// <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; }
/// <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); }
public void ResetDefaults() { GetSettings().ResetDefaults(); _client = null; }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
public static FlurlClient Authenticate(this Url url, IAuthenticationProvider authenticationProvider) { var client = new FlurlClient(url, autoDispose: true); return client.Authenticate(authenticationProvider); }
protected FlurlClient GetClient() { if (_client == null) _client = new FlurlClient("http://www.api.com"); return _client; }