Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed _servletDispatchRequest() to check for non-null WOResponse content... #635

Merged
merged 2 commits into from
May 6, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
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;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
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;

/**
* Fixes a bug in servletDispatchRequest() that manifests when a WOResponse
* uses a content stream rather than an NSData.
*
* @author faizel
*
*/
public class _WOApplicationWrapper
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<String, Object> 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<String, Object> ourUserInfo = new HashMap(userInfo.size());
for (Iterator<String> mapEnum = userInfo.keySet().iterator(); mapEnum.hasNext();) {
String key = (String)mapEnum.next();
ourUserInfo.put(key, userInfo.get(key));
}


Map<String, ? extends List<String>> 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();
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<String> _adaptorVersion = new NSArray(new String[] { "5.2" });

private static Map<String, ? extends List<String>> _headersFromRequest(HttpServletRequest request, Map<String, ? extends List<String>> extraHeaders, boolean isDeployed) {
Map<String, List<String>> headers = new HashMap();


for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) {
String key = (String)e.nextElement();
ArrayList<String> values = new ArrayList(1);
for (Enumeration e2 = request.getHeaders(key); e2.hasMoreElements();) {
values.add((String)e2.nextElement());
}
headers.put(key.toLowerCase(), values);
}

Iterator<String> mapEnum;
if (extraHeaders != null) {
for (mapEnum = extraHeaders.keySet().iterator(); mapEnum.hasNext();) {
String key = (String)mapEnum.next();
List<String> value = (List)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<String> 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);
}
}
}
String key;
}

public String servletResponseForComponentWithName(String name, Map<String, Object> bindings, Map<String, ? extends List<String>> extraHeaders, Map<String, Object> userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed)
{
NSMutableDictionary<String, Object> ourBindings = new NSMutableDictionary(bindings);
NSMutableDictionary<String, Object> ourUserInfo = new NSMutableDictionary(userInfo);

Map<String, ? extends List<String>> 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<String, Object> formValues, InputStream contentStream, Map<String, ? extends List<String>> extraHeaders, Map<String, Object> userInfo, String urlPrefix, String appName, boolean mergeResponseHeaders, boolean isDeployed)
{
NSMutableDictionary<String, Object> ourFormValues = new NSMutableDictionary(formValues);
NSMutableDictionary<String, Object> ourUserInfo = new NSMutableDictionary(userInfo);

Map<String, ? extends List<String>> 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();
}
}

/* Location: /Users/fdakri/.m2/repository/com/webobjects/JavaWOJSPServlet/5.4.3/JavaWOJSPServlet-5.4.3.jar
* Qualified Name: com.webobjects.jspservlet._WOApplicationWrapper
* Java Class Version: 5 (49.0)
* JD-Core Version: 0.7.0.1
*/