예제 #1
0
        private async Task ParseMultipart(DocumentsOperationContext context, MergedBatchCommand command)
        {
            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                MultipartRequestHelper.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, RequestBodyStream());

            for (var i = 0; i < int.MaxValue; i++)
            {
                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);

                if (section == null)
                {
                    break;
                }

                var bodyStream = GetBodyStream(section);
                if (i == 0)
                {
                    await BatchRequestParser.BuildCommandsAsync(context, command, bodyStream, Database, ServerStore);

                    continue;
                }

                if (command.AttachmentStreams == null)
                {
                    command.AttachmentStreams         = new Queue <MergedBatchCommand.AttachmentStream>();
                    command.AttachmentStreamsTempFile = Database.DocumentsStorage.AttachmentsStorage.GetTempFile("batch");
                }

                var attachmentStream = new MergedBatchCommand.AttachmentStream
                {
                    Stream = command.AttachmentStreamsTempFile.StartNewStream()
                };
                attachmentStream.Hash = await AttachmentsStorageHelper.CopyStreamToFileAndCalculateHash(context, bodyStream, attachmentStream.Stream, Database.DatabaseShutdown);

                attachmentStream.Stream.Flush();
                command.AttachmentStreams.Enqueue(attachmentStream);
            }
        }
예제 #2
0
        private async Task InsertDocument(BlittableJsonReaderObject document, string id, Dictionary <string, byte[]> attachments)
        {
            _commands.Add(new BatchRequestParser.CommandData
            {
                Type     = CommandType.PUT,
                Document = document,
                Id       = id
            });

            foreach (var attachment in attachments)
            {
                var memoryStream = new MemoryStream(attachment.Value);
                var stream       = _command.AttachmentStreamsTempFile.StartNewStream();

                _toDispose.Add(memoryStream);
                _toDispose.Add(stream);

                var attachmentStream = new BatchHandler.MergedBatchCommand.AttachmentStream
                {
                    Stream = stream,
                    Hash   = await AttachmentsStorageHelper.CopyStreamToFileAndCalculateHash(_context, memoryStream, stream, _context.DocumentDatabase.DatabaseShutdown)
                };

                _attachmentStreams.Add(attachmentStream);

                _commands.Add(new BatchRequestParser.CommandData
                {
                    Type        = CommandType.AttachmentPUT,
                    Id          = id,
                    ContentType = "",
                    Name        = attachment.Key
                });
            }

            if (_commands.Count >= _database.Factory.Options.BatchSize)
            {
                await FlushCommands();
            }
        }
예제 #3
0
        public async Task Put()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var id          = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id");
                var name        = GetQueryStringValueAndAssertIfSingleAndNotEmpty("name");
                var contentType = GetStringQueryString("contentType", false) ?? "";

                AttachmentDetails result;
                using (var streamsTempFile = Database.DocumentsStorage.AttachmentsStorage.GetTempFile("put"))
                    using (var stream = streamsTempFile.StartNewStream())
                    {
                        Stream requestBodyStream = RequestBodyStream();
                        string hash;
                        try
                        {
                            hash = await AttachmentsStorageHelper.CopyStreamToFileAndCalculateHash(context, requestBodyStream, stream, Database.DatabaseShutdown);
                        }
                        catch (Exception)
                        {
                            try
                            {
                                // if we failed to read the entire request body stream, we might leave
                                // data in the pipe still, this will cause us to read and discard the
                                // rest of the attachment stream and return the actual error to the caller
                                requestBodyStream.CopyTo(Stream.Null);
                            }
                            catch (Exception)
                            {
                                // we tried, but we can't clean the request, so let's just kill
                                // the connection
                                HttpContext.Abort();
                            }
                            throw;
                        }

                        var changeVector = context.GetLazyString(GetStringFromHeaders("If-Match"));

                        var cmd = new MergedPutAttachmentCommand
                        {
                            Database             = Database,
                            ExpectedChangeVector = changeVector,
                            DocumentId           = id,
                            Name        = name,
                            Stream      = stream,
                            Hash        = hash,
                            ContentType = contentType
                        };
                        stream.Flush();
                        await Database.TxMerger.Enqueue(cmd);

                        cmd.ExceptionDispatchInfo?.Throw();
                        result = cmd.Result;
                    }

                HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;

                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    writer.WriteStartObject();

                    writer.WritePropertyName(nameof(AttachmentDetails.ChangeVector));
                    writer.WriteString(result.ChangeVector);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Name));
                    writer.WriteString(result.Name);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.DocumentId));
                    writer.WriteString(result.DocumentId);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.ContentType));
                    writer.WriteString(result.ContentType);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Hash));
                    writer.WriteString(result.Hash);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Size));
                    writer.WriteInteger(result.Size);

                    writer.WriteEndObject();
                }
            }
        }
예제 #4
0
        public async Task Put()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var id          = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id");
                var name        = GetQueryStringValueAndAssertIfSingleAndNotEmpty("name");
                var contentType = GetStringQueryString("contentType", false) ?? "";

                AttachmentDetails result;
                using (var streamsTempFile = Database.DocumentsStorage.AttachmentsStorage.GetTempFile("put"))
                    using (var stream = streamsTempFile.StartNewStream())
                    {
                        var hash = await AttachmentsStorageHelper.CopyStreamToFileAndCalculateHash(context, RequestBodyStream(), stream, Database.DatabaseShutdown);

                        var changeVector = context.GetLazyString(GetStringQueryString("If-Match", false));

                        var cmd = new MergedPutAttachmentCommand
                        {
                            Database             = Database,
                            ExpectedChangeVector = changeVector,
                            DocumentId           = id,
                            Name        = name,
                            Stream      = stream,
                            Hash        = hash,
                            ContentType = contentType
                        };
                        await Database.TxMerger.Enqueue(cmd);

                        cmd.ExceptionDispatchInfo?.Throw();
                        result = cmd.Result;
                    }

                HttpContext.Response.StatusCode = (int)HttpStatusCode.Created;

                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    writer.WriteStartObject();

                    writer.WritePropertyName(nameof(AttachmentDetails.ChangeVector));
                    writer.WriteString(result.ChangeVector);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Name));
                    writer.WriteString(result.Name);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.DocumentId));
                    writer.WriteString(result.DocumentId);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.ContentType));
                    writer.WriteString(result.ContentType);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Hash));
                    writer.WriteString(result.Hash);
                    writer.WriteComma();

                    writer.WritePropertyName(nameof(AttachmentDetails.Size));
                    writer.WriteInteger(result.Size);

                    writer.WriteEndObject();
                }
            }
        }