void SerializeError(RecyclableMemoryStream response, string error) { response.Position = 0; response.SetLength(0); _serializer.SerializeException(response, error); response.Position = 0; }
private RecyclableMemoryStream Encrypt(byte[] buffer, long bufferlength, int size, out int sizePadded) { sizePadded = size + (RijndaelStream.AES_KEY.Length - (size % RijndaelStream.AES_KEY.Length)); RecyclableMemoryStream result = new RecyclableMemoryStream(); result.SetLength(sizePadded); byte[] temp = new byte[sizePadded]; unsafe { fixed(byte *source = buffer, dest = temp) { for (int i = 0; i < bufferlength; i++) { dest[i] = source[i]; } using (Rijndael aes = Rijndael.Create()) { aes.Mode = CipherMode.ECB; using (ICryptoTransform encrypt = aes.CreateEncryptor(RijndaelStream.RAW_AES_KEY, new byte[16])) encrypt.TransformBlock(temp, 0, sizePadded, result.GetBuffer(), 0); } } } result.Position = 0; return(result); }
public void CanDecreaseLength() { using var stream = new RecyclableMemoryStream(); stream.WriteByte(0xCA); stream.WriteByte(0xFE); Assert.That(stream.Length, Is.EqualTo(2)); Assert.That(stream.Position, Is.EqualTo(2)); stream.SetLength(1); Assert.That(stream.Length, Is.EqualTo(1)); Assert.That(stream.Position, Is.EqualTo(1)); }
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(); }
/// <summary> /// Remove everything used for the last message /// </summary> public void Clear() { _bytesTransferred = 0; _bytesLeftToSend = 0; _payloadPosition = 0; _contentLengths = null; if (_disposeBodyStream) { //bodyStream is null for channels that connected //but never sent a message. _bodyStream?.Dispose(); _bodyStream = null; } _headerStream.SetLength(0); _contentStream.SetLength(0); _headerIsSent = _headerCreated = false; _message = null; _disposeBodyStream = false; }
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>()); }
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()); }
async Task IRequestHandler.HandleRequest(IRequest req) { Exception ex = null; object result = null; MethodCall call = null; try { if (req.Data is RecyclableMemoryStream || req.Data is MemoryStream) { call = _serializer.DeserializeCall(req.Data, _binder, _selector, req.Context); } else { using var copy = new RecyclableMemoryStream(StreamPool.Shared); await req.Data.CopyToAsync(copy); req.Data.Dispose(); copy.Position = 0; call = _serializer.DeserializeCall(copy, _binder, _selector, req.Context); } } catch (Exception e) { ex = e; } if (call != null) { object res = null; try { if (_interceptor != null) { res = _interceptor.Intercept(call, req.Context, () => ConvertToTask(call.Method.Invoke(call.Target, call.Arguments))); } else { res = call.Method.Invoke(call.Target, call.Arguments); } } catch (Exception e) { ex = e; } if (res != null) { var task = res as Task; if (task == null) { result = res; } else { try { await task; if (call.Method.ReturnType != typeof(Task)) { result = task.GetType().GetProperty("Result")?.GetValue(task); } } catch (Exception e) { ex = e; } } } } using var response = new RecyclableMemoryStream(StreamPool.Shared); if (ex == null) { try { _serializer.SerializeResult(response, result); response.Position = 0; } catch (Exception e) { ex = e; } } if (ex != null) { response.Position = 0; response.SetLength(0); _serializer.SerializeException(response, ex.ToString()); response.Position = 0; } try { await req.RespondAsync(response); } catch { //TODO: redirect it somewhere? } }
public void CanIncreaseLength() { using var stream = new RecyclableMemoryStream(); Assert.That(() => stream.SetLength(4), Throws.Nothing); Assert.That(stream.Length, Is.EqualTo(4)); }