/// <summary> /// Convertes the handler response into a <see cref="ProfileResponse"/>. /// </summary> /// <returns>The <see cref="ProfileResponse"/>.</returns> internal ProfileResponse ToResponse() { if (Status != ProfileStatus.OK) { return(ProfileResponse.CreateError(Status, Error)); } else { return(ProfileResponse.Create(Value)); } }
/// <summary> /// Handles incoming client connections on a background thread. /// </summary> /// <param name="pipeIndexObject">Passes as the index into the [pipes] array this thread will use for its server side pipe.</param> private void ServerThread(object pipeIndexObject) { try { var pipeIndex = (int)pipeIndexObject; while (true) { lock (syncLock) { if (disposing) { // The server is shutting down, so exit the thread. return; } if (pipes[pipeIndex] != null) { pipes[pipeIndex].Dispose(); pipes[pipeIndex] = null; } #pragma warning disable CA1416 pipes[pipeIndex] = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumberOfServerInstances: threads.Length, PipeTransmissionMode.Message, PipeOptions.CurrentUserOnly); #pragma warning restore CA1416 } var pipe = pipes[pipeIndex]; pipe.WaitForConnection(); if (disposing) { return; } var reader = new StreamReader(pipe); var writer = new StreamWriter(pipe); writer.AutoFlush = true; var requestLine = reader.ReadLine(); var request = (ProfileRequest)null; var handlerResult = (ProfileHandlerResult)null; try { request = ProfileRequest.Parse(requestLine); } catch (FormatException) { // Report an malformed request to the client and then continue // listening for the next request. writer.WriteLine(ProfileResponse.CreateError(ProfileStatus.BadRequest, "Malformed request")); return; } if (GetIsReady != null) { handlerResult = GetIsReady(); if (handlerResult != null) { writer.WriteLine(handlerResult.ToResponse()); #pragma warning disable CA1416 pipe.WaitForPipeDrain(); #pragma warning restore CA1416 pipe.Dispose(); pipes[pipeIndex] = null; continue; } } request.Args.TryGetValue("name", out var name); request.Args.TryGetValue("vault", out var vault); request.Args.TryGetValue("masterpassword", out var masterPassword); try { switch (request.Command) { case "GET-PROFILE-VALUE": if (name == null) { handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.MissingArg, $"GET-PROFILE-VALUE: [name] argument is required."); break; } handlerResult = GetProfileValueHandler(request, name); break; case "GET-SECRET-PASSWORD": if (name == null) { handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.MissingArg, $"GET-SECRET-PASSWORD: [name] argument is required."); break; } handlerResult = GetSecretPasswordHandler(request, name, vault, masterPassword); break; case "GET-SECRET-VALUE": if (name == null) { handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.MissingArg, $"GET-SECRET-VALUE: [name] argument is required."); break; } handlerResult = GetSecretValueHandler(request, name, vault, masterPassword); break; case "CALL": if (CallHandler == null) { handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.BadCommand, $"Server has no call handler."); } else { handlerResult = CallHandler(request); } break; default: handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.BadCommand, $"Unexpected command: {request.Command}"); break; } } catch (Exception e) { handlerResult = ProfileHandlerResult.CreateError(request, ProfileStatus.BadCommand, NeonHelper.ExceptionError(e)); } writer.WriteLine(handlerResult.ToResponse()); #pragma warning disable CA1416 pipe.WaitForPipeDrain(); #pragma warning restore CA1416 pipe.Disconnect(); } } catch { // Handle all exceptions by exiting the thread. return; } }