コード例 #1
0
        /// <summary>
        /// Posts the data of a given data block to the server.
        /// </summary>
        private HttpResponseMessage SendDataBlock(HttpClient client, StreamedDataBlock dataBlock)
        {
            string actionUri = VfsUris.Default.WriteStreamedDataBlockUri;

            actionUri = actionUri.ConstructUri(Uris.PatternTransferId, dataBlock.TransferTokenId);
            actionUri = actionUri.ConstructUri(Uris.PatternBlockNumber, dataBlock.BlockNumber.ToString(CultureInfo.InvariantCulture));

            RequestHeaders requestHeader = new RequestHeaders();

            //write the HTTP headers
            VfsHttpHeaders headers = VfsHttpHeaders.Default;

            requestHeader.Add(headers.TransferId, dataBlock.TransferTokenId); //duplicate transfer ID, might be useful in some scenarios
            requestHeader.Add(headers.BlockNumber, dataBlock.BlockNumber.ToString());
            requestHeader.Add(headers.IsLastBlock, Convert.ToString(dataBlock.IsLastBlock).ToLowerInvariant());
            requestHeader.Add(headers.BlockOffset, dataBlock.Offset.ToString());

            if (dataBlock.BlockLength.HasValue)
            {
                requestHeader.Add(headers.BlockLength, dataBlock.BlockLength.ToString());
            }

            using (dataBlock.Data)
            {
                return(client.Send(HttpMethod.POST, actionUri, requestHeader, HttpContent.Create(() => dataBlock.Data)));
            }
        }
コード例 #2
0
        /// <summary>
        /// Handles the actual writing of the submitted data to the file system.
        /// </summary>
        /// <param name="transfer">The processed transfer.</param>
        /// <param name="dataBlock">A data block that provides a data stream that
        /// is written to the file system.</param>
        protected override void WriteStreamedDataBlockImpl(TTransfer transfer, StreamedDataBlock dataBlock)
        {
            TempStream stream = GetCachedTempData(transfer, dataBlock.Offset);

            //when it comes to reading from the source stream, make sure no limits (block or whole file size)
            //are exceeded
            if (!transfer.Token.MaxResourceSize.HasValue)
            {
                if (!transfer.Token.MaxBlockSize.HasValue)
                {
                    //just write the stream - there is no limit
                    dataBlock.WriteTo(stream);
                }
                else
                {
                    //the limit is the maximum block size
                    dataBlock.WriteTo(stream, transfer.Token.MaxBlockSize.Value);
                }
            }
            else
            {
                //first we need to make sure we won't go over the max resource size
                long maxSize = transfer.Token.MaxResourceSize.Value - dataBlock.Offset;

                if (transfer.Token.MaxBlockSize.HasValue)
                {
                    //the other limit is the block size - take whatever is smaller
                    maxSize = Math.Min(maxSize, transfer.Token.MaxBlockSize.Value);
                }

                //the limit is the maximum block size
                dataBlock.WriteTo(stream, maxSize);
            }
        }
コード例 #3
0
        /// <summary>
        /// Uploads a given data block that contains a chunk of data for an uploaded file.
        /// </summary>
        /// <param name="block">The block to be written.</param>
        /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
        /// either because it's an invalid number, or because only sequential downloads
        /// are possible, and the block does not refer to the current download
        /// position.
        /// </exception>
        /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
        public void WriteBlock(BufferedDataBlock block)
        {
            Ensure.ArgumentNotNull(block, "block");

            //switch to streaming
            MemoryStream stream = new MemoryStream(block.Data);

            if (block.BlockLength != block.Data.Length)
            {
                string msg = "Block number {0} of transfer [{1}] has a buffer of size [{2}] that doesn't match the indicated block size of [{3}].";
                msg = String.Format(msg, block.BlockNumber, block.TransferTokenId, block.Data.Length, block.BlockLength);
                throw new DataBlockException(msg);
            }

            var streamingBlock = new StreamedDataBlock
            {
                TransferTokenId = block.TransferTokenId,
                BlockNumber     = block.BlockNumber,
                BlockLength     = block.BlockLength,
                Offset          = block.Offset,
                IsLastBlock     = block.IsLastBlock,
                Data            = stream
            };

            WriteBlockStreamed(streamingBlock);
        }
