/// <summary> /// Read a Request from the given stream. /// /// The total request size must be less than 1MB. /// </summary> /// <returns>null if the Request was too large, the Request otherwise.</returns> public static async Task <ServerRequest> ReadAsync(Stream inStream, CancellationToken cancellationToken) { // Read the length of the request var lengthBuffer = new byte[4]; ServerLogger.Log("Reading length of request"); await ServerProtocol.ReadAllAsync(inStream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false); var length = BitConverter.ToInt32(lengthBuffer, 0); // Back out if the request is > 1MB if (length > 0x100000) { ServerLogger.Log("Request is over 1MB in length, cancelling read."); return(null); } cancellationToken.ThrowIfCancellationRequested(); // Read the full request var requestBuffer = new byte[length]; await ServerProtocol.ReadAllAsync(inStream, requestBuffer, length, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); ServerLogger.Log("Parsing request"); // Parse the request into the Request data structure. using (var reader = new BinaryReader(new MemoryStream(requestBuffer), Encoding.Unicode)) { var protocolVersion = reader.ReadUInt32(); var argumentCount = reader.ReadUInt32(); var argumentsBuilder = new List <RequestArgument>((int)argumentCount); for (var i = 0; i < argumentCount; i++) { cancellationToken.ThrowIfCancellationRequested(); argumentsBuilder.Add(RequestArgument.ReadFromBinaryReader(reader)); } return(new ServerRequest(protocolVersion, argumentsBuilder)); } }
/// <summary> /// May throw exceptions if there are pipe problems. /// </summary> /// <param name="stream"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public static async Task <ServerResponse> ReadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { ServerLogger.Log("Reading response length"); // Read the response length var lengthBuffer = new byte[4]; await ServerProtocol.ReadAllAsync(stream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false); var length = BitConverter.ToUInt32(lengthBuffer, 0); // Read the response ServerLogger.Log("Reading response of length {0}", length); var responseBuffer = new byte[length]; await ServerProtocol.ReadAllAsync( stream, responseBuffer, responseBuffer.Length, cancellationToken) .ConfigureAwait(false); using (var reader = new BinaryReader(new MemoryStream(responseBuffer), Encoding.Unicode)) { var responseType = (ResponseType)reader.ReadInt32(); switch (responseType) { case ResponseType.Completed: return(CompletedServerResponse.Create(reader)); case ResponseType.MismatchedVersion: return(new MismatchedVersionServerResponse()); case ResponseType.Shutdown: return(ShutdownServerResponse.Create(reader)); case ResponseType.Rejected: return(new RejectedServerResponse()); default: throw new InvalidOperationException("Received invalid response type from server."); } } }