Skip to content

Instantly share code, notes, and snippets.

@alexbeletsky
Created October 3, 2011 17:06
Show Gist options
  • Save alexbeletsky/1259608 to your computer and use it in GitHub Desktop.
Save alexbeletsky/1259608 to your computer and use it in GitHub Desktop.
Running SSH under web application
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Diagnostics;
using System.IO;
// Please try to run both: Cassini and IIS.
// For IIS select Application Pool with Process Identity == Your identity
//
// Expected output:
// Hi you_github_accout! You've successfully authenticated, but GitHub does not provide shell access.
//
// Actual output (Cassini):
// Hi you_github_accout! You've successfully authenticated, but GitHub does not provide shell access.
//
// Actual output (IIS):
// HANGS UP
namespace SshDiagnose.Controllers {
public class HomeController : Controller {
class CommandOutputReceiver {
private readonly TextWriter SynchronizedOutputWriter;
private readonly TextWriter SynchronizedErrorWriter;
private readonly TextWriter SynchronizedCombinedWriter;
private readonly StringWriter OutputWriter;
private readonly StringWriter ErrorWriter;
private readonly StringWriter CombinedWriter;
public CommandOutputReceiver() {
OutputWriter = new StringWriter();
SynchronizedOutputWriter = TextWriter.Synchronized(OutputWriter);
ErrorWriter = new StringWriter();
SynchronizedErrorWriter = TextWriter.Synchronized(ErrorWriter);
CombinedWriter = new StringWriter();
SynchronizedCombinedWriter = TextWriter.Synchronized(CombinedWriter);
}
public void OutputDataReceived(object sender, DataReceivedEventArgs e) {
SynchronizedOutputWriter.WriteLine(e.Data);
SynchronizedCombinedWriter.WriteLine(e.Data);
}
public void ErrorDataReceived(object sender, DataReceivedEventArgs e) {
SynchronizedErrorWriter.WriteLine(e.Data);
SynchronizedCombinedWriter.WriteLine(e.Data);
}
public string Output {
get {
return OutputWriter.ToString();
}
}
public string Error {
get {
return ErrorWriter.ToString();
}
}
public string ErrorAndOutput {
get {
return CombinedWriter.ToString();
}
}
}
public ActionResult Index() {
var output = new CommandOutputReceiver();
var process = CreateProcess("cmd", "/C ssh -n -T git@github.com", output);
RunProcess(process);
return new ContentResult() { Content = output.ErrorAndOutput };
}
private void RunProcess(Process p) {
ConsoleCancelEventHandler killOnCtrlC = (sender, cancelEvent) => p.Kill();
p.Start();
System.Console.CancelKeyPress += killOnCtrlC;
try {
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();
}
finally {
System.Console.CancelKeyPress -= killOnCtrlC;
}
}
private Process CreateProcess(string commandName, string commandArgumentsForLogging, CommandOutputReceiver output) {
var processInfo = new ProcessStartInfo(commandName, commandArgumentsForLogging);
processInfo.CreateNoWindow = true;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.UseShellExecute = false;
processInfo.ErrorDialog = false;
var p = new Process { StartInfo = processInfo };
p.ErrorDataReceived += output.ErrorDataReceived;
p.OutputDataReceived += output.OutputDataReceived;
return p;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment