/// <inheritdoc /> public async Task <FluentHttpResponse> Invoke(FluentHttpMiddlewareContext context) { var request = context.Request; var options = request.GetResponseCachingOptions(_options); if (options.ShouldIgnore || options.Matcher != null && !options.Matcher(request)) { return(await _next(context)); } var hash = request.GetHash(); FluentHttpResponse response = null; if (!options.IsWriteOnly) { response = await _service.Get(hash); } if (response != null) { foreach (var item in request.Items) { response.Items[item.Key] = item.Value; } _logger.LogInformation("Pre-request - Returning a cached response {hash}", hash); return(response); } response = await _next(context); _logger.LogInformation("Post-Response - Caching request... {hash}", hash); await _service.Set(hash, response); return(response); }
private static Exception GetV2Exception(IDictionary<string, object> json, FluentHttpResponse response) { GithubApiException exception; if (json.ContainsKey("error")) { exception = new GithubApiException((string)json["error"]); return exception; } return new NotImplementedException(); }
public async Task Set(string hash, FluentHttpResponse response) { var item = await _serializer.Serialize <HttpResponseEntity>(response); item.Id = await hash.ComputeHash(); await _dbContext.HttpResponses.AddAsync(item); await _dbContext.Commit(); await _cache.Set(item.Id, Task.FromResult(response)); }
public static Exception GetException(string responseString, GithubApiVersion version, FluentHttpResponse response, out object json) { try { json = JsonSerializer.Current.DeserializeObject(responseString); return version == GithubApiVersion.V3 ? GetV3Exception((IDictionary<string, object>)json, response) : GetV2Exception((IDictionary<string, object>)json, response); } catch (Exception ex) { json = null; return ex; } }
/// <summary> /// Run specified middleware, and finally send the given request. /// </summary> /// <param name="middlewareCollection">Middleware to pipe.</param> /// <param name="request">Request to send.</param> /// <param name="send">Actual send function.</param> /// <returns>Returns response.</returns> public async Task <FluentHttpResponse> Run(IList <MiddlewareConfig> middlewareCollection, FluentHttpRequest request, FluentHttpRequestDelegate send) { if (middlewareCollection.Count == 0) { return(await send(request)); } FluentHttpResponse httpResult = null; IFluentHttpMiddleware previousMiddleware = null; for (int i = middlewareCollection.Count; i-- > 0;) { request.CancellationToken.ThrowIfCancellationRequested(); var middlewareOptions = middlewareCollection[i]; var isLast = middlewareCollection.Count - 1 == i; var isFirst = i == 0; var next = isLast ? send : previousMiddleware.Invoke; object[] ctor; if (middlewareOptions.Args == null) { ctor = new object[] { next } } ; else { ctor = new object[middlewareOptions.Args.Length + 1]; ctor[0] = next; Array.Copy(middlewareOptions.Args, 0, ctor, 1, middlewareOptions.Args.Length); } var instance = (IFluentHttpMiddleware)ActivatorUtilities.CreateInstance(_serviceProvider, middlewareOptions.Type, ctor); if (isFirst) { httpResult = await instance.Invoke(request); } else { previousMiddleware = instance; } } return(httpResult); }
/// <summary> /// Deserialize back to response. /// </summary> /// <param name="item"></param> /// <returns></returns> public Task <FluentHttpResponse> Deserialize(IHttpResponseStore item) { var contentType = new ContentType(item.ContentHeaders.ContentType); var encoding = string.IsNullOrEmpty(contentType.CharSet) ? Encoding.UTF8 : Encoding.GetEncoding(contentType.CharSet); var cloned = new FluentHttpResponse(new HttpResponseMessage((HttpStatusCode)item.StatusCode) { Content = new StringContent(item.Content, encoding, contentType.MediaType), ReasonPhrase = item.ReasonPhrase, Version = new Version(item.Version), RequestMessage = item.RequestMessage, }); // todo: add items? cloned.Headers.AddRange(item.Headers); return(Task.FromResult(cloned)); }
/// <summary> /// Convert to a serializable object. /// </summary> /// <param name="response"></param> /// <returns></returns> public async Task <THttpResponseStore> Serialize <THttpResponseStore>(FluentHttpResponse response) where THttpResponseStore : IHttpResponseStore, new() { var message = new THttpResponseStore { Content = await response.Content.ReadAsStringAsync() }; message.ContentHeaders = new FluentHttpHeaders(response.Content.Headers); message.Hash = response.GetRequestHash(); message.ReasonPhrase = response.ReasonPhrase; message.StatusCode = (int)response.StatusCode; message.Url = response.Message.RequestMessage.RequestUri.ToString(); message.Version = response.Message.Version.ToString(); message.Headers = new FluentHttpHeaders(response.Headers); message.RequestMessage = response.Message.RequestMessage; message.RequestMessage.Content = null; // deserializing cause issues so clear it.. or else if we really need it we can separate to object and reconstruct it "manually" return(message); }
private static Exception GetV3Exception(IDictionary<string, object> json, FluentHttpResponse response) { if (json.ContainsKey("message")) { var message = (string)json["message"]; switch (response.HttpWebResponse.StatusCode) { case HttpStatusCode.NotFound: return new GithubApiNotFoundException(message); case HttpStatusCode.Unauthorized: return new GithubApiBadCredentialsException(message); default: return new GithubApiException(message); } } throw new ApplicationException("Invalid error message"); }
public Task Set(string hash, FluentHttpResponse response) { _cache.Set(hash, response); return(Task.CompletedTask); }