From c929eb037b055e2969b0b6082a8bc7f9e9d04e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Bock?= Date: Wed, 13 May 2015 14:13:00 +0200 Subject: [PATCH 1/4] * removed unnecessary imports * removed unnecessary casts * suppressed warning about potential null pointer exception --- .../jspservlet/_WOApplicationWrapper.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java b/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java index 24423a452f9..1c35884d6b8 100644 --- a/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java +++ b/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java @@ -1,18 +1,5 @@ package com.webobjects.jspservlet; -import com.webobjects.appserver.WOApplication; -import com.webobjects.appserver.WODynamicURL; -import com.webobjects.appserver.WORequest; -import com.webobjects.appserver.WOResponse; -import com.webobjects.appserver._private.WOInputStreamData; -import com.webobjects.appserver._private.WONoCopyPushbackInputStream; -import com.webobjects.foundation.NSArray; -import com.webobjects.foundation.NSData; -import com.webobjects.foundation.NSDelayedCallbackCenter; -import com.webobjects.foundation.NSLog; -import com.webobjects.foundation.NSLog.Logger; -import com.webobjects.foundation.NSMutableDictionary; -import com.webobjects.foundation.NSMutableRange; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -22,12 +9,25 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; + import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import com.webobjects.appserver.WOApplication; +import com.webobjects.appserver.WODynamicURL; +import com.webobjects.appserver.WORequest; +import com.webobjects.appserver.WOResponse; +import com.webobjects.appserver._private.WOInputStreamData; +import com.webobjects.appserver._private.WONoCopyPushbackInputStream; +import com.webobjects.foundation.NSArray; +import com.webobjects.foundation.NSData; +import com.webobjects.foundation.NSDelayedCallbackCenter; +import com.webobjects.foundation.NSLog; +import com.webobjects.foundation.NSMutableDictionary; +import com.webobjects.foundation.NSMutableRange; + /** * Fixes a bug in servletDispatchRequest() that manifests when a WOResponse * uses a content stream rather than an NSData. @@ -95,7 +95,7 @@ public void servletDispatchRequest(Map userInfo, boolean isDeplo Map ourUserInfo = new HashMap(userInfo.size()); for (Iterator mapEnum = userInfo.keySet().iterator(); mapEnum.hasNext();) { - String key = (String)mapEnum.next(); + String key = mapEnum.next(); ourUserInfo.put(key, userInfo.get(key)); } @@ -180,7 +180,8 @@ public void servletDispatchRequest(Map userInfo, boolean isDeplo if (is == null) { NSMutableRange range = new NSMutableRange(); - byte[] contentBytesNoCopy = ourContent.bytesNoCopy(range); + @SuppressWarnings("null") // as neither ourContent and is may be null + byte[] contentBytesNoCopy = ourContent.bytesNoCopy(range); out.write(contentBytesNoCopy, range.location(), range.length()); } else { try { @@ -240,8 +241,8 @@ public void servletDispatchRequest(Map userInfo, boolean isDeplo Iterator mapEnum; if (extraHeaders != null) { for (mapEnum = extraHeaders.keySet().iterator(); mapEnum.hasNext();) { - String key = (String)mapEnum.next(); - List value = (List)extraHeaders.get(key); + String key = mapEnum.next(); + List value = extraHeaders.get(key); if (value == null) { headers.remove(key.toLowerCase()); } else { @@ -269,15 +270,15 @@ public void servletDispatchRequest(Map userInfo, boolean isDeplo } private static void _mergeHeaders(WOResponse woResponse, HttpServletResponse servletResponse) { - for (Iterator iterator = woResponse.headerKeys().iterator(); iterator.hasNext();) { String key = (String)iterator.next(); - String lowercaseKey = key.toLowerCase(); - if (!"content-length".equals(lowercaseKey)) { - for (String value : woResponse.headersForKey(lowercaseKey)) { - servletResponse.addHeader(key, value); - } - } - } - String key; + for (Iterator iterator = woResponse.headerKeys().iterator(); iterator.hasNext();) { + String key = (String)iterator.next(); + String lowercaseKey = key.toLowerCase(); + if (!"content-length".equals(lowercaseKey)) { + for (String value : woResponse.headersForKey(lowercaseKey)) { + servletResponse.addHeader(key, value); + } + } + } } public String servletResponseForComponentWithName(String name, Map bindings, Map> extraHeaders, Map userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed) From 098d4dba808733cb47c255aa5ee2b412676629e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Bock?= Date: Wed, 13 May 2015 14:20:21 +0200 Subject: [PATCH 2/4] Replaced erxservletadaptor.jar by its source file ERXServletAdaptor.java --- .../jspservlet/ERXServletAdaptor.java | 41 ++++++++++++++++++ Frameworks/Core/ERJars/.classpath | 1 - .../ERJars/Libraries/erxservletadaptor.jar | Bin 1447 -> 0 bytes 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java delete mode 100644 Frameworks/Core/ERJars/Libraries/erxservletadaptor.jar diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java new file mode 100644 index 00000000000..453233cfbac --- /dev/null +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java @@ -0,0 +1,41 @@ +package er.extensions.jspservlet; + +import java.lang.reflect.Method; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.UnavailableException; + +import com.webobjects.jspservlet.WOServletAdaptor; + +public class ERXServletAdaptor extends WOServletAdaptor +{ + private static final long serialVersionUID = 1L; + + public ERXServletAdaptor() throws ServletException { + super(); + } + + static void invokeApplicationSetupMethod(final ServletContext servletContext) throws UnavailableException { + final ClassLoader classLoader = WOServletAdaptor.class.getClassLoader(); + try { + final String applicationClassName = servletContext.getInitParameter("WOApplicationClass"); + if (applicationClassName == null || "".equals(applicationClassName)) { + throw new UnavailableException("WOApplicationClass must be defined. Verify your web.xml configuration."); + } + + final Class applicationClass = classLoader.loadClass(applicationClassName); + final Method method = applicationClass.getMethod("setup", String[].class); + method.invoke(null, new Object[] {new String[0]}); + } + catch (Exception e) { + e.printStackTrace(); + throw new UnavailableException("Error initializing ERXServletAdaptor: " + e.getMessage()); + } + } + + public void init() throws ServletException { + invokeApplicationSetupMethod(this.getServletContext()); + super.init(); + } +} \ No newline at end of file diff --git a/Frameworks/Core/ERJars/.classpath b/Frameworks/Core/ERJars/.classpath index 5a377f07b52..54722660be2 100644 --- a/Frameworks/Core/ERJars/.classpath +++ b/Frameworks/Core/ERJars/.classpath @@ -3,7 +3,6 @@ - diff --git a/Frameworks/Core/ERJars/Libraries/erxservletadaptor.jar b/Frameworks/Core/ERJars/Libraries/erxservletadaptor.jar deleted file mode 100644 index b04cab8f82ea68bb80543986ca8988e1083514f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1447 zcmWIWW@Zs#-~hrkzD?!~NI-;vg~8V~#8KDN&rRRg(a+P(H8@1i*X`da28PeRXHNTg z>*`(P_14uocjo-&AcHH$51u}H%ES=h&Cao@p6Q)5&?reD4uD&bfo6dLP&TzlKeeJH zHLo}`Kd)FntGJ*zwWus7wM5@FC?XibbWBMsD9JCSBA=Za*Od zm4mao&&;X)_WoA(`=7t(-~Z3>fm4RpmTB@O&l9!&(_$~{?e3J_{>Ur+{G_;~k0&?# zJTBdr5Mnd?SKX`UZ-XAW&)i&WZS-E&I3nJ5o&JUL^E$Kd&1ujVI?Kf({{8c&M=Kqq z{5WH78Gh^edt_nldqkDr%N`cJ<-t=@VZ@j_>@%N z%5%O8@833yZH)N!x7(YmXZBOu>hN>nTGM8lhpGn2mrf{W~>wYeKv+20P z$&9eWmW`{APn|cd(nNRa^}s~Oo(Fr{0}{kD|Y{qK&ewwT7GMZP~3bzC$?)Z%ah|IJm$+mfd&S?=WL z5~Y-8b6iJ!@XQcKXBVWmh>Tw}1RQN%Y+9r@EUXN?(_jZ}HsX zYQ08DTIFwk=8luU*R6Q9qt~C+FVg1fQKswv+52`$UHsv*;Ckqmiw3#|TW)49-8KJ8 zA^+wchdcZ~OZR)XobBUSYbd)jRdAonVdtR3&yRn|Z;(D>6C@?Za&CUg%E#O~n_PMS zar=~KUQC<5uC%MEqM==CU&_<`_k9)XAFuu;5FRmm`p2F>?`9=GS=zScKt}aj?$FCg z+Ds9O;^MN$%MNADoY9v0@5t+d<1FV}nk!m%cs=pkyoAX+1&Wnn5Ol&s03r|Xx_47(?zq|W-yF>lH(kJfz5*1=e zTX;`$rHADn>RaO3UKZQ9S$0m+%cW|Z`g45r84qe4eyP{{bZ)$<+OU2G2( z`s28{!Q$6X`K2bumOR!`K3G~adHL-bM`g3_xw2i3a2MiJU3J1T%eXe@k+j|KfJ57V z^vz?RccF+x3EUyCZt4GH29-tA8m%tru`n9=5K0RU9=YkvR$ From 6e1ee8c3a670201199f17cb650464c8fd72ac8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Bock?= Date: Wed, 13 May 2015 14:27:00 +0200 Subject: [PATCH 3/4] reformatted source --- .../jspservlet/_WOApplicationWrapper.java | 555 +++++++++--------- 1 file changed, 273 insertions(+), 282 deletions(-) diff --git a/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java b/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java index 1c35884d6b8..4b7ab7848ef 100644 --- a/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java +++ b/Frameworks/Core/ERExtensions/Sources/com/webobjects/jspservlet/_WOApplicationWrapper.java @@ -36,287 +36,278 @@ * */ public class _WOApplicationWrapper - implements _WOServletAppInterface +implements _WOServletAppInterface { - private WOApplication appInstance = null; - - - public _WOApplicationWrapper() {} - - public String applicationName() - { - return this.appInstance.name(); - } - - public void setApplication(Object uncastApp) { - this.appInstance = ((WOApplication)uncastApp); - } - - public Object applicationObject() { - return this.appInstance; - } - - public void setSessionStoreClassName(String sessionStoreClassName) { - this.appInstance.setSessionStoreClassName(sessionStoreClassName); - } - - public void setContextClassName(String contextClassName) { - this.appInstance.setContextClassName(contextClassName); - } - - public void servletDispatchRequest(Map userInfo, boolean isDeployed) throws IOException { - HttpServletRequest request = (HttpServletRequest)userInfo.get("HttpServletRequest"); - HttpServletResponse response = (HttpServletResponse)userInfo.get("HttpServletResponse"); - - StringBuffer urlBuffer = new StringBuffer(); - - String contextPath = request.getContextPath(); - String servletPath = request.getServletPath(); - String pathInfo = request.getPathInfo(); - String queryString = request.getQueryString(); - - if (contextPath != null) { - urlBuffer.append(contextPath); - } - if (servletPath != null) { - urlBuffer.append(servletPath); - } - if (pathInfo != null) { - urlBuffer.append(pathInfo); - } - if (queryString != null) { - urlBuffer.append('?'); - urlBuffer.append(queryString); - } - - - String aURL = new String(urlBuffer); - - - Map ourUserInfo = new HashMap(userInfo.size()); - for (Iterator mapEnum = userInfo.keySet().iterator(); mapEnum.hasNext();) { - String key = mapEnum.next(); - ourUserInfo.put(key, userInfo.get(key)); - } - - - Map> headers = _headersFromRequest(request, null, isDeployed); - - - NSData contentData = null; - - int contentLength = request.getContentLength(); - if (contentLength > 0) { - WONoCopyPushbackInputStream pbsis = new WONoCopyPushbackInputStream(new BufferedInputStream(request.getInputStream()), contentLength); - contentData = new WOInputStreamData(pbsis, contentLength); - } - - WORequest ourRequest = this.appInstance.createRequest(request.getMethod(), aURL, "HTTP/1.0", headers, contentData, ourUserInfo); - - WODynamicURL woURL = ourRequest._uriDecomposed(); - - - if ((woURL.requestHandlerKey() == null) && (woURL.requestHandlerPath() == null) && (woURL.queryString() == null) && (this.appInstance.name().equals(woURL.applicationName()))) - { - - if (!this.appInstance.shouldRestoreSessionOnCleanEntry(ourRequest)) - { - HttpSession aSession = request.getSession(false); - if (aSession != null) { - try - { - aSession.invalidate(); - } - catch (IllegalStateException ise) { - NSLog._conditionallyLogPrivateException(ise); - } - } - } - } - - WOResponse ourResponse = this.appInstance.dispatchRequest(ourRequest); - - - - NSDelayedCallbackCenter.defaultCenter().eventEnded(); - - _mergeHeaders(ourResponse, response); - - - - - int bufferSize = 0; - long ourContentLength = 0L; - NSData ourContent = null; - InputStream is = ourResponse.contentInputStream(); - - if (is != null) { - bufferSize = ourResponse.contentInputStreamBufferSize(); - ourContentLength = ourResponse.contentInputStreamLength(); - } else { - ourContent = ourResponse.content(); - ourContentLength = ourContent == null ? 0L : ourContent.length(); - } - - if (ourContentLength > 0L) { - response.setContentLength((int)ourContentLength); - } - - String contentType = ourResponse.headerForKey("content-type"); - if (contentType != null) { - response.setContentType(contentType); - } - - - - response.setHeader("x-webobjects-servlet", "YES"); - - response.setStatus(ourResponse.status()); - - ServletOutputStream out; - // FD-2015-01-07: check for non-null input stream as well as non-null content data - if ((ourContent != null || is != null) && (ourContentLength > 0L)) { - out = response.getOutputStream(); - - if (is == null) { - NSMutableRange range = new NSMutableRange(); - @SuppressWarnings("null") // as neither ourContent and is may be null - byte[] contentBytesNoCopy = ourContent.bytesNoCopy(range); - out.write(contentBytesNoCopy, range.location(), range.length()); - } else { - try { - byte[] buffer = new byte[bufferSize]; - while (ourContentLength > 0L) { - int read = is.read(buffer, 0, ourContentLength > bufferSize ? bufferSize : (int)ourContentLength); - if (read == -1) - break; - ourContentLength -= read; - out.write(buffer, 0, read); - } - try - { - is.close(); - } catch (Exception e) { - NSLog.err.appendln("<_WOApplicationWrapper>: Failed to close content InputStream: " + e); - if (NSLog.debugLoggingAllowedForLevelAndGroups(NSLog.DebugLevelInformational, NSLog.DebugGroupJSPServlets)) { - NSLog.err.appendln(e); - } - } - - - out.flush(); - } - finally - { - try - { - is.close(); - } catch (Exception e) { - NSLog.err.appendln("<_WOApplicationWrapper>: Failed to close content InputStream: " + e); - if (NSLog.debugLoggingAllowedForLevelAndGroups(NSLog.DebugLevelInformational, NSLog.DebugGroupJSPServlets)) { - NSLog.err.appendln(e); - } - } - } - } - } - } - - - private static NSArray _adaptorVersion = new NSArray(new String[] { "5.2" }); - - private static Map> _headersFromRequest(HttpServletRequest request, Map> extraHeaders, boolean isDeployed) { - Map> headers = new HashMap(); - - - for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) { - String key = (String)e.nextElement(); - ArrayList values = new ArrayList(1); - for (Enumeration e2 = request.getHeaders(key); e2.hasMoreElements();) { - values.add((String)e2.nextElement()); - } - headers.put(key.toLowerCase(), values); - } - - Iterator mapEnum; - if (extraHeaders != null) { - for (mapEnum = extraHeaders.keySet().iterator(); mapEnum.hasNext();) { - String key = mapEnum.next(); - List value = extraHeaders.get(key); - if (value == null) { - headers.remove(key.toLowerCase()); - } else { - headers.put(key.toLowerCase(), new ArrayList(value)); - } - } - } - - - if (isDeployed) { - headers.put("x-webobjects-adaptor-version", _adaptorVersion); - } - - - NSArray values = new NSArray(new String[] { request.getServerName() }); - headers.put("x-webobjects-servlet-server-name", values); - - values = new NSArray(new String[] { Integer.toString(request.getServerPort()) }); - headers.put("x-webobjects-servlet-server-port", values); - - values = new NSArray(new String[] { request.getRemoteAddr() }); - headers.put("remote_addr", values); - - return headers; - } - - private static void _mergeHeaders(WOResponse woResponse, HttpServletResponse servletResponse) { - for (Iterator iterator = woResponse.headerKeys().iterator(); iterator.hasNext();) { - String key = (String)iterator.next(); - String lowercaseKey = key.toLowerCase(); - if (!"content-length".equals(lowercaseKey)) { - for (String value : woResponse.headersForKey(lowercaseKey)) { - servletResponse.addHeader(key, value); - } - } - } - } - - public String servletResponseForComponentWithName(String name, Map bindings, Map> extraHeaders, Map userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed) - { - NSMutableDictionary ourBindings = new NSMutableDictionary(bindings); - NSMutableDictionary ourUserInfo = new NSMutableDictionary(userInfo); - - Map> ourHeaders = _headersFromRequest((HttpServletRequest)userInfo.get("HttpServletRequest"), extraHeaders, isDeployed); - - WOResponse woResponse = this.appInstance.responseForComponentWithName(name, ourBindings, ourHeaders, ourUserInfo, urlPrefix, appName); - - if (mergeResponseHeaders) { - _mergeHeaders(woResponse, (HttpServletResponse)userInfo.get("HttpServletResponse")); - - - ((HttpServletResponse)userInfo.get("HttpServletResponse")).setHeader("x-webobjects-servlet", "YES"); - } - - return woResponse.contentString(); - } - - - public String servletResponseForDirectActionWithNameAndClass(String actionName, String className, Map formValues, InputStream contentStream, Map> extraHeaders, Map userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed) - { - NSMutableDictionary ourFormValues = new NSMutableDictionary(formValues); - NSMutableDictionary ourUserInfo = new NSMutableDictionary(userInfo); - - Map> ourHeaders = _headersFromRequest((HttpServletRequest)userInfo.get("HttpServletRequest"), extraHeaders, isDeployed); - - WOResponse woResponse = this.appInstance.responseForDirectActionWithNameAndClass(actionName, className, ourFormValues, contentStream, ourHeaders, ourUserInfo, urlPrefix, appName); - - if (mergeResponseHeaders) { - _mergeHeaders(woResponse, (HttpServletResponse)userInfo.get("HttpServletResponse")); - - - ((HttpServletResponse)userInfo.get("HttpServletResponse")).setHeader("x-webobjects-servlet", "YES"); - } - - return woResponse.contentString(); - } + private WOApplication appInstance = null; + + + public _WOApplicationWrapper() {} + + public String applicationName() { + return this.appInstance.name(); + } + + public void setApplication(Object uncastApp) { + this.appInstance = ((WOApplication)uncastApp); + } + + public Object applicationObject() { + return this.appInstance; + } + + public void setSessionStoreClassName(String sessionStoreClassName) { + this.appInstance.setSessionStoreClassName(sessionStoreClassName); + } + + public void setContextClassName(String contextClassName) { + this.appInstance.setContextClassName(contextClassName); + } + + public void servletDispatchRequest(Map userInfo, boolean isDeployed) throws IOException { + HttpServletRequest request = (HttpServletRequest)userInfo.get("HttpServletRequest"); + HttpServletResponse response = (HttpServletResponse)userInfo.get("HttpServletResponse"); + + StringBuffer urlBuffer = new StringBuffer(); + + String contextPath = request.getContextPath(); + String servletPath = request.getServletPath(); + String pathInfo = request.getPathInfo(); + String queryString = request.getQueryString(); + + if (contextPath != null) { + urlBuffer.append(contextPath); + } + if (servletPath != null) { + urlBuffer.append(servletPath); + } + if (pathInfo != null) { + urlBuffer.append(pathInfo); + } + if (queryString != null) { + urlBuffer.append('?'); + urlBuffer.append(queryString); + } + + String aURL = new String(urlBuffer); + + Map ourUserInfo = new HashMap(userInfo.size()); + for (Iterator mapEnum = userInfo.keySet().iterator(); mapEnum.hasNext();) { + String key = mapEnum.next(); + ourUserInfo.put(key, userInfo.get(key)); + } + + + Map> headers = _headersFromRequest(request, null, isDeployed); + + + NSData contentData = null; + + int contentLength = request.getContentLength(); + if (contentLength > 0) { + WONoCopyPushbackInputStream pbsis = new WONoCopyPushbackInputStream(new BufferedInputStream(request.getInputStream()), contentLength); + contentData = new WOInputStreamData(pbsis, contentLength); + } + + WORequest ourRequest = this.appInstance.createRequest(request.getMethod(), aURL, "HTTP/1.0", headers, contentData, ourUserInfo); + + WODynamicURL woURL = ourRequest._uriDecomposed(); + + + if ((woURL.requestHandlerKey() == null) && (woURL.requestHandlerPath() == null) && (woURL.queryString() == null) && (this.appInstance.name().equals(woURL.applicationName()))) + { + + if (!this.appInstance.shouldRestoreSessionOnCleanEntry(ourRequest)) + { + HttpSession aSession = request.getSession(false); + if (aSession != null) { + try + { + aSession.invalidate(); + } + catch (IllegalStateException ise) { + NSLog._conditionallyLogPrivateException(ise); + } + } + } + } + + WOResponse ourResponse = this.appInstance.dispatchRequest(ourRequest); + + + + NSDelayedCallbackCenter.defaultCenter().eventEnded(); + + _mergeHeaders(ourResponse, response); + + int bufferSize = 0; + long ourContentLength = 0L; + NSData ourContent = null; + InputStream is = ourResponse.contentInputStream(); + + if (is != null) { + bufferSize = ourResponse.contentInputStreamBufferSize(); + ourContentLength = ourResponse.contentInputStreamLength(); + } else { + ourContent = ourResponse.content(); + ourContentLength = ourContent == null ? 0L : ourContent.length(); + } + + if (ourContentLength > 0L) { + response.setContentLength((int)ourContentLength); + } + + String contentType = ourResponse.headerForKey("content-type"); + if (contentType != null) { + response.setContentType(contentType); + } + + response.setHeader("x-webobjects-servlet", "YES"); + + response.setStatus(ourResponse.status()); + + ServletOutputStream out; + // FD-2015-01-07: check for non-null input stream as well as non-null content data + if ((ourContent != null || is != null) && (ourContentLength > 0L)) { + out = response.getOutputStream(); + + if (is == null) { + NSMutableRange range = new NSMutableRange(); + @SuppressWarnings("null") // as neither ourContent and is may be null + byte[] contentBytesNoCopy = ourContent.bytesNoCopy(range); + out.write(contentBytesNoCopy, range.location(), range.length()); + } else { + try { + byte[] buffer = new byte[bufferSize]; + while (ourContentLength > 0L) { + int read = is.read(buffer, 0, ourContentLength > bufferSize ? bufferSize : (int)ourContentLength); + if (read == -1) + break; + ourContentLength -= read; + out.write(buffer, 0, read); + } + try + { + is.close(); + } catch (Exception e) { + NSLog.err.appendln("<_WOApplicationWrapper>: Failed to close content InputStream: " + e); + if (NSLog.debugLoggingAllowedForLevelAndGroups(NSLog.DebugLevelInformational, NSLog.DebugGroupJSPServlets)) { + NSLog.err.appendln(e); + } + } + + + out.flush(); + } + finally + { + try + { + is.close(); + } catch (Exception e) { + NSLog.err.appendln("<_WOApplicationWrapper>: Failed to close content InputStream: " + e); + if (NSLog.debugLoggingAllowedForLevelAndGroups(NSLog.DebugLevelInformational, NSLog.DebugGroupJSPServlets)) { + NSLog.err.appendln(e); + } + } + } + } + } + } + + private static NSArray _adaptorVersion = new NSArray(new String[] { "5.2" }); + + private static Map> _headersFromRequest(HttpServletRequest request, Map> extraHeaders, boolean isDeployed) { + Map> headers = new HashMap(); + + + for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) { + String key = (String)e.nextElement(); + ArrayList values = new ArrayList(1); + for (Enumeration e2 = request.getHeaders(key); e2.hasMoreElements();) { + values.add((String)e2.nextElement()); + } + headers.put(key.toLowerCase(), values); + } + + Iterator mapEnum; + if (extraHeaders != null) { + for (mapEnum = extraHeaders.keySet().iterator(); mapEnum.hasNext();) { + String key = mapEnum.next(); + List value = extraHeaders.get(key); + if (value == null) { + headers.remove(key.toLowerCase()); + } else { + headers.put(key.toLowerCase(), new ArrayList(value)); + } + } + } + + + if (isDeployed) { + headers.put("x-webobjects-adaptor-version", _adaptorVersion); + } + + + NSArray values = new NSArray(new String[] { request.getServerName() }); + headers.put("x-webobjects-servlet-server-name", values); + + values = new NSArray(new String[] { Integer.toString(request.getServerPort()) }); + headers.put("x-webobjects-servlet-server-port", values); + + values = new NSArray(new String[] { request.getRemoteAddr() }); + headers.put("remote_addr", values); + + return headers; + } + + private static void _mergeHeaders(WOResponse woResponse, HttpServletResponse servletResponse) { + for (Iterator iterator = woResponse.headerKeys().iterator(); iterator.hasNext();) { + String key = (String)iterator.next(); + String lowercaseKey = key.toLowerCase(); + if (!"content-length".equals(lowercaseKey)) { + for (String value : woResponse.headersForKey(lowercaseKey)) { + servletResponse.addHeader(key, value); + } + } + } + } + + public String servletResponseForComponentWithName(String name, Map bindings, Map> extraHeaders, Map userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed) + { + NSMutableDictionary ourBindings = new NSMutableDictionary(bindings); + NSMutableDictionary ourUserInfo = new NSMutableDictionary(userInfo); + + Map> ourHeaders = _headersFromRequest((HttpServletRequest)userInfo.get("HttpServletRequest"), extraHeaders, isDeployed); + + WOResponse woResponse = this.appInstance.responseForComponentWithName(name, ourBindings, ourHeaders, ourUserInfo, urlPrefix, appName); + + if (mergeResponseHeaders) { + _mergeHeaders(woResponse, (HttpServletResponse)userInfo.get("HttpServletResponse")); + + + ((HttpServletResponse)userInfo.get("HttpServletResponse")).setHeader("x-webobjects-servlet", "YES"); + } + + return woResponse.contentString(); + } + + + public String servletResponseForDirectActionWithNameAndClass(String actionName, String className, Map formValues, InputStream contentStream, Map> extraHeaders, Map userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed) + { + NSMutableDictionary ourFormValues = new NSMutableDictionary(formValues); + NSMutableDictionary ourUserInfo = new NSMutableDictionary(userInfo); + + Map> ourHeaders = _headersFromRequest((HttpServletRequest)userInfo.get("HttpServletRequest"), extraHeaders, isDeployed); + + WOResponse woResponse = this.appInstance.responseForDirectActionWithNameAndClass(actionName, className, ourFormValues, contentStream, ourHeaders, ourUserInfo, urlPrefix, appName); + + if (mergeResponseHeaders) { + _mergeHeaders(woResponse, (HttpServletResponse)userInfo.get("HttpServletResponse")); + + + ((HttpServletResponse)userInfo.get("HttpServletResponse")).setHeader("x-webobjects-servlet", "YES"); + } + + return woResponse.contentString(); + } } From 1f4d4b4b907836f89659e49eed91efa6f0eca66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Bock?= Date: Wed, 13 May 2015 14:36:22 +0200 Subject: [PATCH 4/4] A ApplicationDidFinishLaunchingNotification will be posted if the servlet has been initialized (Fix for wocommunity/wonder#642) --- .../Sources/er/extensions/appserver/ERXApplication.java | 3 --- .../Sources/er/extensions/jspservlet/ERXServletAdaptor.java | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXApplication.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXApplication.java index e7f3e7609d1..be9381b9317 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXApplication.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/appserver/ERXApplication.java @@ -1261,9 +1261,6 @@ public ERXApplication() { } } - if (isDeployedAsServlet()) { - NSNotificationCenter.defaultCenter().postNotification(WOApplication.ApplicationDidFinishLaunchingNotification, this); - } } /** diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java index 453233cfbac..30edeb9cfef 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/jspservlet/ERXServletAdaptor.java @@ -6,6 +6,8 @@ import javax.servlet.ServletException; import javax.servlet.UnavailableException; +import com.webobjects.appserver.WOApplication; +import com.webobjects.foundation.NSNotificationCenter; import com.webobjects.jspservlet.WOServletAdaptor; public class ERXServletAdaptor extends WOServletAdaptor @@ -34,8 +36,12 @@ static void invokeApplicationSetupMethod(final ServletContext servletContext) th } } + @Override public void init() throws ServletException { invokeApplicationSetupMethod(this.getServletContext()); super.init(); + + // Fix for wocommunity/wonder#642 + NSNotificationCenter.defaultCenter().postNotification(WOApplication.ApplicationDidFinishLaunchingNotification, this); } } \ No newline at end of file