コード例 #4
0
 /// <summary>
 /// Uploads a given data block that provides a chunk of data for an uploaded file as a stream.
 /// </summary>
 /// <param name="block">The block to be written.</param>
 /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
 /// either because it's an invalid number, or because only sequential downloads
 /// are possible, and the block does not refer to the current download
 /// position.
 /// </exception>
 /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
 public virtual void WriteBlockStreamed(StreamedDataBlock block)
 {
     SecureAction(FileSystemTask.DataBlockUploadRequest,
                  () => OrchestrateBlockWriting(block, WriteStreamedDataBlockImpl),
                  () =>
                  String.Format("Could not write strea,ed data block [{0}] for transfer [{1}]", block.BlockNumber,
                                block.TransferTokenId));
 }
コード例 #5
0
        /// <summary>
        /// Uploads a given data block that provides a chunk of data for an uploaded file as a stream.
        /// </summary>
        /// <param name="block">The block to be written.</param>
        /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
        /// either because it's an invalid number, or because only sequential downloads
        /// are possible, and the block does not refer to the current download
        /// position.
        /// </exception>
        /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
        public void WriteBlockStreamed(StreamedDataBlock block)
        {
            Ensure.ArgumentNotNull(block, "block");

            SecureRequest(FileSystemTask.DataBlockUploadRequest,
                          c => SendDataBlock(c, block),
                          () =>
                          String.Format("Could not upload block [{0}] for transfer [{1}].", block.BlockNumber,
                                        block.TransferTokenId));
        }
コード例 #6
0
 /// <summary>
 /// Parses the received buffer and wraps it into a memory stream.
 /// </summary>
 /// <param name="bufferedBlock">A buffered block.</param>
 private void ParseBuffer(BufferedDataBlock bufferedBlock)
 {
   StreamedDataBlock streamedBlock = new StreamedDataBlock
                                       {
                                         TransferTokenId = bufferedBlock.TransferTokenId,
                                         BlockLength = bufferedBlock.BlockLength,
                                         BlockNumber = bufferedBlock.BlockNumber,
                                         IsLastBlock = bufferedBlock.IsLastBlock,
                                         Offset = bufferedBlock.Offset,
                                         Data = new MemoryStream(bufferedBlock.Data)
                                       };
   OutputAction(streamedBlock);
 }
コード例 #7
0
        /// <summary>
        /// Parses the received buffer and wraps it into a memory stream.
        /// </summary>
        /// <param name="bufferedBlock">A buffered block.</param>
        private void ParseBuffer(BufferedDataBlock bufferedBlock)
        {
            StreamedDataBlock streamedBlock = new StreamedDataBlock
            {
                TransferTokenId = bufferedBlock.TransferTokenId,
                BlockLength     = bufferedBlock.BlockLength,
                BlockNumber     = bufferedBlock.BlockNumber,
                IsLastBlock     = bufferedBlock.IsLastBlock,
                Offset          = bufferedBlock.Offset,
                Data            = new MemoryStream(bufferedBlock.Data)
            };

            OutputAction(streamedBlock);
        }
コード例 #8
0
        /// <summary>
        /// Gets a given <see cref="BufferedDataBlock"/> from the currently downloaded
        /// resource.
        /// </summary>
        /// <param name="transferId">Identifies the transfer and resource.</param>
        /// <param name="blockNumber">The number of the requested block.</param>
        /// <returns>A data block which contains the data as an in-memory buffer
        /// (<see cref="BufferedDataBlock.Data"/>).</returns>
        /// <exception cref="DataBlockException">If the data block cannot be delivered,
        /// either because it's an invalid number, or because only sequential downloads
        /// are possible, and the block does not refer to the current download
        /// position. Check the <see cref="TransmissionCapabilities"/> flag in order
        /// to get the service's capabilities.
        /// </exception>
        /// <exception cref="VirtualResourceNotFoundException">If the resource does
        /// not exist.</exception>
        /// <remarks>It's up to the service to resolve a block number to the
        /// corect piece of data. Simplest case for services that operate on one
        /// resource or stream is to just make all served
        /// blocks the same size (apart from the last one, of course), which
        /// allows to easily calculate the offset of the requested block.</remarks>
        public BufferedDataBlock ReadBlock(string transferId, long blockNumber)
        {
            //read stream
            StreamedDataBlock block = ReadBlockStreamed(transferId, blockNumber);

            byte[] buffer = block.Data.ReadIntoBuffer();

            return(new BufferedDataBlock
            {
                TransferTokenId = transferId,
                BlockNumber = blockNumber,
                BlockLength = block.BlockLength,
                Offset = block.Offset,
                IsLastBlock = block.IsLastBlock,
                Data = buffer
            });
        }
