From: Konstantin Triger Date: Wed, 27 Dec 2006 13:21:51 +0000 (-0000) Subject: Implemented Servlet session management. Servlet hosting moved to Mainsoft.Web package X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=40967aa9d98e641cc93041c4fc03271c071b7be3;p=mono.git Implemented Servlet session management. Servlet hosting moved to Mainsoft.Web package svn path=/trunk/mcs/; revision=70121 --- 40967aa9d98e641cc93041c4fc03271c071b7be3 diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/BaseHttpServlet.cs index 00000000000,00000000000..e919a4ffa71 new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/BaseHttpServlet.cs @@@ -1,0 -1,0 +1,278 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++ ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++ ++using System; ++ ++using System.Configuration; ++using System.Web; ++using System.Web.Configuration; ++using System.Threading; ++using System.Web.Hosting; ++using System.IO; ++ ++using javax.servlet; ++using javax.servlet.http; ++using vmw.common; ++using java.util; ++ ++namespace Mainsoft.Web.Hosting ++{ ++ public class BaseHttpServlet : HttpServlet ++ { ++ //private AppDomain _servletDomain; ++ static LocalDataStoreSlot _servletRequestSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_REQUEST); ++ static LocalDataStoreSlot _servletResponseSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_RESPONSE); ++ static LocalDataStoreSlot _servletSlot = Thread.GetNamedDataSlot(J2EEConsts.CURRENT_SERVLET); ++ ++ public BaseHttpServlet() ++ { ++ } ++ ++ override public void init(ServletConfig config) ++ { ++ base.init(config); ++ InitServlet(config); ++ ++ } ++ ++ protected virtual void InitServlet(ServletConfig config) ++ { ++ try ++ { ++ AppDomain servletDomain = createServletDomain(config); ++ vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain); ++ ++ //GH Infromation Initizalization ++ int nowInt = DateTime.Now.ToString().GetHashCode(); ++ servletDomain.SetData(".domainId", nowInt.ToString("x")); ++ nowInt += "/".GetHashCode (); ++ servletDomain.SetData(".appId", nowInt.ToString("x")); ++ servletDomain.SetData(".appName", nowInt.ToString("x")); ++ ++ servletDomain.SetData(J2EEConsts.CLASS_LOADER, vmw.common.TypeUtils.ToClass(this).getClassLoader()); ++ servletDomain.SetData(J2EEConsts.SERVLET_CONFIG, config); ++ servletDomain.SetData(J2EEConsts.RESOURCE_LOADER, new vmw.@internal.j2ee.ServletResourceLoader(config.getServletContext())); ++ ++ config.getServletContext().setAttribute(J2EEConsts.APP_DOMAIN, servletDomain); ++ } ++ finally ++ { ++ vmw.@internal.EnvironmentUtils.cleanTLS(); ++ vmw.@internal.EnvironmentUtils.clearAppDomain(); ++ } ++ } ++ ++ override protected void service (HttpServletRequest req, HttpServletResponse resp) ++ { ++ try ++ { ++ // Very important - to update Virtual Path!!! ++ AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN); ++ servletDomain.SetData(IAppDomainConfig.APP_VIRT_DIR, req.getContextPath()); ++ servletDomain.SetData(".hostingVirtualPath", req.getContextPath()); ++ ++ // Put to the TLS current AppDomain of the servlet, so anyone can use it. ++ vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain); ++ ++ //put request to the TLS ++ Thread.SetData(_servletRequestSlot, req); ++ //put response to the TLS ++ Thread.SetData(_servletResponseSlot, resp); ++ //put the servlet object to the TLS ++ Thread.SetData(_servletSlot, this); ++ ++ ++ ++ resp.setHeader("X-Powered-By", "ASP.NET"); ++ resp.setHeader("X-AspNet-Version", "1.1.4322"); ++ ++ //PageMapper.LoadFileList(); ++ ++ resp.setContentType("text/html"); ++ HttpWorkerRequest gwr = new ServletWorkerRequest(this, req, resp); ++ HttpRuntime.ProcessRequest(gwr); ++ } ++ finally ++ { ++ HttpContext.Current = null; ++ Thread.SetData(_servletRequestSlot, null); ++ Thread.SetData(_servletResponseSlot, null); ++ Thread.SetData(_servletSlot, null); ++ vmw.@internal.EnvironmentUtils.clearAppDomain(); ++ //cleaning ++ //vmw.Utils.cleanTLS(); //clean up all TLS entries for current Thread. ++ //java.lang.Thread.currentThread().setContextClassLoader(null); ++ } ++ } ++ ++ override public void destroy() ++ { ++ try ++ { ++ AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN); ++ vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain); ++#if DEBUG ++ Console.WriteLine("Destroy of GhHttpServlet"); ++#endif ++ base.destroy(); ++ HttpRuntime.Close(); ++ vmw.@internal.EnvironmentUtils.cleanAllBeforeServletDestroy(this); ++ this.getServletContext().removeAttribute(J2EEConsts.APP_DOMAIN); ++ java.lang.Thread.currentThread().setContextClassLoader(null); ++ } ++ catch(Exception e) ++ { ++#if DEBUG ++ Console.WriteLine("ERROR in Servlet Destroy {0},{1}",e.GetType(), e.Message); ++ Console.WriteLine(e.StackTrace); ++#endif ++ } ++ finally ++ { ++ vmw.@internal.EnvironmentUtils.clearAppDomain(); ++ } ++ } ++ ++ private AppDomain createServletDomain(ServletConfig config) ++ { ++ string rootPath = J2EEUtils.GetApplicationRealPath(config); ++ AppDomainSetup domainSetup = new AppDomainSetup(); ++ string name = config.getServletName();//.getServletContextName(); ++ if (name == null) ++ name = "GH Application"; ++ domainSetup.ApplicationName = name; ++ domainSetup.ConfigurationFile = rootPath + "/Web.config"; ++ ++ AppDomain servletDomain = AppDomain.CreateDomain(name, null, domainSetup); ++ ++ ++ ++ ++ ++ //servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config)); ++ //servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath); ++ ++ servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config)); ++ servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath); ++ ++ //Set DataDirectory substitution string (http://blogs.msdn.com/dataaccess/archive/2005/10/28/486273.aspx) ++ string dataDirectory = config.getServletContext().getInitParameter ("DataDirectory"); ++ if (dataDirectory == null) ++ dataDirectory = "APP_DATA"; ++ ++ if (!Path.IsPathRooted (dataDirectory)) { ++ java.io.InputStream inputStream = config.getServletContext ().getResourceAsStream ("/WEB-INF/classes/appData.properties"); ++ string root; ++ if (inputStream != null) { ++ try { ++ Properties props = new Properties (); ++ props.load (inputStream); ++ root = props.getProperty ("root.folder"); ++ } ++ finally { ++ inputStream.close (); ++ } ++ } ++ else ++ root = config.getServletContext ().getRealPath ("/"); ++ ++ if (root == null) ++ root = String.Empty; ++ ++ dataDirectory = Path.Combine (root, dataDirectory); ++ } ++ ++ if (dataDirectory [dataDirectory.Length - 1] != Path.DirectorySeparatorChar) ++ dataDirectory += Path.DirectorySeparatorChar; ++ ++ servletDomain.SetData ("DataDirectory", dataDirectory); ++ ++ // The BaseDir is the full path to the physical dir of the app ++ // and allows the application to modify files in the case of ++ // open deployment. ++ string webApp_baseDir = config.getServletContext().getRealPath(""); ++ if (webApp_baseDir == null || webApp_baseDir == "") ++ webApp_baseDir = rootPath; ++ servletDomain.SetData(IAppDomainConfig.APP_BASE_DIR , webApp_baseDir); ++#if DEBUG ++ Console.WriteLine("Initialization of webapp " + webApp_baseDir); ++#endif ++ // Mordechai : setting the web app deserializer object. ++ servletDomain.SetData(J2EEConsts.DESERIALIZER_CONST , this.GetDeserializer()); ++ servletDomain.SetData(vmw.@internal.EnvironmentUtils.GH_DRIVER_UTILS_CONST, this.getDriverUtils()); ++ //servletDomain.SetData(".hostingVirtualPath", "/"); ++ //servletDomain.SetData(".hostingInstallDir", "/"); ++ return servletDomain; ++ } ++ ++ virtual protected vmw.@internal.io.IObjectsDeserializer GetDeserializer() ++ { ++ if (m_deseializer == null) ++ m_deseializer = new GHWebDeseserializer(); ++ return m_deseializer; ++ } ++ ++ protected vmw.@internal.io.IObjectsDeserializer m_deseializer = null; ++ /// Mordechai: This class comes to solve a problem in class deserialize ++ /// within web application. The problem is that the classloader that created ++ /// some user web class (for example aspx page) is not the class loader ++ /// that de-serialize it - thus we end with ClassDefNotFoundException. ++ /// To prevent this situation we delegate the serialization back the the ++ /// web app (which has the correct class loader...) ++ /// ++ ++ virtual protected vmw.@internal.IDriverUtils getDriverUtils() ++ { ++ //by default no driver utils, the specific servlet will override this method ++ return null; ++ } ++ } ++ ++ public class GHWebDeseserializer : vmw.@internal.io.IObjectsDeserializer ++ { ++ ++ Object vmw.@internal.io.IObjectsDeserializer.Deserialize(java.io.ObjectInputStream stream) ++ { ++ object obj = stream.readObject(); ++ return obj; ++ } ++ } ++} ++ ++namespace System.Web.GH ++{ ++ public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet ++ { ++ } ++ ++} ++ ++namespace System.Web.J2EE ++{ ++ public class BaseHttpServlet : Mainsoft.Web.Hosting.BaseHttpServlet ++ { ++ } ++ ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/BaseStaticHttpServlet.cs index 00000000000,00000000000..6b6ce7c1d2d new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/BaseStaticHttpServlet.cs @@@ -1,0 -1,0 +1,121 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++ ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++ ++using System; ++using System.IO; ++using System.Configuration; ++using System.Web.Configuration; ++using System.Threading; ++ ++using javax.servlet; ++using javax.servlet.http; ++using vmw.common; ++ ++namespace System.Web.J2EE ++{ ++ public class BaseStaticHttpServlet : HttpServlet ++ { ++ public BaseStaticHttpServlet() ++ { ++ } ++ ++ override public void init(ServletConfig config) ++ { ++ base.init(config); ++ ServletContext context = config.getServletContext(); ++ AppDir = config.getInitParameter(IAppDomainConfig.APP_DIR_NAME); ++ if (AppDir != null) { ++ AppDir = AppDir.Replace('\\', '/'); ++ if (AppDir[AppDir.Length - 1] != '/') ++ AppDir += '/'; ++ } ++ } ++ ++ override protected void service(HttpServletRequest req, HttpServletResponse resp) ++ { ++ String pathInfo = req.getRequestURI(); ++ String contextPath = req.getContextPath(); ++ if (pathInfo.Equals(contextPath) || ++ ((pathInfo.Length - contextPath.Length) == 1) && pathInfo[pathInfo.Length-1] == '/' && pathInfo.StartsWith(contextPath)) ++ pathInfo = contextPath + req.getServletPath(); ++ resp.setHeader("X-Powered-By", "ASP.NET"); ++ resp.setHeader("X-AspNet-Version", "1.1.4322"); ++ ++ ServletOutputStream hos = resp.getOutputStream(); ++ String filename = ""; ++ try ++ { ++ pathInfo = pathInfo.Substring(contextPath.Length); ++ if (pathInfo.StartsWith("/") || pathInfo.StartsWith("\\")) ++ pathInfo = pathInfo.Substring(1); ++ filename = AppDir + pathInfo; ++ resp.setContentType(this.getServletContext().getMimeType(filename)); ++ FileStream fis = null; ++ try { ++ fis = new FileStream(filename,FileMode.Open,FileAccess.Read); ++ byte[] buf = new byte[4 * 1024]; // 4K buffer ++ int bytesRead; ++ while ((bytesRead = fis.Read(buf,0,buf.Length)) != -1 && ++ bytesRead != 0) { ++ hos.write(TypeUtils.ToSByteArray(buf), 0, bytesRead); ++ } ++ } ++ finally { ++ if (fis != null) fis.Close(); ++ } ++ } ++ catch (System.IO.FileNotFoundException e) ++ { ++ resp.setStatus(404,"Object Not Found."); ++ HttpException myExp = new HttpException (404, "File '" + filename + "' not found."); ++ hos.print(((HttpException) myExp).GetHtmlErrorMessage ()); ++ hos.flush(); ++ } ++ catch(Exception e) ++ { ++ Console.WriteLine("ERROR in Static File Reading {0},{1}",e.GetType(), e.Message); ++ resp.setStatus(500); ++ HttpException myExp = new HttpException ("Exception in Reading static file", e); ++ hos.print(((HttpException) myExp).GetHtmlErrorMessage ()); ++ hos.flush(); ++ } ++ } ++ ++ override public void destroy() ++ { ++ base.destroy(); ++ } ++ ++ private string AppDir; ++ } ++} ++ ++namespace System.Web.GH ++{ ++ public class BaseStaticHttpServlet : System.Web.J2EE.BaseStaticHttpServlet ++ { ++ } ++ ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/ServletWorkerRequest.jvm.cs index 00000000000,00000000000..469e44ae5b5 new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.Hosting/ServletWorkerRequest.jvm.cs @@@ -1,0 -1,0 +1,438 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++ ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++using System; ++using System.IO; ++using System.Text; ++using System.Runtime.InteropServices; ++using System.Web.Util; ++using vmw.common; ++using System.Web.J2EE; ++using System.Collections; ++using System.Web; ++using javax.servlet; ++using javax.servlet.http; ++using System.Collections.Specialized; ++using System.Globalization; ++using System.Web.Hosting; ++ ++namespace Mainsoft.Web.Hosting { ++ [MonoTODO("Implement security demands on the path usage functions (and review)")] ++ [ComVisible (false)] ++ internal sealed class ServletWorkerRequest : HttpWorkerRequest { ++ readonly HttpServlet _HttpServlet; ++ readonly HttpServletRequest _HttpServletRequest; ++ readonly HttpServletResponse _HttpServletResponse; ++ ++ readonly string _requestUri; ++ readonly string _pathInfo; ++ ++ static readonly StringDictionary _srvVarsToHeaderMap; ++ ++ private string [][] unknownHeaders; ++ string _rawUrl; ++ ++ private HttpWorkerRequest.EndOfSendNotification _endOfSendCallback; ++ private object _endOfSendArgs; ++ ++ enum KnownServerVariable { ++ AUTH_TYPE, ++ CONTENT_LENGTH, ++ CONTENT_TYPE, ++ QUERY_STRING, ++ REMOTE_ADDR, ++ REMOTE_HOST, ++ REMOTE_USER, ++ REQUEST_METHOD, ++ REQUEST_URI, ++ SCRIPT_NAME, ++ SERVER_NAME, ++ SERVER_PORT, ++ SERVER_PROTOCOL, ++ SERVER_SOFTWARE, ++ PATH_INFO ++ }; ++ ++ static readonly Hashtable KnownServerVariableMap; ++ ++ static ServletWorkerRequest() { ++ _srvVarsToHeaderMap = new StringDictionary(); ++ _srvVarsToHeaderMap.Add("HTTP_ACCEPT", "Accept"); ++ _srvVarsToHeaderMap.Add("HTTP_REFERER", "Referer"); ++ _srvVarsToHeaderMap.Add("HTTP_ACCEPT_LANGUAGE", "Accept-Language"); ++ _srvVarsToHeaderMap.Add("HTTP_ACCEPT_ENCODING", "Accept-Encoding"); ++ _srvVarsToHeaderMap.Add("HTTP_CONNECTION", "Connection"); ++ _srvVarsToHeaderMap.Add("HTTP_HOST", "Host"); ++ _srvVarsToHeaderMap.Add("HTTP_USER_AGENT", "User-Agent"); ++ _srvVarsToHeaderMap.Add("HTTP_SOAPACTION", "SOAPAction"); ++ ++ string[] knownServerVariableNames = Enum.GetNames(typeof(KnownServerVariable)); ++ KnownServerVariableMap = CollectionsUtil.CreateCaseInsensitiveHashtable(knownServerVariableNames.Length); ++ for (int i = 0; i < knownServerVariableNames.Length; i++) ++ KnownServerVariableMap[knownServerVariableNames[i]] = (KnownServerVariable)i; ++ } ++ ++ public ServletWorkerRequest (HttpServlet servlet, HttpServletRequest req, HttpServletResponse resp) { ++ _HttpServlet = servlet; ++ _HttpServletRequest = req; ++ _HttpServletResponse = resp; ++ ++ string contextPath = req.getContextPath(); ++ string requestURI = req.getRequestURI(); ++ if (String.CompareOrdinal(requestURI, contextPath) == 0 || ++ (((requestURI.Length - contextPath.Length) == 1) && ++ requestURI[contextPath.Length] == '/' && ++ String.CompareOrdinal(requestURI, 0, contextPath, 0, contextPath.Length) == 0 )) ++ requestURI = contextPath + req.getServletPath(); ++ ++ _requestUri = Uri.UnescapeDataString(requestURI); ++ const int dotInvokeLength = 7; //".invoke".Length ++ if (_requestUri.Length > dotInvokeLength && ++ String.CompareOrdinal(".invoke", 0, _requestUri, ++ _requestUri.Length - dotInvokeLength, dotInvokeLength) == 0) { ++ ++ _requestUri = _requestUri.Substring(0, _requestUri.Length - dotInvokeLength); ++ ++ int paramNameStart = _requestUri.LastIndexOf('/'); ++ _pathInfo = _requestUri.Substring(paramNameStart, _requestUri.Length - paramNameStart); ++ } ++ } ++ ++ public HttpServlet Servlet { ++ get { ++ return _HttpServlet; ++ } ++ } ++ ++ public HttpServletRequest ServletRequest { ++ get{ ++ return _HttpServletRequest; ++ } ++ } ++ ++ public HttpServletResponse ServletResponse { ++ get{ ++ return _HttpServletResponse; ++ } ++ } ++ ++ [MonoTODO("Implement security")] ++ public override string MachineInstallDirectory { ++ get { ++ return "."; ++ } ++ } ++ ++ public override string MachineConfigPath { ++ get { return "."; } ++ } ++ ++ public override void EndOfRequest () { ++ if (_endOfSendCallback != null) ++ _endOfSendCallback(this, _endOfSendArgs); ++ } ++ ++ public override void FlushResponse (bool finalFlush) { ++ ServletOutputStream servletOutputStream = _HttpServletResponse.getOutputStream(); ++ servletOutputStream.flush(); ++ if (finalFlush) ++ servletOutputStream.close(); ++ } ++ ++ public override string GetAppPath () { ++ return _HttpServletRequest.getContextPath(); ++ } ++ public override string GetAppPathTranslated () { ++ return J2EEUtils.GetApplicationRealPath(_HttpServlet.getServletConfig());; ++ } ++ ++ public override string GetFilePath () { ++ string uri = GetUriPath(); ++ string pathInfo = GetPathInfo(); ++ if (pathInfo != null && pathInfo.Length > 0) ++ uri = uri.Substring(0, uri.Length - pathInfo.Length); ++ ++ return uri; ++ } ++ ++ public override string GetFilePathTranslated () { ++ string page = GetFilePath (); ++ ++ if (Path.DirectorySeparatorChar != '/') ++ page = page.Replace ('/', Path.DirectorySeparatorChar); ++ ++ if (page [0] == Path.DirectorySeparatorChar) ++ page = page.Substring (1); ++ ++ return Path.Combine (GetAppPathTranslated (), page); ++ } ++ ++ public override string GetHttpVerbName () { ++ return _HttpServletRequest.getMethod(); ++ } ++ ++ public override string GetHttpVersion () { ++ return _HttpServletRequest.getProtocol(); ++ } ++ ++ public override string GetLocalAddress () { ++ return _HttpServletRequest.getLocalAddr(); ++ } ++ ++ public override int GetLocalPort () { ++ return _HttpServletRequest.getLocalPort(); ++ } ++ ++ public override string GetPathInfo () { ++ string pathInfo = _pathInfo != null ? _pathInfo : _HttpServletRequest.getPathInfo(); ++ return pathInfo != null ? pathInfo : String.Empty; ++ } ++ ++ public override string GetQueryString () { ++ return _HttpServletRequest.getQueryString(); ++ } ++ ++ public override string GetRawUrl () { ++ if (_rawUrl == null) { ++ StringBuilder builder = new StringBuilder(); ++ builder.Append(GetUriPath()); ++ string pathInfo = GetPathInfo(); ++ string query = GetQueryString(); ++ if (query != null && query.Length > 0) { ++ builder.Append('?'); ++ builder.Append(query); ++ } ++ ++ _rawUrl = builder.ToString(); ++ } ++ ++ return _rawUrl; ++ } ++ ++ public override string GetRemoteAddress() { ++ return _HttpServletRequest.getRemoteAddr(); ++ } ++ ++ public override string GetRemoteName() { ++ return _HttpServletRequest.getRemoteHost(); ++ } ++ ++ ++ public override int GetRemotePort() { ++ try { ++ return _HttpServletRequest.getRemotePort(); ++ } ++ catch(Exception e) { //should catch also java.lang.Throwable ++ //if servlet API is 2.3 and below - there is no ++ //method getRemotePort in ServletRequest interface... ++ //should be described as limitation. ++ return 0; ++ } ++ } ++ ++ public override string GetServerVariable(string name) { ++ // FIXME: We need to make a proper mapping between the standard server ++ // variables and java equivalent. probably we have to have a configuration file ++ // which associates between the two. Pay a special attention on GetUnknownRequestHeader/s ++ // while implementing. Ensure that system web "common" code correctly calls each method. ++ ++ string headerName = _srvVarsToHeaderMap[name]; ++ ++ if (headerName != null) ++ return _HttpServletRequest.getHeader( headerName ); ++ ++ object knownVariable = KnownServerVariableMap[name]; ++ if (knownVariable != null) ++ return GetKnownServerVariable((KnownServerVariable)knownVariable); ++ ++ return _HttpServletRequest.getHeader( name ); ++ } ++ ++ string GetKnownServerVariable(KnownServerVariable index) { ++ switch (index) { ++ case KnownServerVariable.AUTH_TYPE : return _HttpServletRequest.getAuthType(); ++ case KnownServerVariable.CONTENT_LENGTH : return Convert.ToString(_HttpServletRequest.getContentLength()); ++ case KnownServerVariable.CONTENT_TYPE : return _HttpServletRequest.getContentType(); ++ case KnownServerVariable.QUERY_STRING : return GetQueryString(); ++ case KnownServerVariable.REMOTE_ADDR : return GetRemoteAddress(); ++ case KnownServerVariable.REMOTE_HOST : return GetRemoteName(); ++ case KnownServerVariable.REMOTE_USER : return _HttpServletRequest.getRemoteUser(); ++ case KnownServerVariable.REQUEST_METHOD : return GetHttpVerbName (); ++ case KnownServerVariable.REQUEST_URI : return GetUriPath(); ++ case KnownServerVariable.SCRIPT_NAME : return GetFilePath (); ++ case KnownServerVariable.SERVER_NAME : return GetServerName(); ++ case KnownServerVariable.SERVER_PORT : return Convert.ToString(_HttpServletRequest.getServerPort()); ++ case KnownServerVariable.SERVER_PROTOCOL : return GetHttpVersion (); ++ case KnownServerVariable.SERVER_SOFTWARE : return Servlet.getServletContext().getServerInfo(); ++ case KnownServerVariable.PATH_INFO : return GetPathInfo(); ++ default: throw new IndexOutOfRangeException("index"); ++ } ++ } ++ ++ public override string GetUriPath() { ++ return _requestUri; ++ } ++ ++ public override IntPtr GetUserToken() { ++ return IntPtr.Zero; ++ } ++ ++ public override string MapPath (string path) { ++ string appVirtualPath = GetAppPath(); ++ if (path.StartsWith(appVirtualPath)) { ++ path = path.Remove(0,appVirtualPath.Length); ++ if (path.StartsWith("/")) ++ path = path.Remove(0,1); ++ } ++ //string realPath = Servlet.getServletContext().getRealPath(path); ++ // if (Path.IsPathRooted(path)) ++ // return path; ++ // if (!path.StartsWith(IAppDomainConfig.WAR_ROOT_SYMBOL)&& ++ // !path.StartsWith("/") && !path.StartsWith("\\")&& !Path.IsPathRooted(path)) ++ // return IAppDomainConfig.WAR_ROOT_SYMBOL + "/" + path; ++ // else if (!path.StartsWith(IAppDomainConfig.WAR_ROOT_SYMBOL)&& !Path.IsPathRooted(path)) ++ // return IAppDomainConfig.WAR_ROOT_SYMBOL + path; ++ // else ++ // return path; ++ ++ if (path.StartsWith(IAppDomainConfig.WAR_ROOT_SYMBOL)) { ++ return path; ++ } ++ ++ string retVal = IAppDomainConfig.WAR_ROOT_SYMBOL; ++ ++ if (!path.StartsWith("/") && !path.StartsWith("\\")) ++ retVal += "/"; ++ ++ retVal += path; ++ ++ return retVal; ++ } ++ ++ public override void SendResponseFromFile (IntPtr handle, long offset, long length) { ++ throw new NotSupportedException(); ++ } ++ ++ public override void SendResponseFromFile (string filename, long offset, long length) { ++ using (FileStream fs = File.OpenRead (filename)) { ++ byte [] buffer = new byte [4 * 1024]; ++ ++ if (offset != 0) ++ fs.Position = offset; ++ ++ long remain = length; ++ int n; ++ while (remain > 0 && (n = fs.Read (buffer, 0, (int) Math.Min (remain, buffer.Length))) != 0){ ++ remain -= n; ++ SendResponseFromMemory(buffer, n); ++ } ++ } ++ } ++ ++ public override void SendResponseFromMemory (byte [] data, int length) { ++ sbyte [] sdata = vmw.common.TypeUtils.ToSByteArray(data); ++ _HttpServletResponse.getOutputStream().write(sdata, 0 , length); ++ } ++ ++ public override void SendStatus(int statusCode, string statusDescription) { ++ // setStatus(int, string) is deprecated ++ _HttpServletResponse.setStatus(statusCode/*, statusDescription*/); ++ } ++ ++ public override void SendUnknownResponseHeader(string name, string value) { ++ if (HeadersSent ()) ++ return; ++ ++ _HttpServletResponse.addHeader(name, value); ++ } ++ ++ public override bool HeadersSent () { ++ return _HttpServletResponse.isCommitted(); ++ } ++ ++ public override void SendCalculatedContentLength (int contentLength) { ++ _HttpServletResponse.setContentLength(contentLength); ++ } ++ ++ public override void SendKnownResponseHeader (int index, string value) { ++ SendUnknownResponseHeader (GetKnownResponseHeaderName (index), value); ++ } ++ ++ public override string GetKnownRequestHeader (int index) { ++ return GetUnknownRequestHeader(GetKnownRequestHeaderName (index)); ++ } ++ ++ public override string GetUnknownRequestHeader (string name) { ++ return _HttpServletRequest.getHeader(name); ++ } ++ ++ public override string [][] GetUnknownRequestHeaders () { ++ if (unknownHeaders == null) { ++ ArrayList pairs = new ArrayList (); ++ for (java.util.Enumeration he = _HttpServletRequest.getHeaderNames(); he.hasMoreElements() ;) { ++ string key = (string) he.nextElement(); ++ int index = HttpWorkerRequest.GetKnownRequestHeaderIndex (key); ++ if (index != -1) ++ continue; ++ pairs.Add (new string [] {key, _HttpServletRequest.getHeader(key)}); ++ } ++ ++ if (pairs.Count != 0) { ++ unknownHeaders = new string [pairs.Count][]; ++ for (int i = 0; i < pairs.Count; i++) ++ unknownHeaders [i] = (string []) pairs [i]; ++ } ++ } ++ if (unknownHeaders == null) unknownHeaders = new string [0][]; ++ ++ return unknownHeaders; ++ } ++ ++ public override int ReadEntityBody (byte [] buffer, int size) { ++ if (buffer == null || size == 0) ++ return 0; ++ sbyte [] sbuffer = vmw.common.TypeUtils.ToSByteArray(buffer); ++ int r = _HttpServletRequest.getInputStream().read(sbuffer, 0, size); ++ return (r==-1)?0:r; ++ } ++ ++ public override void SetEndOfSendNotification(System.Web.HttpWorkerRequest.EndOfSendNotification callback, object extraData) { ++ _endOfSendCallback = callback; ++ _endOfSendArgs = extraData; ++ } ++ ++ public override string GetProtocol() { ++ return _HttpServletRequest.getScheme(); ++ } ++ ++ public override string GetServerName() { ++ return _HttpServletRequest.getServerName(); ++ } ++ ++ public override bool IsSecure() { ++ return _HttpServletRequest.isSecure(); ++ } ++ } ++} ++ diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.J2EE.vmwcsproj index 35b21c56110,35b21c56110..c5168c01b1e --- a/mcs/class/Mainsoft.Web/Mainsoft.Web.J2EE.vmwcsproj +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.J2EE.vmwcsproj @@@ -1,4 -1,4 +1,4 @@@ -- ++ Debug_Java AnyCPU @@@ -99,7 -99,7 +99,7 @@@ --> -- ++ @@@ -107,14 -107,14 +107,20 @@@ ..\lib\rt.dll False -- -- ++ ++ ..\lib\j2ee.dll False -- -- ++ ++ False ++ ++ False ++ ++ ++ ++ @@@ -124,6 -124,6 +130,9 @@@ MonoTODOAttribute.cs ++ ++ ++ @@@ -132,6 -132,6 +141,14 @@@ ++ ++ ++ ++ ++ ++ ++ ++ diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ObjectInputStream.cs index 00000000000,00000000000..caea7f3a7a1 new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ObjectInputStream.cs @@@ -1,0 -1,0 +1,204 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++// Authors: ++// Vladimir Krasnov ++// Konstantin Triger ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++ ++using System; ++using java.io; ++ ++namespace Mainsoft.Web.SessionState ++{ ++ public sealed partial class ServletSessionStateStoreProvider ++ { ++ sealed class ObjectInputStream : System.IO.Stream, ObjectInput ++ { ++ readonly ObjectInput _javaObjectInput; ++ ++ public ObjectInputStream (ObjectInput stream) { ++ _javaObjectInput = stream; ++ } ++ ++ public override bool CanRead { ++ get { ++ return true; ++ } ++ } ++ ++ public override bool CanWrite { ++ get { ++ return false; ++ } ++ } ++ ++ public override bool CanSeek { ++ get { ++ return true; ++ } ++ } ++ ++ public override long Length { ++ get { ++ throw new NotSupportedException (); ++ } ++ } ++ ++ public override long Position { ++ get { ++ throw new NotSupportedException (); ++ } ++ set { ++ throw new NotSupportedException (); ++ } ++ } ++ ++ public override void Flush () { ++ throw new NotSupportedException (); ++ } ++ ++ public override long Seek (long offset, System.IO.SeekOrigin origin) { ++ if (origin == System.IO.SeekOrigin.Current) ++ return _javaObjectInput.skip (offset); ++ ++ throw new NotSupportedException (); ++ } ++ ++ public override void SetLength (long value) { ++ throw new NotSupportedException (); ++ } ++ ++ public override int Read (byte [] buffer, int offset, int count) { ++ return _javaObjectInput.read (vmw.common.TypeUtils.ToSByteArray (buffer), offset, count); ++ } ++ ++ public override void Write (byte [] buffer, int offset, int count) { ++ throw new NotSupportedException (); ++ } ++ ++ public override int ReadByte () { ++ return _javaObjectInput.read (); ++ } ++ ++ public override void Close () { ++ _javaObjectInput.close (); ++ } ++ ++ #region ObjectInput Members ++ ++ public int available () { ++ return _javaObjectInput.available (); ++ } ++ ++ public void close () { ++ _javaObjectInput.close (); ++ } ++ ++ public int read (sbyte [] __p1, int __p2, int __p3) { ++ return _javaObjectInput.read (__p1, __p2, __p3); ++ } ++ ++ public int read (sbyte [] __p1) { ++ return _javaObjectInput.read (__p1); ++ } ++ ++ public int read () { ++ return _javaObjectInput.read (); ++ } ++ ++ public object readObject () { ++ return _javaObjectInput.readObject (); ++ } ++ ++ public long skip (long __p1) { ++ return _javaObjectInput.skip (__p1); ++ } ++ ++ #endregion ++ ++ #region DataInput Members ++ ++ public bool readBoolean () { ++ return _javaObjectInput.readBoolean (); ++ } ++ ++ public sbyte readByte () { ++ return _javaObjectInput.readByte (); ++ } ++ ++ public char readChar () { ++ return _javaObjectInput.readChar (); ++ } ++ ++ public double readDouble () { ++ return _javaObjectInput.readDouble (); ++ } ++ ++ public float readFloat () { ++ return _javaObjectInput.readFloat (); ++ } ++ ++ public void readFully (sbyte [] __p1, int __p2, int __p3) { ++ _javaObjectInput.readFully (__p1, __p2, __p3); ++ } ++ ++ public void readFully (sbyte [] __p1) { ++ _javaObjectInput.readFully (__p1); ++ } ++ ++ public int readInt () { ++ return _javaObjectInput.readInt (); ++ } ++ ++ public string readLine () { ++ return _javaObjectInput.readLine (); ++ } ++ ++ public long readLong () { ++ return _javaObjectInput.readLong (); ++ } ++ ++ public short readShort () { ++ return _javaObjectInput.readShort (); ++ } ++ ++ public string readUTF () { ++ return _javaObjectInput.readUTF (); ++ } ++ ++ public int readUnsignedByte () { ++ return _javaObjectInput.readUnsignedByte (); ++ } ++ ++ public int readUnsignedShort () { ++ return _javaObjectInput.readUnsignedShort (); ++ } ++ ++ public int skipBytes (int __p1) { ++ return _javaObjectInput.skipBytes (__p1); ++ } ++ ++ #endregion ++ } ++ } ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ObjectOutputStream.cs index 00000000000,00000000000..be8c5c06864 new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ObjectOutputStream.cs @@@ -1,0 -1,0 +1,186 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++// Authors: ++// Vladimir Krasnov ++// Konstantin Triger ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++ ++using System; ++using java.io; ++ ++namespace Mainsoft.Web.SessionState ++{ ++ public sealed partial class ServletSessionStateStoreProvider ++ { ++ sealed class ObjectOutputStream : System.IO.Stream, ObjectOutput ++ { ++ readonly ObjectOutput _javaObjectOutput; ++ ++ public ObjectOutputStream (ObjectOutput stream) { ++ _javaObjectOutput = stream; ++ } ++ ++ public override bool CanRead { ++ get { ++ return false; ++ } ++ } ++ ++ public override bool CanSeek { ++ get { ++ return false; ++ } ++ } ++ ++ public override bool CanWrite { ++ get { ++ return true; ++ } ++ } ++ ++ public override void Close () { ++ _javaObjectOutput.close (); ++ } ++ ++ public override void Flush () { ++ _javaObjectOutput.flush (); ++ } ++ ++ public override long Length { ++ get { ++ throw new NotSupportedException (); ++ } ++ } ++ ++ public override long Position { ++ get { ++ throw new NotSupportedException (); ++ } ++ set { ++ throw new NotSupportedException (); ++ } ++ } ++ ++ public override long Seek (long offset, System.IO.SeekOrigin origin) { ++ throw new NotSupportedException (); ++ } ++ ++ public override void SetLength (long value) { ++ throw new NotSupportedException (); ++ } ++ ++ public override int Read (byte [] buffer, int offset, int count) { ++ throw new NotSupportedException (); ++ } ++ ++ public override void Write (byte [] buffer, int offset, int count) { ++ _javaObjectOutput.write (vmw.common.TypeUtils.ToSByteArray (buffer), offset, count); ++ } ++ ++ public override void WriteByte (byte value) { ++ _javaObjectOutput.write (value); ++ } ++ ++ public ObjectOutput NativeStream { ++ get { return _javaObjectOutput; } ++ } ++ ++ #region ObjectOutput Members ++ ++ public void close () { ++ _javaObjectOutput.close (); ++ } ++ ++ public void flush () { ++ _javaObjectOutput.flush (); ++ } ++ ++ public void write (sbyte [] __p1, int __p2, int __p3) { ++ _javaObjectOutput.write (__p1, __p2, __p3); ++ } ++ ++ public void write (sbyte [] __p1) { ++ _javaObjectOutput.write (__p1); ++ } ++ ++ public void write (int __p1) { ++ _javaObjectOutput.write (__p1); ++ } ++ ++ public void writeObject (object __p1) { ++ _javaObjectOutput.writeObject (__p1); ++ } ++ ++ #endregion ++ ++ #region DataOutput Members ++ ++ ++ public void writeBoolean (bool __p1) { ++ _javaObjectOutput.writeBoolean (__p1); ++ } ++ ++ public void writeByte (int __p1) { ++ _javaObjectOutput.writeByte (__p1); ++ } ++ ++ public void writeBytes (string __p1) { ++ _javaObjectOutput.writeBytes (__p1); ++ } ++ ++ public void writeChar (int __p1) { ++ _javaObjectOutput.writeChar (__p1); ++ } ++ ++ public void writeChars (string __p1) { ++ _javaObjectOutput.writeChars (__p1); ++ } ++ ++ public void writeDouble (double __p1) { ++ _javaObjectOutput.writeDouble (__p1); ++ } ++ ++ public void writeFloat (float __p1) { ++ _javaObjectOutput.writeFloat (__p1); ++ } ++ ++ public void writeInt (int __p1) { ++ _javaObjectOutput.writeInt (__p1); ++ } ++ ++ public void writeLong (long __p1) { ++ _javaObjectOutput.writeLong (__p1); ++ } ++ ++ public void writeShort (int __p1) { ++ _javaObjectOutput.writeShort (__p1); ++ } ++ ++ public void writeUTF (string __p1) { ++ _javaObjectOutput.writeUTF (__p1); ++ } ++ ++ #endregion ++ } ++ } ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionIDManager.cs index 00000000000,00000000000..7dad35d8549 new file mode 100755 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionIDManager.cs @@@ -1,0 -1,0 +1,47 @@@ ++using System; ++using System.Collections.Generic; ++using System.Text; ++using System.Web; ++using System.Web.SessionState; ++using javax.servlet.http; ++ ++namespace Mainsoft.Web.SessionState ++{ ++ public sealed class ServletSessionIDManager : ISessionIDManager ++ { ++ #region ISessionIDManager Members ++ ++ public string CreateSessionID (HttpContext context) { ++ return ServletSessionStateStoreProvider.GetWorkerRequest (context). ++ ServletRequest.getSession(true).getId(); ++ } ++ ++ public string GetSessionID (HttpContext context) { ++ HttpServletRequest request = ServletSessionStateStoreProvider.GetWorkerRequest (context).ServletRequest; ++ return request.isRequestedSessionIdValid () ? request.getRequestedSessionId () : null; ++ } ++ ++ public void Initialize () { ++ } ++ ++ public bool InitializeRequest (HttpContext context, bool suppressAutoDetectRedirect, out bool supportSessionIDReissue) { ++ supportSessionIDReissue = true; ++ return false; ++ } ++ ++ public void RemoveSessionID (HttpContext context) { ++ ServletSessionStateStoreProvider.GetWorkerRequest (context).ServletRequest.getSession ().invalidate (); ++ } ++ ++ public void SaveSessionID (HttpContext context, string id, out bool redirected, out bool cookieAdded) { ++ redirected = false; ++ cookieAdded = false; ++ } ++ ++ public bool Validate (string id) { ++ return true; ++ } ++ ++ #endregion ++ } ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionStateItemCollection.cs index 00000000000,00000000000..670a8ff0680 new file mode 100755 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionStateItemCollection.cs @@@ -1,0 -1,0 +1,153 @@@ ++using System; ++using System.Collections; ++using System.Collections.Generic; ++using System.Text; ++using System.Web.SessionState; ++using System.Web; ++using System.Threading; ++ ++using javax.servlet; ++using javax.servlet.http; ++ ++namespace Mainsoft.Web.SessionState ++{ ++ public sealed partial class ServletSessionStateStoreProvider ++ { ++ sealed class ServletSessionStateItemCollection : ISessionStateItemCollection, java.io.Externalizable ++ { ++ readonly ReaderWriterLock _rwLock; ++ SessionStateItemCollection _items; ++ HttpStaticObjectsCollection _staticObjects; ++ bool _needSessionPersistence; ++ ++ public ServletSessionStateItemCollection () { _rwLock = new ReaderWriterLock (); } //for deserialization ++ ++ public ServletSessionStateItemCollection(HttpContext context) : this() { ++ ++ _items = new SessionStateItemCollection (); ++ _staticObjects = new HttpStaticObjectsCollection (); ++ ++ ServletConfig config = ServletSessionStateStoreProvider.GetWorkerRequest (context).Servlet.getServletConfig (); ++ string sessionPersistance = config.getInitParameter (J2EEConsts.Enable_Session_Persistency); ++ if (sessionPersistance != null) { ++ try { ++ _needSessionPersistence = Boolean.Parse (sessionPersistance); ++ } ++ catch (Exception) { ++ _needSessionPersistence = false; ++ Console.WriteLine ("EnableSessionPersistency init param's value is invalid. the value is " + sessionPersistance); ++ } ++ } ++ } ++ ++ public HttpStaticObjectsCollection StaticObjects { ++ get { return _staticObjects; } ++ } ++ #region ISessionStateItemCollection Members ++ ++ public void Clear () { ++ _items.Clear (); ++ } ++ ++ public bool Dirty { ++ get { ++ return _items.Dirty; ++ } ++ set { ++ _items.Dirty = value; ++ } ++ } ++ ++ public System.Collections.Specialized.NameObjectCollectionBase.KeysCollection Keys { ++ get { return _items.Keys; } ++ } ++ ++ public void Remove (string name) { ++ _items.Remove (name); ++ } ++ ++ public void RemoveAt (int index) { ++ _items.RemoveAt (index); ++ } ++ ++ public object this [int index] { ++ get { ++ return _items [index]; ++ } ++ set { ++ _items [index] = value; ++ } ++ } ++ ++ public object this [string name] { ++ get { ++ return _items [name]; ++ } ++ set { ++ _items [name] = value; ++ } ++ } ++ ++ #endregion ++ ++ #region ICollection Members ++ ++ public void CopyTo (Array array, int index) { ++ ((ICollection) _items).CopyTo (array, index); ++ } ++ ++ public int Count { ++ get { return ((ICollection) _items).Count; } ++ } ++ ++ public bool IsSynchronized { ++ get { return ((ICollection) _items).IsSynchronized; } ++ } ++ ++ public object SyncRoot { ++ get { return ((ICollection) _items).SyncRoot; } ++ } ++ ++ #endregion ++ ++ #region IEnumerable Members ++ ++ public System.Collections.IEnumerator GetEnumerator () { ++ return ((IEnumerable) _items).GetEnumerator (); ++ } ++ ++ #endregion ++ ++ #region Externalizable Members ++ ++ public void readExternal (java.io.ObjectInput input) { ++ lock (this) { ++ _needSessionPersistence = input.readBoolean (); ++ if (!_needSessionPersistence) //noting has been written ++ return; ++ ++ ObjectInputStream ms = new ObjectInputStream (input); ++ System.IO.BinaryReader br = new System.IO.BinaryReader (ms); ++ _items = SessionStateItemCollection.Deserialize (br); ++ _staticObjects = HttpStaticObjectsCollection.Deserialize (br); ++ } ++ } ++ ++ public void writeExternal (java.io.ObjectOutput output) { ++ lock (this) { ++ output.writeBoolean (_needSessionPersistence); ++ if (!_needSessionPersistence) ++ //indicates that there is nothing to serialize for this object ++ return; ++ ++ ObjectOutputStream ms = new ObjectOutputStream (output); ++ System.IO.BinaryWriter bw = new System.IO.BinaryWriter (ms); ++ _items.Serialize (bw); ++ _staticObjects.Serialize (bw); ++ } ++ } ++ ++ #endregion ++ } ++ } ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionStateStoreProvider.cs index 00000000000,00000000000..4b6b2cfb61c new file mode 100755 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/ServletSessionStateStoreProvider.cs @@@ -1,0 -1,0 +1,78 @@@ ++using System; ++using System.Collections.Generic; ++using System.Text; ++using System.Web.SessionState; ++using System.Web; ++using System.Web.Hosting; ++using javax.servlet; ++using javax.servlet.http; ++using Mainsoft.Web.Hosting; ++ ++namespace Mainsoft.Web.SessionState ++{ ++ public sealed partial class ServletSessionStateStoreProvider : SessionStateStoreProviderBase ++ { ++ public override SessionStateStoreData CreateNewStoreData (HttpContext context, int timeout) { ++ ServletSessionStateItemCollection sessionState = new ServletSessionStateItemCollection (context); ++ return new SessionStateStoreData ( ++ sessionState, ++ sessionState.StaticObjects, ++ timeout); ++ //return new SessionStateStoreData (new SessionStateItemCollection (), ++ // SessionStateUtility.GetSessionStaticObjects (context), ++ // timeout); ++ } ++ ++ static internal ServletWorkerRequest GetWorkerRequest (HttpContext context) { ++ IServiceProvider sp = (IServiceProvider) context; ++ return (ServletWorkerRequest) sp.GetService (typeof (HttpWorkerRequest)); ++ } ++ ++ public override void CreateUninitializedItem (HttpContext context, string id, int timeout) { ++ //HttpSession session = GetWorker(context).ServletRequest.getSession (false); //.setMaxInactiveInterval (timeout * 60); ++ } ++ ++ public override void Dispose () { ++ ++ } ++ ++ public override void EndRequest (HttpContext context) { ++ } ++ ++ public override SessionStateStoreData GetItem (HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { ++ locked = false; ++ lockAge = TimeSpan.Zero; ++ lockId = null; ++ actions = SessionStateActions.None; ++ if (id == null) ++ return null; ++ return (SessionStateStoreData) GetWorkerRequest (context).ServletRequest.getSession (false).getAttribute (J2EEConsts.SESSION_STATE); ++ } ++ ++ public override SessionStateStoreData GetItemExclusive (HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { ++ return GetItem (context, id, out locked, out lockAge, out lockId, out actions); ++ } ++ ++ public override void InitializeRequest (HttpContext context) { ++ } ++ ++ public override void ReleaseItemExclusive (HttpContext context, string id, object lockId) { ++ } ++ ++ public override void RemoveItem (HttpContext context, string id, object lockId, SessionStateStoreData item) { ++ GetWorkerRequest (context).ServletRequest.getSession (false).setAttribute (J2EEConsts.SESSION_STATE, null); ++ } ++ ++ public override void ResetItemTimeout (HttpContext context, string id) { ++ //Java does this for us ++ } ++ ++ public override void SetAndReleaseItemExclusive (HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { ++ GetWorkerRequest (context).ServletRequest.getSession (false).setAttribute (J2EEConsts.SESSION_STATE, item.Items); ++ } ++ ++ public override bool SetItemExpireCallback (SessionStateItemExpireCallback expireCallback) { ++ throw new Exception (); ++ } ++ } ++} diff --cc mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/SessionListener.cs index 00000000000,00000000000..774f3c4f2aa new file mode 100644 --- /dev/null +++ b/mcs/class/Mainsoft.Web/Mainsoft.Web.SessionState/SessionListener.cs @@@ -1,0 -1,0 +1,92 @@@ ++// ++// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com) ++// ++ ++// ++// Permission is hereby granted, free of charge, to any person obtaining ++// a copy of this software and associated documentation files (the ++// "Software"), to deal in the Software without restriction, including ++// without limitation the rights to use, copy, modify, merge, publish, ++// distribute, sublicense, and/or sell copies of the Software, and to ++// permit persons to whom the Software is furnished to do so, subject to ++// the following conditions: ++// ++// The above copyright notice and this permission notice shall be ++// included in all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++// ++ ++using System; ++using System.Web.SessionState; ++using System.Reflection; ++using javax.servlet.http; ++ ++namespace Mainsoft.Web.Hosting ++{ ++ /// ++ /// Summary description for Class1. ++ /// ++ public class SessionListener: javax.servlet.http.HttpSessionListener ++ { ++ private MethodInfo method; ++ private bool firstTime = true; ++ public SessionListener() ++ { ++ } ++ ++ public void sessionCreated(HttpSessionEvent se) ++ { ++ } ++ ++ public void sessionDestroyed(HttpSessionEvent se) ++ { ++ object o = se.getSession().getAttribute(J2EEConsts.SESSION_STATE); ++ if (o == null) ++ return; ++ AppDomain servletDomain = (AppDomain)se.getSession().getServletContext().getAttribute(J2EEConsts.APP_DOMAIN); ++ vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain); ++ try ++ { ++ //HttpApplicationFactory.InvokeSessionEnd(o); ++ } ++#if DEBUG ++ catch (Exception e) ++ { ++ Console.WriteLine(e.Message); ++ Console.WriteLine(e.StackTrace); ++ } ++#endif ++ finally ++ { ++ vmw.@internal.EnvironmentUtils.clearAppDomain(); ++ } ++ } ++ } ++} ++ ++namespace System.Web.GH ++{ ++ /// ++ /// Summary description for Class1. ++ /// ++ public class SessionListener : Mainsoft.Web.Hosting.SessionListener ++ { ++ } ++} ++ ++namespace System.Web.J2EE ++{ ++ /// ++ /// Summary description for Class1. ++ /// ++ public class SessionListener : Mainsoft.Web.Hosting.SessionListener ++ { ++ } ++}