singrdk/base/Applications/cassini/Main.cs

239 lines
8.5 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
//------------------------------------------------------------------------------
// <copyright company='Microsoft Corporation'>
// Copyright (c) Microsoft Corporation. All rights reserved.
// Information Contained Herein is Proprietary and Confidential.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
using Microsoft.VisualStudio.WebHost;
using System.Globalization;
using Microsoft.Singularity;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.VisualStudio.WebServer {
[ConsoleCategory(HelpMessage="cassini [options] A web server",
DefaultAction=true)]
internal sealed class Parameters
{
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[BoolParameter( "v", Default=false , HelpMessage="Verbose")]
internal bool verbose;
[BoolParameter( "s", Default=false , HelpMessage="Silent")]
internal bool silent;
[BoolParameter( "quitURL", Default=false , HelpMessage="Allow special URL to terminate")]
internal bool quitURL;
[StringParameter( "port", Default=null , HelpMessage="Port ID to listen to")]
internal string portString;
[StringParameter( "vpath", Default="", HelpMessage="Root of Virtual Path")]
internal string virtualPath;
[StringParameter( "client", Default="", HelpMessage="Client IP")]
internal string client;
[StringParameter( "apparg", Default="", HelpMessage="Arg to pass to client app")]
internal string appArg;
[StringParameter( "app", Mandatory=true, Default="", HelpMessage="Name of the app to run")]
internal string app;
reflective internal Parameters();
internal int AppMain() {
return WebServerApp.AppMain(this);
}
}
public sealed class WebServerApp {
internal static int AppMain(Parameters! config) {
bool verbose = config.verbose;
bool silent = config.silent;
string virtualPath = config.virtualPath;
if (virtualPath != null) {
virtualPath = virtualPath.Trim();
}
if ((virtualPath == null) || (virtualPath.Length == 0)) {
virtualPath = "/";
}
else {
if (virtualPath.StartsWith("/") == false) {
if (!silent) {
ShowUsage();
}
return -1;
}
}
string physicalPath = "\\";
/*
HACKHACK FIXME: the file system is not wired up
in Singularity; avoid using it!
string physicalPath = (string)commandLine.Options["path"];
if (physicalPath != null) {
physicalPath = physicalPath.Trim();
}
if ((physicalPath == null) || (physicalPath.Length == 0)) {
if (!silent) {
ShowUsage();
}
return -1;
}
else {
if (Directory.Exists(physicalPath) == false) {
if (!silent) {
ShowMessage("The physical path '"+ physicalPath + "' does not exist!");
}
return -2;
}
// added this to resolve paths like "."
physicalPath = Path.GetFullPath(physicalPath);
}
*/
int port = 0;
string portText = config.portString;
if (portText != null) {
portText = portText.Trim();
}
if ((portText != null) && (portText.Length != 0)) {
try {
port = Int32.Parse(portText);
if ((port < 1) || (port > 65535)) {
if (!silent) {
ShowUsage();
}
return -1;
}
}
catch {
if (!silent) {
ShowMessage("Invalid port '" + portText + "'");
}
return -3;
}
}
else {
port = 80;
}
// clientIP was added so that we could test using Cassini remotely on
// lab machines. This now allows the client to be localhost or clientIP.
string clientIP = config.client;
if (clientIP != null) {
clientIP = clientIP.Trim();
}
if ((clientIP == null) || (clientIP.Length == 0)) {
clientIP = "localhost";
}
//
// Singularity-specific initialization
//
string webApp = config.app;
bool quitURL = config.quitURL;
// FIXME: should generalize this so more than one arg can be passed to
// the webapp!
string[] appArgs = null;
if (config.appArg != null) {
appArgs = new string[1];
appArgs[0] = config.appArg;
}
if ((webApp == null) || (webApp.Length == 0)) {
webApp = "HelloWebApp.x86";
}
webApp.Trim();
if (!Dispatcher.Initialize(webApp, appArgs, verbose, quitURL))
{
if (!silent) {
ShowMessage("Invalid web application name \"" + webApp + "\"");
return -5;
}
}
// ====================
// Actually start the server below
// ===================
try {
Server server = new Server(port, virtualPath, physicalPath, clientIP);
server.Start();
String s1 = String.Format( Environment.NewLine +
"Running Web Server on port {0}." + Environment.NewLine + Environment.NewLine +
"Application '{1}' is mapped to '{2}'." + Environment.NewLine + Environment.NewLine,
port, virtualPath, physicalPath);
String s2 = String.Format( "http://localhost:{0}{1}",
port, virtualPath);
if (!s2.EndsWith("/"))
s2 += "/";
Console.WriteLine(s1+s2+Environment.NewLine);
// Currently no console-read support in Singularity. Run forever!
//Console.WriteLine("Hit Enter to stop the server");
//Console.ReadLine();
//server.Stop();
}
catch (Exception ex) {
if (!silent) {
ShowMessage("Error opening port " + port + ": " + ex.Message);
}
return -5;
}
return 0;
}
private static void ShowUsage() {
string usageString;
usageString = "Invalid usage.\n\n";
usageString += "cassini [options]\n";
usageString += "Options:\n";
usageString += " -app:<application> run application.\n";
usageString += " -apparg:<argument> supply argument to application.\n";
usageString += " -path:<physicalpath>\n";
usageString += " -port:<port>\n";
usageString += " -quitURL quit if URL ending in \"quit\" is received.\n";
usageString += " [-silent]\n";
usageString += " [-verbose] show files served\n";
usageString += " [-vpath:<virtualpath>]\n";
usageString += " [-client:<clientIP>]\n";
ShowMessage(usageString);
}
private static void ShowMessage(String msg) {
Console.WriteLine("Visual Web Developer Web Server:\n" + msg);
}
}
}