This should fix #76928. This fix incorporates ideas from a patch
[mono.git] / mcs / class / System.Web / System.Web.J2EE / BaseHttpServlet.cs
1 //
2 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
3 //
4
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //
25
26 using System;
27
28 using System.Configuration;
29 using System.Web.Configuration;
30 using System.Threading;
31 using System.Web.Hosting;
32
33 using javax.servlet;
34 using javax.servlet.http;
35 using vmw.common;
36
37 namespace System.Web.J2EE
38 {
39         public class BaseHttpServlet : HttpServlet
40         {
41                 //private AppDomain _servletDomain;
42                 static LocalDataStoreSlot _servletRequestSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_REQUEST);
43                 static LocalDataStoreSlot _servletResponseSlot = Thread.GetNamedDataSlot(J2EEConsts.SERVLET_RESPONSE);
44                 static LocalDataStoreSlot _servletSlot = Thread.GetNamedDataSlot(J2EEConsts.CURRENT_SERVLET);
45
46
47                 public BaseHttpServlet()
48                 {
49                 }
50
51                 override public void init(ServletConfig config)
52                 {
53                         base.init(config);
54                         InitServlet(config);
55                         
56                 }
57
58                 protected virtual void InitServlet(ServletConfig config)
59                 {
60                         try 
61                         {
62                                 AppDomain servletDomain = createServletDomain(config);
63
64                                 //GH Infromation Initizalization
65                                 servletDomain.SetData(J2EEConsts.CLASS_LOADER, vmw.common.TypeUtils.ToClass(this).getClassLoader());
66                                 servletDomain.SetData(J2EEConsts.SERVLET_CONFIG, config);
67                                 servletDomain.SetData(J2EEConsts.RESOURCE_LOADER, new vmw.@internal.j2ee.ServletResourceLoader(config.getServletContext()));
68
69                                 config.getServletContext().setAttribute(J2EEConsts.APP_DOMAIN, servletDomain);
70                         }
71                         finally 
72                         {
73                                 vmw.@internal.EnvironmentUtils.cleanTLS();
74                         }
75                 }
76
77                 override protected void service(HttpServletRequest req, HttpServletResponse resp)
78                 {
79                         try 
80                         {
81                                 // Very important - to update Virtual Path!!!
82                                 AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN);
83                                 servletDomain.SetData(IAppDomainConfig.APP_VIRT_DIR, req.getContextPath());
84                                 servletDomain.SetData(".hostingVirtualPath", req.getContextPath());
85                                 //put request to the TLS
86                                 Thread.SetData(_servletRequestSlot, req);
87                                 //put response to the TLS
88                                 Thread.SetData(_servletResponseSlot, resp);
89                                 //put the servlet object to the TLS
90                                 Thread.SetData(_servletSlot, this);
91                                 // Put to the TLS current AppDomain of the servlet, so anyone can use it.
92                                 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
93                                 resp.setHeader("X-Powered-By", "ASP.NET");
94                                 resp.setHeader("X-AspNet-Version", "1.1.4322");
95
96 //                              PageMapper.LoadFileList();
97
98                                 resp.setContentType("text/html");
99                                 HttpWorkerRequest gwr = new ServletWorkerRequest(this, req, resp, resp.getOutputStream());
100                                 HttpRuntime.ProcessRequest(gwr);
101                         }
102                         finally 
103                         {
104                                 HttpContext.Current = null;
105                                 Thread.SetData(_servletRequestSlot, null);
106                                 Thread.SetData(_servletResponseSlot, null);
107                                 Thread.SetData(_servletSlot, null);
108                                 vmw.@internal.EnvironmentUtils.clearAppDomain();
109                                 //cleaning
110                                 //vmw.Utils.cleanTLS(); //clean up all TLS entries for current Thread.
111                                 //java.lang.Thread.currentThread().setContextClassLoader(null);
112                         }
113                 }
114
115                 override public void destroy()
116                 {
117                         try 
118                         {
119                                 AppDomain servletDomain = (AppDomain)this.getServletContext().getAttribute(J2EEConsts.APP_DOMAIN);
120                                 vmw.@internal.EnvironmentUtils.setAppDomain(servletDomain);
121                                 Console.WriteLine("Destroy of GhHttpServlet");
122                                 base.destroy();
123                                 HttpRuntime.Close();
124                                 vmw.@internal.EnvironmentUtils.cleanAllBeforeServletDestroy(this);
125                                 this.getServletContext().removeAttribute(J2EEConsts.APP_DOMAIN);
126                                 java.lang.Thread.currentThread().setContextClassLoader(null);
127                         }
128                         catch(Exception e) 
129                         {
130                                 Console.WriteLine("ERROR in Servlet Destroy {0},{1}",e.GetType(), e.Message);
131                                 Console.WriteLine(e.StackTrace);
132                         }
133                         finally
134                         {
135                                 vmw.@internal.EnvironmentUtils.clearAppDomain();
136                         }
137                 }
138
139                 private AppDomain createServletDomain(ServletConfig config)
140                 {
141                                 string rootPath = J2EEUtils.GetApplicationRealPath(config);
142                                 AppDomainSetup domainSetup = new AppDomainSetup();
143                                 string name = config.getServletName();//.getServletContextName();
144                                 if (name == null)
145                                         name = "GH Application";
146                                 domainSetup.ApplicationName = name;
147                                 domainSetup.ConfigurationFile = rootPath + "/Web.config";
148
149                                 AppDomain servletDomain = AppDomain.CreateDomain(name, null, domainSetup);
150                                 int nowInt = DateTime.Now.ToString().GetHashCode();
151                                 servletDomain.SetData(".domainId", nowInt.ToString("x"));
152                                 nowInt += "/".GetHashCode ();
153                                 servletDomain.SetData(".appId", nowInt.ToString("x"));
154                                 servletDomain.SetData(".appName", nowInt.ToString("x"));
155                                 //servletDomain.SetData(".appPath", "/"); - Only for Exe
156                                 //servletDomain.SetData(".appVPath", "/"); - Only for Exe
157                 
158                                 servletDomain.SetData(IAppDomainConfig.APP_PHYS_DIR, J2EEUtils.GetApplicationPhysicalPath(config));
159                                 servletDomain.SetData(IAppDomainConfig.WEB_APP_DIR, rootPath);
160
161                                 // The BaseDir is the full path to the physical dir of the app
162                                 // and allows the application to modify files in the case of
163                                 // open deployment.
164                                 string webApp_baseDir = config.getServletContext().getRealPath("");
165                                 if (webApp_baseDir == null || webApp_baseDir == "")
166                                         webApp_baseDir = rootPath;
167                                 servletDomain.SetData(IAppDomainConfig.APP_BASE_DIR , webApp_baseDir);
168                                 Console.WriteLine("Initialization of webapp " + webApp_baseDir);
169
170                                 // Mordechai : setting the web app deserializer object.
171                                 servletDomain.SetData(J2EEConsts.DESERIALIZER_CONST , this.GetDeserializer());
172
173                                 //servletDomain.SetData(".hostingVirtualPath", "/");
174                                 servletDomain.SetData(".hostingInstallDir", "/");
175                                 return servletDomain;
176                 }
177         
178                 virtual protected vmw.@internal.io.IObjectsDeserializer GetDeserializer()
179                 {
180                         if (m_deseializer == null)
181                                 m_deseializer = new GHWebDeseserializer();
182                         return m_deseializer;
183                 }
184
185                 protected vmw.@internal.io.IObjectsDeserializer m_deseializer = null;
186                 /// Mordechai: This class comes to solve a problem in class deserialize
187                 /// within web application. The problem is that the classloader that created 
188                 /// some user web class (for example aspx page) is not the class loader
189                 /// that de-serialize it - thus we end with ClassDefNotFoundException.
190                 /// To prevent this situation we delegate the serialization back the the 
191                 /// web app (which has the correct class loader...)
192         }
193
194         public class GHWebDeseserializer : vmw.@internal.io.IObjectsDeserializer 
195         {
196
197                         Object vmw.@internal.io.IObjectsDeserializer.Deserialize(java.io.ObjectInputStream stream)
198                         {
199                                 object obj = stream.readObject();
200                                 return obj;
201                         }
202         }
203
204 }
205
206 namespace System.Web.GH
207 {
208         public class BaseHttpServlet : System.Web.J2EE.BaseHttpServlet
209         {
210         }
211
212 }