Пример #1
0
        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()}"
                              );
                    }
                }
            }
        }
Пример #2
0
 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));
        }
Пример #5
0
        // 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));
        }
Пример #6
0
 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))) { }
     }
 }
Пример #7
0
        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));
        }
Пример #8
0
        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)));
        }
Пример #9
0
        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}'.");
        }
Пример #10
0
        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;
        }
Пример #11
0
        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))));
        }
Пример #12
0
        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();
            }
        }