コード例 #9
0
        public void WriteTo(object entity, IHttpEntity response, string[] codecParameters)
        {
            //get the data block to be transferred
            StreamedDataBlock dataBlock = (StreamedDataBlock)entity;


            if (HttpContext.Current != null)
            {
                //disable buffering
                HttpContext.Current.Response.BufferOutput = false;

                if (dataBlock.BlockLength.HasValue)
                {
                    //only set the content lengths, if we actually know it
                    response.SetHeader("Content-Length", dataBlock.BlockLength.Value.ToString(CultureInfo.InvariantCulture));
                }

                response.SetHeader("Content-Type", MediaType.ApplicationOctetStream.Name);
            }
            else
            {
                response.ContentLength = dataBlock.BlockLength;
                response.ContentType   = MediaType.ApplicationOctetStream;
            }

            //write the HTTP headers
            VfsHttpHeaders headers = VfsHttpHeaders.Default;

            response.SetHeader(headers.TransferId, dataBlock.TransferTokenId);
            response.SetHeader(headers.BlockLength, dataBlock.BlockLength.ToString());
            response.SetHeader(headers.BlockNumber, dataBlock.BlockNumber.ToString());
            response.SetHeader(headers.IsLastBlock, dataBlock.IsLastBlock.ToString());
            response.SetHeader(headers.BlockOffset, dataBlock.Offset.ToString());

            using (dataBlock.Data)
            {
                //write data to response stream, then close the stream
                dataBlock.Data.CopyTo(response.Stream);
            }
        }
コード例 #10
0
        protected override void InitInternal()
        {
            base.InitInternal();
            InitToken();

            byte[] buffer = new byte[10000];
            Array.Copy(SourceFileContents, buffer, 10000);

            BufferedBlock = new BufferedDataBlock
            {
                TransferTokenId = Token.TransferId,
                BlockLength     = 10000,
                Data            = buffer
            };

            StreamedBlock = new StreamedDataBlock
            {
                TransferTokenId = Token.TransferId,
                BlockLength     = 10000,
                Data            = new ChunkStream(new MemoryStream(SourceFileContents), 10000, 0, false)
            };
        }
コード例 #11
0
        private void WriteBlock(string transferId, long blockNumber, Stream input)
        {
            //get meta information from headers
            VfsHttpHeaders       headerNames = VfsHttpHeaders.Default;
            HttpHeaderDictionary headers     = Request.Headers;

            var blockLength = Convert.ToInt32(headers[headerNames.BlockLength]);
            var isLastBlock = headers.ContainsKey(headerNames.IsLastBlock) ? Convert.ToBoolean(headers[headerNames.IsLastBlock]) : false;
            var offset      = Convert.ToInt64(headers[headerNames.BlockOffset]);

            StreamedDataBlock block = new StreamedDataBlock
            {
                TransferTokenId = transferId,
                BlockNumber     = blockNumber,
                IsLastBlock     = isLastBlock,
                BlockLength     = blockLength,
                Offset          = offset,
                Data            = new NonSeekableStream(input)
            };

            FileSystem.UploadTransfers.WriteBlockStreamed(block);
        }
コード例 #12
0
        protected override void InitInternal()
        {
            base.InitInternal();
            InitToken();

            //read first 10000 bytes
            byte[] buffer = GetBuffer(10000);


            BufferedBlock = new BufferedDataBlock
            {
                TransferTokenId = Token.TransferId,
                BlockLength     = 10000,
                Data            = buffer
            };

            StreamedBlock = new StreamedDataBlock
            {
                TransferTokenId = Token.TransferId,
                BlockLength     = 10000,
                Data            = new ChunkStream(new MemoryStream(buffer), 10000, 0, false)
            };
        }
コード例 #13
0
 /// <summary>
 /// Handles the actual writing of the submitted data to the file system.
 /// </summary>
 /// <param name="transfer">The processed transfer.</param>
 /// <param name="dataBlock">A data block that provides a data stream that
 /// is written to the file system.</param>
 protected abstract void WriteStreamedDataBlockImpl(TTransfer transfer, StreamedDataBlock dataBlock);
コード例 #14
0
 /// <summary>
 /// Uploads a given data block that provides a chunk of data for an uploaded file as a stream.
 /// </summary>
 /// <param name="block">The block to be written.</param>
 /// <exception cref="DataBlockException">If the data block's contents cannot be stored,
 /// either because it's an invalid number, or because only sequential downloads
 /// are possible, and the block does not refer to the current download
 /// position.
 /// </exception>
 /// <exception cref="TransferStatusException">If the transfer has already expired.</exception>
 void IFSDataUploadService.WriteDataBlockStreamed(StreamedDataBlock block)
 {
     throw new NotImplementedException();
 }
コード例 #15
0
 /// <summary>
 ///
 /// </summary>
 public void WriteBlockStreamed(StreamedDataBlock block)
 {
     throw new NotImplementedException();
 }