private async Task <(Stream Content, string MimeType)> InvokeAsync(UriString uri, HttpMethod method, IImmutableSession metadata) { using (var request = new HttpRequestMessage(method, uri)) { var content = metadata.Get(Use <IHttpNamespace> .Namespace, x => x.Content); if (content != null) { request.Content = new StreamContent(content.Rewind()); request.Content.Headers.ContentType = new MediaTypeHeaderValue(metadata.Get(Use <IHttpNamespace> .Namespace, x => x.ContentType)); } Metadata.Get(Use <IHttpNamespace> .Namespace, x => x.ConfigureRequestHeaders, _ => { })(request.Headers); metadata.Get(Use <IHttpNamespace> .Namespace, x => x.ConfigureRequestHeaders)(request.Headers); using (var response = await _client.SendAsync(request, HttpCompletionOption.ResponseContentRead, metadata.Get(Use <IAnyNamespace> .Namespace, x => x.CancellationToken))) { var responseContentCopy = new MemoryStream(); if (response.Content.Headers.ContentLength > 0) { await response.Content.CopyToAsync(responseContentCopy); } var clientErrorClass = new Range <int>(400, 499); var serverErrorClass = new Range <int>(500, 599); var classOfStatusCode = clientErrorClass.ContainsInclusive((int)response.StatusCode) ? "Client" : serverErrorClass.ContainsInclusive((int)response.StatusCode) ? "Server" : null; if (classOfStatusCode is null) { return(responseContentCopy, response.Content.Headers.ContentType.MediaType); } using (var responseReader = new StreamReader(responseContentCopy.Rewind())) { throw DynamicException.Create ( classOfStatusCode, $"StatusCode: {(int)response.StatusCode} ({response.StatusCode}){Environment.NewLine}{await responseReader.ReadToEndAsync()}" ); } } } }
protected async Task <string> ReadBodyAsync(Stream value, IImmutableSession metadata) { using (var bodyReader = new StreamReader(value, metadata.Get(Use <IMailNamespace> .Namespace, x => x.BodyEncoding, Encoding.UTF8))) { return(await bodyReader.ReadToEndAsync()); } }
public static IImmutableSession WithReferences(this IImmutableSession context, IEnumerable <IExpression> expressions) { var registrations = context .Get(Expression.Namespace, x => x.References, ImmutableDictionary <SoftString, IExpression> .Empty) .SetItems(expressions.Select(e => new KeyValuePair <SoftString, IExpression>($"R.{e.Name.ToString()}", e))); return(context.Set(Expression.Namespace, x => x.References, registrations)); }
public static IImmutableSession WithComparer(this IImmutableSession context, string name, IEqualityComparer <object> comparer) { var comparers = context .Get(Expression.Namespace, x => x.Comparers, ImmutableDictionary <SoftString, IEqualityComparer <object> > .Empty) .SetItem(name, comparer); return(context.Set(Expression.Namespace, x => x.Comparers, comparers)); }
// protected override Task<IResourceInfo> PostAsyncInternal(UriString uri, Stream value, ResourceMetadata metadata) // { // ValidateFormatNotNull(this, uri, metadata); // // //var resource = new InMemoryResourceInfo(uri, metadata.Format(), value); // //_items.Remove(resource); // //_items.Add(resource); // //return Task.FromResult<IResourceInfo>(resource); // } protected override async Task <IResourceInfo> PutAsyncInternal(UriString uri, Stream value, IImmutableSession metadata) { //ValidateFormatNotNull(this, uri, metadata); var name = _uriConverter.Convert <string>(uri); _items[name] = await ResourceHelper.Deserialize <object>(value, metadata); return(new InMemoryResourceInfo(uri, metadata.Get(Use <IResourceNamespace> .Namespace, y => y.Format), value)); }
public static async Task SetItemAsync(this IResourceProvider resources, UriString uri, object value, IImmutableSession metadata) { if (metadata.Get(Use <IResourceNamespace> .Namespace, x => x.Type) == typeof(string)) { using (var stream = await ResourceHelper.SerializeTextAsync((string)value)) using (await resources.PutAsync(uri, stream, metadata.Set(Use <IResourceNamespace> .Namespace, x => x.Format, MimeType.Text))) { } } else { using (var stream = await ResourceHelper.SerializeBinaryAsync(value)) using (await resources.PutAsync(uri, stream, metadata.Set(Use <IResourceNamespace> .Namespace, x => x.Format, MimeType.Binary))) { } } }
protected override async Task <IResourceInfo> PostAsyncInternal(UriString uri, Stream value, IImmutableSession session) { var message = new MimeMessage(); message.From.Add(new MailboxAddress(session.Get(Use <IMailNamespace> .Namespace, x => x.From))); message.To.AddRange(session.Get(Use <IMailNamespace> .Namespace, x => x.To).Where(Conditional.IsNotNullOrEmpty).Select(x => new MailboxAddress(x))); message.Cc.AddRange(session.Get(Use <IMailNamespace> .Namespace, x => x.CC, Enumerable.Empty <string>().ToList()).Where(Conditional.IsNotNullOrEmpty).Select(x => new MailboxAddress(x))); message.Subject = session.Get(Use <IMailNamespace> .Namespace, x => x.Subject); var multipart = new Multipart("mixed") { new TextPart(session.Get(Use <IMailNamespace> .Namespace, x => x.IsHtml) ? TextFormat.Html : TextFormat.Plain) { Text = await ReadBodyAsync(value, session) } }; foreach (var attachment in session.Get(Use <IMailNamespace> .Namespace, x => x.Attachments, new Dictionary <string, byte[]>()).Where(i => i.Key.IsNotNullOrEmpty() && i.Value.IsNotNull())) { var attachmentPart = new MimePart(MediaTypeNames.Application.Octet) { Content = new MimeContent(new MemoryStream(attachment.Value).Rewind()), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = attachment.Key }; multipart.Add(attachmentPart); } message.Body = multipart; using (var smtpClient = new SmtpClient()) { await smtpClient.ConnectAsync ( session.Get(Use <ISmtpNamespace> .Namespace, x => x.Host), session.Get(Use <ISmtpNamespace> .Namespace, x => x.Port), session.Get(Use <ISmtpNamespace> .Namespace, x => x.UseSsl, false) ); await smtpClient.SendAsync(message); } return(new InMemoryResourceInfo(uri, session)); }
protected override Task <IResourceInfo> GetAsyncInternal(UriString uri, IImmutableSession metadata) { //ValidateFormatNotNull(this, uri, metadata); // Embedded resource names are separated by '.' so replace the windows separator. var fullUri = BaseUri + uri; var fullName = fullUri.Path.Decoded.ToString().Replace('/', '.'); // Embedded resource names are case sensitive so find the actual name of the resource. var actualName = _assembly.GetManifestResourceNames().FirstOrDefault(name => SoftString.Comparer.Equals(name, fullName)); var getManifestResourceStream = actualName is null ? default(Func <Stream>) : () => _assembly.GetManifestResourceStream(actualName); return(Task.FromResult <IResourceInfo>(new EmbeddedFileInfo(fullUri, metadata.Get(Use <IResourceNamespace> .Namespace, y => y.Format), getManifestResourceStream))); }
public static async Task <T> Deserialize <T>(Stream value, IImmutableSession metadata) { var format = metadata.Get(Use <IResourceNamespace> .Namespace, x => x.Format); if (format == MimeType.Text) { return((T)(object) await DeserializeTextAsync(value)); } if (format == MimeType.Binary) { return((T) await DeserializeBinaryAsync <object>(value)); } throw DynamicException.Create("Format", $"Unsupported value format: '{format}'."); }
protected ResourceProvider([NotNull] IEnumerable <SoftString> schemes, IImmutableSession metadata) { if (schemes == null) { throw new ArgumentNullException(nameof(schemes)); } //var metadata = Metadata.Empty; // If this is a decorator then the decorated resource-provider already has set this. if (metadata.Get(Use <IProviderNamespace> .Namespace, x => x.DefaultName) is var df && !df) { metadata = metadata.Set(Use <IProviderNamespace> .Namespace, x => x.DefaultName, GetType().ToPrettyString()); } if ((Schemes = schemes.ToImmutableHashSet()).Empty()) { throw new ArgumentException(paramName: nameof(metadata), message: $"{nameof(schemes)} must not be empty."); } Metadata = metadata; }
protected override Task <IResourceInfo> GetAsyncInternal(UriString uri, IImmutableSession metadata) { ValidateRequest(ExtractMethodName(nameof(GetAsync)), uri, metadata, Stream.Null, RequestValidator); return(Task.FromResult <IResourceInfo>(new PhysicalFileInfo(uri, metadata.Get(Use <IResourceNamespace> .Namespace, y => y.Format)))); }
private async Task <IResourceInfo> HandleMethodAsync(UriString uri, IImmutableSession metadata, bool isGet, Func <IResourceProvider, Task <IResourceInfo> > handleAsync) { var cacheKey = uri.Path.Decoded; await _cacheLock.WaitAsync(); try { // Used cached provider if already resolved. if (_cache.TryGetValue(cacheKey, out var cached)) { return(await handleAsync(cached)); } var resourceProviders = _resourceProviders.ToList(); // Use custom-provider-name if available which has the highest priority. if (metadata.Get(Use <IProviderNamespace> .Namespace, x => x.CustomName) is var customName && customName) { var match = resourceProviders .Where(p => p.CustomName?.Equals(customName) == true) // There must be exactly one provider with that name. .SingleOrThrow ( onEmpty: () => DynamicException.Create ( "ProviderNotFound", $"Could not find any provider that would match the name '{(string)customName}'." ), onMultiple: () => DynamicException.Create ( "MultipleProvidersFound", $"There is more than one provider that matches the custom name '{(string)customName}'." ) ); _cache[cacheKey] = match; return(await handleAsync(match)); } // Multiple providers can have the same default name. if (metadata.Get(Use <IProviderNamespace> .Namespace, x => x.DefaultName) is var defaultName && defaultName) { resourceProviders = resourceProviders .Where(p => p.DefaultName.Equals(defaultName)) .ToList(); if (resourceProviders.Empty()) { throw DynamicException.Create ( "ProviderNotFound", $"Could not find any provider that would match the name default name '{(string)defaultName}'." ); } } // Check if there is a provider that matches the scheme of the absolute uri. if (uri.IsAbsolute) { var ignoreScheme = uri.Scheme == DefaultScheme; resourceProviders = ignoreScheme ? resourceProviders : resourceProviders.Where(p => p.Schemes.Contains(DefaultScheme) || p.Schemes.Contains(uri.Scheme)).ToList(); if (resourceProviders.Empty()) { throw DynamicException.Create ( $"ProviderNotFound", $"Could not find any provider that would match any of the schemes [{metadata.Get(Use<IAnyNamespace>.Namespace, x => x.Schemes).Select(x => (string)x).Join(",")}]." ); } } // GET can search multiple providers. if (isGet) { var resource = default(IResourceInfo); foreach (var resourceProvider in resourceProviders) { resource = await handleAsync(resourceProvider); if (resource.Exists) { _cache[cacheKey] = resourceProvider; return(resource); } } return(new InMemoryResourceInfo(uri, resource?.Metadata ?? ImmutableSession.Empty)); } // Other methods are allowed to use only a single provider. else { var match = _cache[uri.Path.Decoded] = resourceProviders.Single(); return(await handleAsync(match)); } } finally { _cacheLock.Release(); } }