Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / WebServices / WebServer / server.cs
blob0e4578c5c68690122c65ed3c2c88cc3ccdf394c7
1 //
2 // server.cs: Web Server that uses ASP.NET hosting
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
8 // (C) Copyright 2004 Novell, Inc. (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.Configuration;
32 using System.Diagnostics;
33 using System.IO;
34 using System.Net;
35 using System.Reflection;
36 using System.Web.Hosting;
38 namespace Mono.ASPNET
40 public class Server
42 static void ShowVersion ()
44 Assembly assembly = Assembly.GetExecutingAssembly ();
45 string version = assembly.GetName ().Version.ToString ();
46 object [] att = assembly.GetCustomAttributes (typeof (AssemblyTitleAttribute), false);
47 //string title = ((AssemblyTitleAttribute) att [0]).Title;
48 att = assembly.GetCustomAttributes (typeof (AssemblyCopyrightAttribute), false);
49 string copyright = ((AssemblyCopyrightAttribute) att [0]).Copyright;
50 att = assembly.GetCustomAttributes (typeof (AssemblyDescriptionAttribute), false);
51 string description = ((AssemblyDescriptionAttribute) att [0]).Description;
52 Console.WriteLine ("{0} {1}\n(c) {2}\n{3}",
53 Path.GetFileName (assembly.Location), version, copyright, description);
56 static void ShowHelp ()
58 #if MODMONO_SERVER
59 Console.WriteLine ("mod-mono-server.exe is a ASP.NET server used from mod_mono.");
60 Console.WriteLine ("Usage is:\n");
61 Console.WriteLine (" mod-mono-server.exe [...]");
62 Console.WriteLine ();
63 Console.WriteLine (" The arguments --filename and --port are mutually exlusive.");
64 Console.WriteLine (" --filename file: a unix socket filename to listen on.");
65 Console.WriteLine (" Default value: /tmp/mod_mono_server");
66 Console.WriteLine (" AppSettings key name: MonoUnixSocket");
67 Console.WriteLine ();
68 #else
69 Console.WriteLine ("Beagle-XSP server is a sample server that hosts the ASP.NET runtime in a");
70 Console.WriteLine ("minimalistic HTTP server\n");
71 //Console.WriteLine ("Usage is:\n");
72 //Console.WriteLine (" xsp.exe [...]");
73 Console.WriteLine ();
74 #endif
75 Console.WriteLine (" --port N: n is the tcp port to listen on.");
76 #if MODMONO_SERVER
77 Console.WriteLine (" Default value: none");
78 #else
79 Console.WriteLine (" Default value: 8080");
80 #endif
81 Console.WriteLine (" AppSettings key name: MonoServerPort");
82 Console.WriteLine ();
83 Console.WriteLine (" --address addr: addr is the ip address to listen on.");
84 #if MODMONO_SERVER
85 Console.WriteLine (" Default value: 127.0.0.1");
86 #else
87 Console.WriteLine (" Default value: 0.0.0.0");
88 #endif
89 Console.WriteLine (" AppSettings key name: MonoServerAddress");
90 Console.WriteLine ();
91 Console.WriteLine (" --root rootdir: the server changes to this directory before");
92 Console.WriteLine (" anything else.");
93 Console.WriteLine (" Default value: current directory.");
94 Console.WriteLine (" AppSettings key name: MonoServerRootDir");
95 Console.WriteLine ();
96 Console.WriteLine (" --appconfigfile FILENAME: adds application definitions from the XML");
97 Console.WriteLine (" configuration file. See sample configuration file that");
98 Console.WriteLine (" comes with the server.");
99 Console.WriteLine (" AppSettings key name: MonoApplicationsConfigFile");
100 Console.WriteLine ();
101 Console.WriteLine (" --appconfigdir DIR: adds application definitions from all XML files");
102 Console.WriteLine (" found in the specified directory DIR. Files must have");
103 Console.WriteLine (" '.webapp' extension");
104 Console.WriteLine (" AppSettings key name: MonoApplicationsConfigDir");
105 Console.WriteLine ();
106 Console.WriteLine (" --applications APPS:");
107 Console.WriteLine (" a comma separated list of virtual directory and");
108 Console.WriteLine (" real directory for all the applications we want to manage");
109 Console.WriteLine (" with this server. The virtual and real dirs. are separated");
110 Console.WriteLine (" by a colon. Optionally you may specify virtual host name");
111 Console.WriteLine (" and a port.");
112 Console.WriteLine ();
113 Console.WriteLine (" [[hostname:]port:]VPath:realpath,...");
114 Console.WriteLine ();
115 Console.WriteLine (" Samples: /:.");
116 Console.WriteLine (" the virtual / is mapped to the current directory.");
117 Console.WriteLine ();
118 Console.WriteLine (" /blog:../myblog");
119 Console.WriteLine (" the virtual /blog is mapped to ../myblog");
120 Console.WriteLine ();
121 Console.WriteLine (" myhost.someprovider.net:/blog:../myblog");
122 Console.WriteLine (" the virtual /blog at myhost.someprovider.net is mapped to ../myblog");
123 Console.WriteLine ();
124 Console.WriteLine (" /:.,/blog:../myblog");
125 Console.WriteLine (" Two applications like the above ones are handled.");
126 Console.WriteLine (" Default value: /:.");
127 Console.WriteLine (" AppSettings key name: MonoApplications");
128 Console.WriteLine ();
129 #if MODMONO_SERVER
130 Console.WriteLine (" --terminate: gracefully terminates a running mod-mono-server instance.");
131 Console.WriteLine (" All other options but --filename or --address and --port");
132 Console.WriteLine (" are ignored if this option is provided.");
133 #endif
134 Console.WriteLine (" --nonstop: don't stop the server by pressing enter. Must be used");
135 Console.WriteLine (" when the server has no controlling terminal.");
136 Console.WriteLine ();
137 Console.WriteLine (" --version: displays version information and exits.");
138 Console.WriteLine (" --verbose: prints extra messages. Mainly useful for debugging.");
140 Console.WriteLine ();
143 [Flags]
144 enum Options {
145 NonStop = 1,
146 Verbose = 1 << 1,
147 Applications = 1 << 2,
148 AppConfigDir = 1 << 3,
149 AppConfigFile = 1 << 4,
150 Root = 1 << 5,
151 FileName = 1 << 6,
152 Address = 1 << 7,
153 Port = 1 << 8,
154 Terminate = 1 << 9,
157 static void CheckAndSetOptions (string name, Options value, ref Options options)
159 if ((options & value) != 0) {
160 ShowHelp ();
161 Console.WriteLine ();
162 Console.WriteLine ("ERROR: Option '{0}' duplicated.", name);
163 Environment.Exit (1);
166 options |= value;
167 if ((options & Options.FileName) != 0 &&
168 ((options & Options.Port) != 0 || (options & Options.Address) != 0)) {
169 ShowHelp ();
170 Console.WriteLine ();
171 Console.WriteLine ("ERROR: --port/--address and --filename are mutually exclusive");
172 Environment.Exit (1);
175 // public static int Main (string [] args)
176 public static int initXSP(string [] args, out ApplicationServer appServer)
178 bool nonstop = false;
179 bool verbose = false;
180 appServer = null;
182 Trace.Listeners.Add (new TextWriterTraceListener (Console.Out));
183 string apps = ConfigurationSettings.AppSettings ["MonoApplications"];
184 string appConfigDir = ConfigurationSettings.AppSettings ["MonoApplicationsConfigDir"];
185 string appConfigFile = ConfigurationSettings.AppSettings ["MonoApplicationsConfigFile"];
186 string rootDir = ConfigurationSettings.AppSettings ["MonoServerRootDir"];
187 object oport;
188 string ip = ConfigurationSettings.AppSettings ["MonoServerAddress"];
189 #if MODMONO_SERVER
190 string filename = ConfigurationSettings.AppSettings ["MonoUnixSocket"];
191 #endif
192 if (ip == "" || ip == null)
193 ip = "0.0.0.0";
195 oport = ConfigurationSettings.AppSettings ["MonoServerPort"];
196 if (oport == null)
197 oport = 8080;
199 Options options = 0;
200 int hash = 0;
201 for (int i = 0; i < args.Length; i++){
202 string a = args [i];
203 hash ^= args [i].GetHashCode () + i;
205 switch (a){
206 #if MODMONO_SERVER
207 case "--filename":
208 CheckAndSetOptions (a, Options.FileName, ref options);
209 filename = args [++i];
210 break;
211 case "--terminate":
212 CheckAndSetOptions (a, Options.Terminate, ref options);
213 break;
214 #endif
215 case "--port":
216 CheckAndSetOptions (a, Options.Port, ref options);
217 oport = args [++i];
218 break;
219 case "--address":
220 CheckAndSetOptions (a, Options.Address, ref options);
221 ip = args [++i];
222 break;
223 case "--root":
224 CheckAndSetOptions (a, Options.Root, ref options);
225 rootDir = args [++i];
226 break;
227 case "--applications":
228 CheckAndSetOptions (a, Options.Applications, ref options);
229 apps = args [++i];
230 break;
231 case "--appconfigfile":
232 CheckAndSetOptions (a, Options.AppConfigFile, ref options);
233 appConfigFile = args [++i];
234 break;
235 case "--appconfigdir":
236 CheckAndSetOptions (a, Options.AppConfigDir, ref options);
237 appConfigDir = args [++i];
238 break;
239 case "--nonstop":
240 nonstop = true;
241 break;
242 case "--help":
243 ShowHelp ();
244 return 0;
245 case "--version":
246 ShowVersion ();
247 return 0;
248 case "--verbose":
249 verbose = true;
250 break;
251 default:
252 Console.WriteLine ("Unknown argument: {0}", a);
253 ShowHelp ();
254 return 1;
258 #if MODMONO_SERVER
259 if (hash < 0)
260 hash = -hash;
262 string lockfile;
263 bool useTCP = ((options & Options.Port) != 0);
264 if (!useTCP) {
265 if (filename == null || filename == "")
266 filename = "/tmp/mod_mono_server";
268 if ((options & Options.Address) != 0) {
269 ShowHelp ();
270 Console.WriteLine ();
271 Console.WriteLine ("ERROR: --address without --port");
272 Environment.Exit (1);
274 lockfile = Path.Combine (Path.GetTempPath (), Path.GetFileName (filename));
275 lockfile = String.Format ("{0}_{1}", lockfile, hash);
276 } else {
277 lockfile = Path.Combine (Path.GetTempPath (), "mod_mono_TCP_");
278 lockfile = String.Format ("{0}_{1}", lockfile, hash);
280 #endif
281 IPAddress ipaddr = null;
282 ushort port;
283 try {
284 port = Convert.ToUInt16 (oport);
285 } catch (Exception) {
286 Console.WriteLine ("The value given for the listen port is not valid: " + oport);
287 return 1;
290 try {
291 ipaddr = IPAddress.Parse (ip);
292 } catch (Exception) {
293 Console.WriteLine ("The value given for the address is not valid: " + ip);
294 return 1;
297 if (rootDir != null && rootDir != "") {
298 try {
299 Environment.CurrentDirectory = rootDir;
300 } catch (Exception e) {
301 Console.WriteLine ("Error: {0}", e.Message);
302 return 1;
306 rootDir = Directory.GetCurrentDirectory ();
308 IWebSource webSource;
309 #if MODMONO_SERVER
310 if (useTCP) {
311 webSource = new ModMonoTCPWebSource (ipaddr, port, lockfile);
312 } else {
313 webSource = new ModMonoWebSource (filename, lockfile);
316 if ((options & Options.Terminate) != 0) {
317 if (verbose)
318 Console.WriteLine ("Shutting down running mod-mono-server...");
320 bool res = ((ModMonoWebSource) webSource).GracefulShutdown ();
321 if (verbose)
322 Console.WriteLine (res ? "Done." : "Failed");
324 return (res) ? 0 : 1;
327 ApplicationServer server = new ApplicationServer (webSource);
328 #else
329 webSource = new XSPWebSource (ipaddr, port);
330 ApplicationServer server = new ApplicationServer (webSource);
331 #endif
332 server.Verbose = verbose;
334 Console.WriteLine (Assembly.GetExecutingAssembly ().GetName ().Name);
335 if (apps != null)
336 server.AddApplicationsFromCommandLine (apps);
338 if (appConfigFile != null)
339 server.AddApplicationsFromConfigFile (appConfigFile);
341 if (appConfigDir != null)
342 server.AddApplicationsFromConfigDirectory (appConfigDir);
344 if (apps == null && appConfigDir == null && appConfigFile == null)
345 server.AddApplicationsFromCommandLine ("/:.");
346 #if MODMONO_SERVER
347 if (!useTCP) {
348 Console.WriteLine ("Listening on: {0}", filename);
349 } else
350 #endif
352 Console.WriteLine ("Listening on port: {0}", port);
353 Console.WriteLine ("Listening on address: {0}", ip);
356 Console.WriteLine ("Root directory: {0}", rootDir);
358 //KNV: return appServer reference to beagle to control it
359 appServer = server;
361 try {
362 if (server.Start (!nonstop) == false)
363 return 2;
365 if (!nonstop) {
366 Console.WriteLine ("Hit Return to stop the server.");
367 Console.ReadLine ();
368 server.Stop ();
370 } catch (Exception e) {
371 Console.WriteLine ("Error: {0}", e.Message);
372 return 1;
375 try { //test beagle/search.asmx is accessible:
376 string wsurl = "http://localhost:"+ oport + "/beagle/search.asmx";
377 HttpWebRequest w = (HttpWebRequest)WebRequest.Create(wsurl);
378 HttpWebResponse r = (HttpWebResponse)w.GetResponse();
379 r.Close();
381 catch (Exception e) {
382 //Console.WriteLine ("Error: {0} in starting bgXsp", e.Message);
383 //return 3;
386 return 0;