/* * Copyright (c) 2003, 2004 The University of Wroclaw. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ namespace Sioux { using Nemerle.Collections; using Nemerle.Xml; using System; using System.IO; using System.Reflection; using System.Net.Sockets; public class AppChooser : Application { public override HandleRequest (request : Request, response : Response) : void { this.request = request; this.response = response; def config = Httpd.GetConfig(); match (request.RequestInfo) { | RequestInfo.Post (url, request_params,_a) | RequestInfo.DynamicGet (url, request_params) => { def url1 = url.Substring (1); def (_,url1,_) = split_unique_at ('/' , url1); def (app_name,_,_) = split_unique_at ('/' , url1); def app_file = config.Get("server/webapps_dir") + "/" + app_name + ".dll"; if(app_name == "") response.WriteNotFound(); else if(app_name==url1) response.WriteRedirect(url + "/" + ( match(request.RequestInfo) { | RequestInfo.DynamicGet(_,_) => construct_param_string(request_params) | _ => "" }) ) else { def app_type = typeof (Application); if(File.Exists(app_file)) { try { assembly=Assembly.LoadFrom(app_file); def types = assembly.GetTypes(); mutable i = 0; while(i < types.Length) { when(types[i].IsSubclassOf(app_type)) { request.CutRequestUrl(); if(Httpd.ContainsApplication(app_name)) { application = Option.UnSome(Httpd.GetApplication(app_name)); application.HandleRequest(request,response) } else { application = (Activator.CreateInstance(types[i]) :> Application); Httpd.AddApplication(app_name,application); application.HandleRequest(request,response) } i=types.Length; } i=i+1; } } catch { | _ is BadImageFormatException => () | _ is FileNotFoundException => () } } else response.WriteNotFound(); } } | _ => ReportInternalError ("invalid request type in HandleRequest") }; } /** * Splits a string given a separator character. Checks if the split was * unique -- or, if the separator occured exactly once in the original * string. */ private split_unique_at (separator : char,str : string) : string * string * bool { def pos = str.IndexOf (separator); def (l, r) = if (pos != -1) (str.Substring (0, pos), str.Substring (pos + 1)) else (str, ""); def validity = l.IndexOf (separator) == -1 && r.IndexOf (separator) == -1; (l, r, validity) } private construct_param_string(lst : list [string * string]) : string { def loop(lst) : string { | [] => "" | (name,value):: rest => name + "=" + value + loop (rest) } if (lst is _ :: _) "?" + loop(lst) else "" } /* -- PRIVATE FIELDS ------------------------------------------------------ */ private mutable assembly : Assembly; private mutable application : Application; } }