private async Task <ConnectionData> HandleMismatchedVersionRequest(CancellationToken cancellationToken)
        {
            var response = new MismatchedVersionBuildResponse();
            await response.WriteAsync(_stream, cancellationToken).ConfigureAwait(false);

            return(new ConnectionData(CompletionReason.CompilationNotStarted));
        }
예제 #2
0
        /// <summary>
        /// May throw exceptions if there are pipe problems.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <BuildResponse> ReadAsync(Stream stream, CancellationToken cancellationToken)
        {
            CompilerServerLogger.Log("Reading response length");
            // Read the response length
            var lengthBuffer = new byte[4];
            await BuildProtocolConstants.ReadAllAsync(stream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);

            var length = BitConverter.ToUInt32(lengthBuffer, 0);

            // Read the response
            CompilerServerLogger.Log("Reading response of length {0}", length);
            var responseBuffer = new byte[length];
            await BuildProtocolConstants.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(CompletedBuildResponse.Create(reader));

                case ResponseType.MismatchedVersion:
                    return(MismatchedVersionBuildResponse.Create(reader));

                default:
                    throw new InvalidOperationException("Received invalid response type from server.");
                }
            }
        }
예제 #3
0
        internal async Task <CompletionData> ProcessAsync(
            Task <IClientConnection> clientConnectionTask,
            bool allowCompilationRequests       = true,
            CancellationToken cancellationToken = default)
        {
            try
            {
                return(await ProcessCore().ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                CompilerServerLogger.LogException(ex, $"Error processing request for client");
                return(CompletionData.RequestError);
            }

            async Task <CompletionData> ProcessCore()
            {
                using var clientConnection = await clientConnectionTask.ConfigureAwait(false);

                var request = await clientConnection.ReadBuildRequestAsync(cancellationToken).ConfigureAwait(false);

                if (request.ProtocolVersion != BuildProtocolConstants.ProtocolVersion)
                {
                    var response = new MismatchedVersionBuildResponse();
                    await clientConnection.WriteBuildResponseAsync(response, cancellationToken).ConfigureAwait(false);

                    return(CompletionData.RequestCompleted);
                }

                if (!string.Equals(request.CompilerHash, BuildProtocolConstants.GetCommitHash(), StringComparison.OrdinalIgnoreCase))
                {
                    var response = new IncorrectHashBuildResponse();
                    await clientConnection.WriteBuildResponseAsync(response, cancellationToken).ConfigureAwait(false);

                    return(CompletionData.RequestCompleted);
                }

                if (request.Arguments.Count == 1 && request.Arguments[0].ArgumentId == BuildProtocolConstants.ArgumentId.Shutdown)
                {
                    var id       = Process.GetCurrentProcess().Id;
                    var response = new ShutdownBuildResponse(id);
                    await clientConnection.WriteBuildResponseAsync(response, cancellationToken).ConfigureAwait(false);

                    return(new CompletionData(CompletionReason.RequestCompleted, shutdownRequested: true));
                }

                if (!allowCompilationRequests)
                {
                    var response = new RejectedBuildResponse("Compilation not allowed at this time");
                    await clientConnection.WriteBuildResponseAsync(response, cancellationToken).ConfigureAwait(false);

                    return(CompletionData.RequestCompleted);
                }

                return(await ProcessCompilationRequestAsync(clientConnection, request, cancellationToken).ConfigureAwait(false));
            }
        }