Exemplo n.º 1
0
 public void Dispose()
 {
     if (_disposeUnderlying)
     {
         _underlying?.Dispose();
     }
     _copy?.Dispose();
 }
        public void ConstructorCreatesAMemoryStream()
        {
            var stream = new RecyclableMemoryStream();

            Assert.That(
                stream.BaseStream,
                Is.TypeOf <Microsoft.IO.RecyclableMemoryStream>());
            stream.Dispose();
        }
 protected override void Dispose(bool disposing)
 {
     base.Dispose(disposing);
     if (disposing)
     {
         _decompressedStream.Dispose();
     }
     _decompressedStream = null;
     _decoder            = null;
 }
Exemplo n.º 4
0
 /// <summary>
 ///     Reset the decoder so that we can parse a new message
 /// </summary>
 public void Clear()
 {
     _bytesLeftForCurrentState = sizeof(short);
     _bytesLeftInSocketBuffer  = 0;
     _contentStream?.Dispose();
     _socketBufferOffset = 0;
     _contentLengths     = null;
     _objects            = null;
     _stateMethod        = ReadHeaderLength;
     _payloadPosition    = 0;
 }
Exemplo n.º 5
0
        private void EventLoop(CancellationToken token)
        {
            try
            {
                for (; ;)
                {
                    token.ThrowIfCancellationRequested();

                    long length = (long)Varint.GetUInt64(_stream);
                    if (length == 0)
                    {
                        continue;
                    }

                    Stream resultSteram = null;

                    try
                    {
                        resultSteram = new RecyclableMemoryStream(_bufferManager);

                        using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 32))
                        {
                            long remain = length;

                            while (remain > 0)
                            {
                                int readLength = _stream.Read(safeBuffer.Value, 0, (int)Math.Min(remain, safeBuffer.Value.Length));
                                resultSteram.Write(safeBuffer.Value, 0, readLength);

                                remain -= readLength;
                            }
                        }

                        resultSteram.Seek(0, SeekOrigin.Begin);

                        this.OnReceive(resultSteram);
                    }
                    catch (Exception)
                    {
                        if (resultSteram != null)
                        {
                            resultSteram.Dispose();
                            resultSteram = null;
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Retrieve a new MemoryStream object with the given tag and with contents copied from the provided
        /// buffer. The provided buffer is not wrapped or used after construction.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="id">A unique identifier which can be used to trace usages of the stream.</param>
        /// <param name="tag">A tag which can be used to track the source of the stream.</param>
        /// <param name="buffer">The byte buffer to copy data from.</param>
        /// <param name="offset">The offset from the start of the buffer to copy from.</param>
        /// <param name="count">The number of bytes to copy from the buffer.</param>
        /// <returns>A MemoryStream.</returns>
        public RecyclableMemoryStream GetStream(Guid id, object tag, byte[] buffer, int offset, int count)
        {
            RecyclableMemoryStream stream = null;

            try
            {
                stream = new RecyclableMemoryStream(this, id, tag, count);
                stream.Write(buffer, offset, count);
                stream.Position = 0;
                return(stream);
            }
            catch
            {
                stream?.Dispose();
                throw;
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Retrieve a new MemoryStream object with the given tag and with contents copied from the provided
        /// buffer. The provided buffer is not wrapped or used after construction.
        /// </summary>
        /// <remarks>The new stream's position is set to the beginning of the stream when returned.</remarks>
        /// <param name="id">A unique identifier which can be used to trace usages of the stream.</param>
        /// <param name="tag">A tag which can be used to track the source of the stream.</param>
        /// <param name="buffer">The byte buffer to copy data from.</param>
        /// <returns>A MemoryStream.</returns>
        public MemoryStream GetStream(Guid id, string tag, Memory <byte> buffer)
        {
            RecyclableMemoryStream stream = null;

            try
            {
                stream = new RecyclableMemoryStream(this, id, tag, buffer.Length);
                stream.Write(buffer.Span);
                stream.Position = 0;
                return(stream);
            }
            catch
            {
                stream?.Dispose();
                throw;
            }
        }
Exemplo n.º 8
0
            private Stream GetStream(string url)
            {
                var recyclableMemoryStream = new RecyclableMemoryStream(_bufferManager);

                try
                {
                    using (var client = new HttpClient())
                    {
                        using (var stream = client.GetStreamAsync(url).Result)
                        {
                            if (stream.Length > 1024 * 1024 * 32)
                            {
                                throw new Exception("too large");
                            }

                            using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                            {
                                int length;

                                while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                {
                                    recyclableMemoryStream.Write(safeBuffer.Value, 0, length);

                                    if (recyclableMemoryStream.Length > 1024 * 1024 * 32)
                                    {
                                        throw new Exception("too large");
                                    }
                                }
                            }

                            recyclableMemoryStream.Seek(0, SeekOrigin.Begin);
                            return(recyclableMemoryStream);
                        }
                    }
                }
                catch (Exception)
                {
                    recyclableMemoryStream.Dispose();

                    throw;
                }
            }
Exemplo n.º 9
0
        private (int, WaitQueue <ResponseInfo>) Send <TArgument>(AmoebaFunctionType type, TArgument argument)
        {
            int id    = this.CreateId();
            var queue = new WaitQueue <ResponseInfo>();

            _queueMap.Add(id, queue);

            var messageStream = new RecyclableMemoryStream(_bufferManager);
            var writer        = new MessageStreamWriter(messageStream, _bufferManager);

            writer.Write((ulong)type);
            writer.Write((ulong)id);

            Stream valueStream = null;

            if (argument != null)
            {
                try
                {
                    valueStream = new RecyclableMemoryStream(_bufferManager);
                    JsonUtils.Save(valueStream, argument);
                }
                catch (Exception)
                {
                    if (valueStream != null)
                    {
                        valueStream.Dispose();
                        valueStream = null;
                    }

                    throw;
                }
            }

            messageStream.Seek(0, SeekOrigin.Begin);
            _messagingManager.Send(new UniteStream(messageStream, valueStream));

            return(id, queue);
        }
        public void PublicMethodThrowAfterDispose()
        {
            var stream = new RecyclableMemoryStream();

            stream.Dispose();

            byte[] buffer = new byte[1];
            Assert.That(
                () => stream.SetLength(10),
                Throws.InstanceOf <ObjectDisposedException>());
            Assert.That(
                () => stream.WriteByte(0x00),
                Throws.InstanceOf <ObjectDisposedException>());
            Assert.That(
                () => stream.Write(buffer, 0, 1),
                Throws.InstanceOf <ObjectDisposedException>());
            Assert.That(
                () => stream.ReadByte(),
                Throws.InstanceOf <ObjectDisposedException>());
            Assert.That(
                () => stream.Read(buffer, 0, 1),
                Throws.InstanceOf <ObjectDisposedException>());
        }
Exemplo n.º 11
0
        public async Task <Stream> SendMessageAsync(Stream message)
        {
            using (var pipe = new NamedPipeClientStream(_serverName, _pipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
            {
                await pipe.ConnectAsync();

                var requestLengthBytes = BitConverter.GetBytes(message.Length);
                await pipe.WriteAsync(requestLengthBytes, 0, 4);

                await message.CopyToAsync(pipe);

                await pipe.FlushAsync();

                var responseLengthBytes = await pipe.ReadExactlyAsync(4);

                var responseLength = BitConverter.ToInt32(responseLengthBytes, 0);

                bool success = false;
                var  ms      = new RecyclableMemoryStream(StreamPool.Shared);
                try
                {
                    await pipe.ReadExactlyAsync(ms, responseLength);

                    ms.Position = 0;
                    success     = true;
                }
                finally
                {
                    if (!success)
                    {
                        ms.Dispose();
                    }
                }

                return(ms);
            }
        }
        public void UpdatedLongBufferIsClean()
        {
            var stream = new RecyclableMemoryStream();

            stream.WriteByte(0x42);
            stream.SetLength(11);
            Assert.That(stream.Length, Is.EqualTo(11));

            stream.Position = 0;
            Assert.That(stream.ReadByte(), Is.EqualTo(0x42));
            for (int i = 0; i < 10; i++)
            {
                Assert.That(stream.ReadByte(), Is.EqualTo(0));
            }

            stream.SetLength(80 * 1024);
            stream.Position = 1;
            for (int i = 1; i < stream.Length; i++)
            {
                Assert.That(stream.ReadByte(), Is.EqualTo(0));
            }

            stream.Dispose();
        }
Exemplo n.º 13
0
            private static Stream Encrypt(Stream stream, ExchangePublicKey publicKey)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }
                if (publicKey == null)
                {
                    throw new ArgumentNullException(nameof(publicKey));
                }

                try
                {
                    RecyclableMemoryStream outStream = null;

                    try
                    {
                        outStream = new RecyclableMemoryStream(_bufferManager);
                        Varint.SetUInt64(outStream, (uint)ConvertCryptoAlgorithm.Aes256);

                        var cryptoKey = new byte[32];
                        var iv        = new byte[32];

                        using (var random = RandomNumberGenerator.Create())
                        {
                            random.GetBytes(cryptoKey);
                            random.GetBytes(iv);
                        }

                        {
                            var encryptedBuffer = Exchange.Encrypt(publicKey, cryptoKey);
                            Varint.SetUInt64(outStream, (uint)encryptedBuffer.Length);
                            outStream.Write(encryptedBuffer, 0, encryptedBuffer.Length);
                        }

                        outStream.Write(iv, 0, iv.Length);

                        using (var aes = Aes.Create())
                        {
                            aes.KeySize = 256;
                            aes.Mode    = CipherMode.CBC;
                            aes.Padding = PaddingMode.PKCS7;

                            using (var inStream = new WrapperStream(stream))
                                using (var cs = new CryptoStream(inStream, aes.CreateEncryptor(cryptoKey, iv), CryptoStreamMode.Read))
                                    using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                    {
                                        int length;

                                        while ((length = cs.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                        {
                                            outStream.Write(safeBuffer.Value, 0, length);
                                        }
                                    }
                        }

                        outStream.Seek(0, SeekOrigin.Begin);
                    }
                    catch (Exception)
                    {
                        if (outStream != null)
                        {
                            outStream.Dispose();
                        }

                        throw;
                    }

                    return(outStream);
                }
                catch (Exception e)
                {
                    throw new ArgumentException(e.Message, e);
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }
            }
Exemplo n.º 14
0
            private static Stream Decompress(Stream stream)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }

                try
                {
                    stream.Seek(0, SeekOrigin.Begin);

                    int type = (int)Varint.GetUInt64(stream);

                    if (type == (int)ConvertCompressionAlgorithm.None)
                    {
                        return(new RangeStream(stream));
                    }
                    else if (type == (int)ConvertCompressionAlgorithm.Deflate)
                    {
                        RecyclableMemoryStream deflateBufferStream = null;

                        try
                        {
                            deflateBufferStream = new RecyclableMemoryStream(_bufferManager);

                            using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
                                using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                {
                                    int length;

                                    while ((length = deflateStream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                    {
                                        deflateBufferStream.Write(safeBuffer.Value, 0, length);

                                        if (deflateBufferStream.Length > 1024 * 1024 * 256)
                                        {
                                            throw new Exception("too large");
                                        }
                                    }
                                }

                            deflateBufferStream.Seek(0, SeekOrigin.Begin);

                            return(deflateBufferStream);
                        }
                        catch (Exception)
                        {
                            if (deflateBufferStream != null)
                            {
                                deflateBufferStream.Dispose();
                            }

                            throw;
                        }
                    }
                    else
                    {
                        throw new ArgumentException("ArgumentException");
                    }
                }
                catch (Exception e)
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    throw new ArgumentException(e.Message, e);
                }
            }
Exemplo n.º 15
0
        private void RunWriteQueueAction()
        {
            //Dequeue all items until threshold is passed
            long totalLength = 0;
            RecyclableMemoryStream stream = null;

            while (totalLength < CoalescingThreshold)
            {
                OperationState state;
                if (!_writeQueue.TryDequeue(out state))
                {
                    //No more items in the write queue
                    break;
                }
                short streamId;
                if (!_freeOperations.TryPop(out streamId))
                {
                    //Queue it up for later.
                    _writeQueue.Enqueue(state);
                    //When receiving the next complete message, we can process it.
                    Logger.Info("Enqueued, no streamIds available. If this message is recurrent consider configuring more connections per host or lower the pressure");
                    break;
                }
                Logger.Verbose("Sending #{0} for {1} to {2}", streamId, state.Request.GetType().Name, Address);
                if (_isCanceled)
                {
                    state.InvokeCallback(new SocketException((int)SocketError.NotConnected));
                    break;
                }
                _pendingOperations.AddOrUpdate(streamId, state, (k, oldValue) => state);
                Interlocked.Increment(ref _inFlight);
                int frameLength;
                try
                {
                    //lazy initialize the stream
                    stream      = stream ?? (RecyclableMemoryStream)Configuration.BufferPool.GetStream(StreamWriteTag);
                    frameLength = state.Request.WriteFrame(streamId, stream, _serializer);
                    if (state.TimeoutMillis > 0)
                    {
                        var requestTimeout = Configuration.Timer.NewTimeout(OnTimeout, streamId, state.TimeoutMillis);
                        state.SetTimeout(requestTimeout);
                    }
                }
                catch (Exception ex)
                {
                    //There was an error while serializing or begin sending
                    Logger.Error(ex);
                    //The request was not written, clear it from pending operations
                    RemoveFromPending(streamId);
                    //Callback with the Exception
                    state.InvokeCallback(ex);
                    break;
                }
                //We will not use the request any more, stop reference it.
                state.Request = null;
                totalLength  += frameLength;
            }
            if (totalLength == 0L)
            {
                // Nothing to write, set the queue as not running
                Interlocked.CompareExchange(ref _writeState, WriteStateInit, WriteStateRunning);
                // Until now, we were preventing other threads to running the queue.
                // Check if we can now write:
                // a read could have finished (freeing streamIds) or new request could have been added to the queue
                if (!_freeOperations.IsEmpty && !_writeQueue.IsEmpty)
                {
                    //The write queue is not empty
                    //An item was added to the queue but we were running: try to launch a new queue
                    RunWriteQueue();
                }
                if (stream != null)
                {
                    //The stream instance could be created if there was an exception while generating the frame
                    stream.Dispose();
                }
                return;
            }
            //Write and close the stream when flushed
            // ReSharper disable once PossibleNullReferenceException : if totalLength > 0 the stream is initialized
            _tcpSocket.Write(stream, () => stream.Dispose());
        }
Exemplo n.º 16
0
        private void RunWriteQueueAction()
        {
            //Dequeue all items until threshold is passed
            long totalLength = 0;
            RecyclableMemoryStream stream = null;
            var timestamp = GetTimestamp();

            while (totalLength < Connection.CoalescingThreshold)
            {
                OperationState state = null;
                while (_writeQueue.TryDequeue(out var tempState))
                {
                    if (tempState.CanBeWritten())
                    {
                        state = tempState;
                        break;
                    }

                    DecrementInFlight();
                }

                if (state == null)
                {
                    //No more items in the write queue
                    break;
                }

                if (!_freeOperations.TryPop(out short streamId))
                {
                    //Queue it up for later.
                    _writeQueue.Enqueue(state);
                    //When receiving the next complete message, we can process it.
                    Connection.Logger.Info("Enqueued, no streamIds available. If this message is recurrent consider configuring more connections per host or lower the pressure");
                    break;
                }
                Connection.Logger.Verbose("Sending #{0} for {1} to {2}", streamId, state.Request.GetType().Name, EndPoint.EndpointFriendlyName);
                if (_isCanceled)
                {
                    DecrementInFlight();
                    state.InvokeCallback(RequestError.CreateClientError(new SocketException((int)SocketError.NotConnected), true), timestamp);
                    break;
                }
                _pendingOperations.AddOrUpdate(streamId, state, (k, oldValue) => state);
                var startLength = stream?.Length ?? 0;
                try
                {
                    //lazy initialize the stream
                    stream = stream ?? (RecyclableMemoryStream)Configuration.BufferPool.GetStream(Connection.StreamWriteTag);
                    var frameLength = state.WriteFrame(streamId, stream, Serializer, timestamp);
                    _connectionObserver.OnBytesSent(frameLength);
                    totalLength += frameLength;
                }
                catch (Exception ex)
                {
                    //There was an error while serializing or begin sending
                    Connection.Logger.Error(ex);
                    //The request was not written, clear it from pending operations
                    RemoveFromPending(streamId);
                    //Callback with the Exception
                    state.InvokeCallback(RequestError.CreateClientError(ex, true), timestamp);

                    //Reset the stream to before we started writing this frame
                    stream?.SetLength(startLength);
                    break;
                }
            }
            if (totalLength == 0L)
            {
                // Nothing to write, set the queue as not running
                Interlocked.CompareExchange(ref _writeState, Connection.WriteStateInit, Connection.WriteStateRunning);
                // Until now, we were preventing other threads to running the queue.
                // Check if we can now write:
                // a read could have finished (freeing streamIds) or new request could have been added to the queue
                if (!_freeOperations.IsEmpty && !_writeQueue.IsEmpty)
                {
                    //The write queue is not empty
                    //An item was added to the queue but we were running: try to launch a new queue
                    RunWriteQueue();
                }
                if (stream != null)
                {
                    //The stream instance could be created if there was an exception while generating the frame
                    stream.Dispose();
                }
                return;
            }
            //Write and close the stream when flushed
            // ReSharper disable once PossibleNullReferenceException : if totalLength > 0 the stream is initialized
            _tcpSocket.Write(stream, () => stream.Dispose());
        }
Exemplo n.º 17
0
 public void Dispose()
 {
     m_disposed = true;
     m_stream?.Dispose();
     m_stream = null;
 }
Exemplo n.º 18
0
        private void _messagingManager_ReceiveEvent(Stream requestStream)
        {
            var reader = new MessageStreamReader(new WrapperStream(requestStream), _bufferManager);

            {
                var type = (AmoebaFunctionType)reader.GetUInt64();
                int id   = (int)reader.GetUInt64();

                if (type == AmoebaFunctionType.Exit)
                {
                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                    _tokenSource.Cancel();
                }
                else if (type == AmoebaFunctionType.Cancel)
                {
                    if (_tasks.TryGetValue(id, out var responseTask))
                    {
                        responseTask.Stop();
                    }
                }
                else
                {
                    var responseTask = ResponseTask.Create((token) =>
                    {
                        try
                        {
                            switch (type)
                            {
                            case AmoebaFunctionType.GetReport:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Report);
                                    break;
                                }

                            case AmoebaFunctionType.GetNetworkConnectionReports:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetNetworkConnectionReports());
                                    break;
                                }

                            case AmoebaFunctionType.GetCacheContentReports:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetCacheContentReports());
                                    break;
                                }

                            case AmoebaFunctionType.GetDownloadContentReports:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.GetDownloadContentReports());
                                    break;
                                }

                            case AmoebaFunctionType.GetConfig:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Config);
                                    break;
                                }

                            case AmoebaFunctionType.SetConfig:
                                {
                                    var config = JsonUtils.Load <ServiceConfig>(requestStream);
                                    _serviceManager.SetConfig(config);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.SetCloudLocations:
                                {
                                    var cloudLocations = JsonUtils.Load <Location[]>(requestStream);
                                    _serviceManager.SetCloudLocations(cloudLocations);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.GetSize:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.Size);
                                    break;
                                }

                            case AmoebaFunctionType.Resize:
                                {
                                    long size = JsonUtils.Load <long>(requestStream);
                                    _serviceManager.Resize(size);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.CheckBlocks:
                                {
                                    _serviceManager.CheckBlocks(new Action <CheckBlocksProgressReport>((report) =>
                                    {
                                        SendResponse(AmoebaFunctionResponseType.Output, id, report);
                                    }), token).Wait();

                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.AddContent:
                                {
                                    var arguments = JsonUtils.Load <(string, DateTime)>(requestStream);
                                    var result    = _serviceManager.AddContent(arguments.Item1, arguments.Item2, token).Result;
                                    SendResponse(AmoebaFunctionResponseType.Result, id, result);
                                    break;
                                }

                            case AmoebaFunctionType.RemoveContent:
                                {
                                    string path = JsonUtils.Load <string>(requestStream);
                                    _serviceManager.RemoveContent(path);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.Diffusion:
                                {
                                    string path = JsonUtils.Load <string>(requestStream);
                                    _serviceManager.DiffuseContent(path);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.AddDownload:
                                {
                                    var arguments = JsonUtils.Load <(Metadata, string, long)>(requestStream);
                                    _serviceManager.AddDownload(arguments.Item1, arguments.Item2, arguments.Item3);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.RemoveDownload:
                                {
                                    var arguments = JsonUtils.Load <(Metadata, string)>(requestStream);
                                    _serviceManager.RemoveDownload(arguments.Item1, arguments.Item2);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.ResetDownload:
                                {
                                    var arguments = JsonUtils.Load <(Metadata, string)>(requestStream);
                                    _serviceManager.ResetDownload(arguments.Item1, arguments.Item2);
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.SetProfile:
                                {
                                    var arguments = JsonUtils.Load <(ProfileContent, DigitalSignature)>(requestStream);
                                    _serviceManager.SetProfile(arguments.Item1, arguments.Item2, token).Wait();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.SetStore:
                                {
                                    var arguments = JsonUtils.Load <(StoreContent, DigitalSignature)>(requestStream);
                                    _serviceManager.SetStore(arguments.Item1, arguments.Item2, token).Wait();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.SetUnicastCommentMessage:
                                {
                                    var arguments = JsonUtils.Load <(Signature, CommentContent, AgreementPublicKey, DigitalSignature)>(requestStream);
                                    _serviceManager.SetUnicastCommentMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.SetMulticastCommentMessage:
                                {
                                    var arguments = JsonUtils.Load <(Tag, CommentContent, DigitalSignature, TimeSpan)>(requestStream);
                                    _serviceManager.SetMulticastCommentMessage(arguments.Item1, arguments.Item2, arguments.Item3, arguments.Item4, token).Wait();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.GetProfile:
                                {
                                    var signature = JsonUtils.Load <Signature>(requestStream);
                                    var result    = _serviceManager.GetProfile(signature, token).Result;
                                    SendResponse(AmoebaFunctionResponseType.Result, id, result);
                                    break;
                                }

                            case AmoebaFunctionType.GetStore:
                                {
                                    var signature = JsonUtils.Load <Signature>(requestStream);
                                    var result    = _serviceManager.GetStore(signature, token).Result;
                                    SendResponse(AmoebaFunctionResponseType.Result, id, result);
                                    break;
                                }

                            case AmoebaFunctionType.GetUnicastCommentMessages:
                                {
                                    var arguments = JsonUtils.Load <(Signature, AgreementPrivateKey)>(requestStream);
                                    var result    = _serviceManager.GetUnicastCommentMessages(arguments.Item1, arguments.Item2, token).Result;
                                    SendResponse(AmoebaFunctionResponseType.Result, id, result);
                                    break;
                                }

                            case AmoebaFunctionType.GetMulticastCommentMessages:
                                {
                                    var tag    = JsonUtils.Load <Tag>(requestStream);
                                    var result = _serviceManager.GetMulticastCommentMessages(tag, token).Result;
                                    SendResponse(AmoebaFunctionResponseType.Result, id, result);
                                    break;
                                }

                            case AmoebaFunctionType.GetState:
                                {
                                    SendResponse(AmoebaFunctionResponseType.Result, id, _serviceManager.State);
                                    break;
                                }

                            case AmoebaFunctionType.Start:
                                {
                                    _serviceManager.Start();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.Stop:
                                {
                                    _serviceManager.Stop();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.Load:
                                {
                                    _serviceManager.Load();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }

                            case AmoebaFunctionType.Save:
                                {
                                    _serviceManager.Save();
                                    SendResponse(AmoebaFunctionResponseType.Result, id, (object)null);
                                    break;
                                }
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            SendResponse(AmoebaFunctionResponseType.Cancel, id, (object)null);
                        }
                        catch (Exception e)
                        {
                            Log.Error(string.Format("Rpc Error: {0}", type.ToString()));
                            Log.Error(e);

                            var argument = new AmoebaErrorMessage(e.GetType().ToString(), e.Message, e.StackTrace?.ToString());
                            SendResponse(AmoebaFunctionResponseType.Error, id, argument);
                        }
                        finally
                        {
                            requestStream.Dispose();
                            _tasks.Remove(id);
                        }
                    });

                    _tasks.Add(id, responseTask);
                    responseTask.Start();
                }
            }

            void SendResponse <T>(AmoebaFunctionResponseType type, int id, T value)
            {
                var messageStream = new RecyclableMemoryStream(_bufferManager);
                var writer        = new MessageStreamWriter(messageStream, _bufferManager);

                writer.Write((ulong)type);
                writer.Write((ulong)id);

                Stream valueStream = null;

                if (value != null)
                {
                    try
                    {
                        valueStream = new RecyclableMemoryStream(_bufferManager);
                        JsonUtils.Save(valueStream, value);
                    }
                    catch (Exception)
                    {
                        if (valueStream != null)
                        {
                            valueStream.Dispose();
                            valueStream = null;
                        }

                        return;
                    }
                }

                messageStream.Seek(0, SeekOrigin.Begin);
                _messagingManager.Send(new UniteStream(messageStream, valueStream));
            }
        }
Exemplo n.º 19
0
            private static Stream Decrypt(Stream stream, ExchangePrivateKey privateKey)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }
                if (privateKey == null)
                {
                    throw new ArgumentNullException(nameof(privateKey));
                }

                try
                {
                    int type = (int)Varint.GetUInt64(stream);

                    if (type == (int)ConvertCryptoAlgorithm.Aes256)
                    {
                        byte[] cryptoKey;

                        {
                            int length = (int)Varint.GetUInt64(stream);

                            var encryptedBuffer = new byte[length];
                            if (stream.Read(encryptedBuffer, 0, encryptedBuffer.Length) != encryptedBuffer.Length)
                            {
                                throw new ArgumentException();
                            }

                            cryptoKey = Exchange.Decrypt(privateKey, encryptedBuffer);
                        }

                        var iv = new byte[32];
                        stream.Read(iv, 0, iv.Length);

                        RecyclableMemoryStream outStream = null;

                        try
                        {
                            outStream = new RecyclableMemoryStream(_bufferManager);

                            using (var aes = Aes.Create())
                            {
                                aes.KeySize = 256;
                                aes.Mode    = CipherMode.CBC;
                                aes.Padding = PaddingMode.PKCS7;

                                using (var inStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true))
                                    using (var cs = new CryptoStream(inStream, aes.CreateDecryptor(cryptoKey, iv), CryptoStreamMode.Read))
                                        using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                        {
                                            int length;

                                            while ((length = cs.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                            {
                                                outStream.Write(safeBuffer.Value, 0, length);
                                            }
                                        }
                            }

                            outStream.Seek(0, SeekOrigin.Begin);
                        }
                        catch (Exception)
                        {
                            if (outStream != null)
                            {
                                outStream.Dispose();
                            }

                            throw;
                        }

                        return(outStream);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                catch (Exception e)
                {
                    throw new ArgumentException(e.Message, e);
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }
            }
Exemplo n.º 20
0
            private static Stream Compress(Stream stream)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException(nameof(stream));
                }

                try
                {
                    var dic = new Dictionary <byte, Stream>();

                    try
                    {
                        stream.Seek(0, SeekOrigin.Begin);

                        RecyclableMemoryStream deflateBufferStream = null;

                        try
                        {
                            deflateBufferStream = new RecyclableMemoryStream(_bufferManager);

                            using (var deflateStream = new DeflateStream(deflateBufferStream, CompressionMode.Compress, true))
                                using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
                                {
                                    int length;

                                    while ((length = stream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
                                    {
                                        deflateStream.Write(safeBuffer.Value, 0, length);
                                    }
                                }

                            deflateBufferStream.Seek(0, SeekOrigin.Begin);

                            dic.Add((byte)ConvertCompressionAlgorithm.Deflate, deflateBufferStream);
                        }
                        catch (Exception)
                        {
                            if (deflateBufferStream != null)
                            {
                                deflateBufferStream.Dispose();
                            }
                        }
                    }
                    catch (Exception)
                    {
                    }

                    dic.Add((byte)ConvertCompressionAlgorithm.None, stream);

                    var list = dic.ToList();

                    list.Sort((x, y) =>
                    {
                        int c = x.Value.Length.CompareTo(y.Value.Length);
                        if (c != 0)
                        {
                            return(c);
                        }

                        return(x.Key.CompareTo(y.Key));
                    });

                    for (int i = 1; i < list.Count; i++)
                    {
                        list[i].Value.Dispose();
                    }

                    var headerStream = new RecyclableMemoryStream(_bufferManager);
                    Varint.SetUInt64(headerStream, list[0].Key);

                    return(new UniteStream(headerStream, list[0].Value));
                }
                catch (Exception ex)
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    throw new ArgumentException(ex.Message, ex);
                }
            }
        public void AllocationStackIsRecorded()
        {
            var memMgr = this.GetMemoryManager();
            memMgr.GenerateCallStacks = true;

            var stream = new RecyclableMemoryStream(memMgr);

            Assert.That(stream.AllocationStack, Is.StringContaining("RecyclableMemoryStream..ctor"));
            stream.Dispose();

            memMgr.GenerateCallStacks = false;

            var stream2 = new RecyclableMemoryStream(memMgr);

            Assert.That(stream2.AllocationStack, Is.Null);

            stream2.Dispose();
        }