예제 #1
0
        public void ToDispose(ByteStringContext.InternalScope obj)
        {
            if (_garbage == null)
            {
                _garbage = new List <ByteStringContext.InternalScope>();
            }

            _garbage.Add(obj);
        }
예제 #2
0
        public MapReduceResultsStore(ulong reduceKeyHash, MapResultsStorageType type, TransactionOperationContext indexContext, MapReduceIndexingContext mapReduceContext, bool create)
        {
            _reduceKeyHash    = reduceKeyHash;
            Type              = type;
            _indexContext     = indexContext;
            _mapReduceContext = mapReduceContext;
            _tx = indexContext.Transaction.InnerTransaction;

            switch (Type)
            {
            case MapResultsStorageType.Tree:
                InitializeTree(create);
                break;

            case MapResultsStorageType.Nested:
                _nestedValueKeyScope = Slice.From(indexContext.Allocator, NestedValuesPrefix + reduceKeyHash, ByteStringType.Immutable, out _nestedValueKey);
                break;

            default:
                throw new ArgumentOutOfRangeException(Type.ToString());
            }
        }
예제 #3
0
        private async Task GetAttachment(bool isDocument)
        {
            var documentId = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id");
            var name       = GetQueryStringValueAndAssertIfSingleAndNotEmpty("name");

            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                using (context.OpenReadTransaction())
                {
                    var   type = AttachmentType.Document;
                    Slice cv;
                    ByteStringContext.InternalScope disposeCv = default(ByteStringContext.InternalScope);
                    if (isDocument == false)
                    {
                        var stream  = TryGetRequestFromStream("ChangeVectorAndType") ?? RequestBodyStream();
                        var request = context.Read(stream, "GetAttachment");

                        if (request.TryGet("Type", out string typeString) == false ||
                            Enum.TryParse(typeString, out type) == false)
                        {
                            throw new ArgumentException("The 'Type' field in the body request is mandatory");
                        }

                        if (request.TryGet("ChangeVector", out string changeVector) == false && changeVector != null)
                        {
                            throw new ArgumentException("The 'ChangeVector' field in the body request is mandatory");
                        }
                        disposeCv = Slice.From(context.Allocator, changeVector, out cv);
                    }
                    else
                    {
                        cv = Slices.Empty;
                    }

                    Attachment attachment;
                    using (disposeCv)
                        attachment = Database.DocumentsStorage.AttachmentsStorage.GetAttachment(context, documentId, name, type, cv);
                    if (attachment == null)
                    {
                        HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }

                    var attachmentChangeVector = GetStringFromHeaders("If-None-Match");
                    if (attachmentChangeVector == attachment.ChangeVector)
                    {
                        HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                        return;
                    }

                    try
                    {
                        var fileName = Path.GetFileName(attachment.Name);
                        fileName = Uri.EscapeDataString(fileName);
                        HttpContext.Response.Headers["Content-Disposition"] = $"attachment; filename=\"{fileName}\"; filename*=UTF-8''{fileName}";
                    }
                    catch (ArgumentException e)
                    {
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info($"Skip Content-Disposition header because of not valid file name: {attachment.Name}", e);
                        }
                    }
                    try
                    {
                        HttpContext.Response.Headers["Content-Type"] = attachment.ContentType.ToString();
                    }
                    catch (InvalidOperationException e)
                    {
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info($"Skip Content-Type header because of not valid content type: {attachment.ContentType}", e);
                        }
                        if (HttpContext.Response.Headers.ContainsKey("Content-Type"))
                        {
                            HttpContext.Response.Headers.Remove("Content-Type");
                        }
                    }
                    HttpContext.Response.Headers["Attachment-Hash"]      = attachment.Base64Hash.ToString();
                    HttpContext.Response.Headers["Attachment-Size"]      = attachment.Stream.Length.ToString();
                    HttpContext.Response.Headers[Constants.Headers.Etag] = $"\"{attachment.ChangeVector}\"";

                    using (context.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer buffer))
                        using (var stream = attachment.Stream)
                        {
                            var responseStream = ResponseBodyStream();
                            var count          = stream.Read(buffer.Buffer.Array, 0, buffer.Length); // can never wait, so no need for async
                            while (count > 0)
                            {
                                await responseStream.WriteAsync(buffer.Buffer.Array, 0, count, Database.DatabaseShutdown);

                                // we know that this can never wait, so no need to do async i/o here
                                count = stream.Read(buffer.Buffer.Array, 0, buffer.Length);
                            }
                        }
                }
        }