Skip to content
Open
Show file tree
Hide file tree
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
Expand Up @@ -19,7 +19,6 @@

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
Expand All @@ -41,9 +40,8 @@ public AbstractRemoteServiceServlet() {
* Standard HttpServlet method: handle the POST. Delegates to
* {@link #processPost(HttpServletRequest, HttpServletResponse)}.
*
* This doPost method swallows ALL exceptions, logs them in the
* ServletContext, and returns a GENERIC_FAILURE_MSG response with status code
* 500.
* This doPost method swallows ALL exceptions, logs them,
* and returns a GENERIC_FAILURE_MSG response with status code 500.
*/
@Override
public final void doPost(HttpServletRequest request,
Expand Down Expand Up @@ -106,9 +104,7 @@ protected void doUnexpectedFailure(Throwable e) {
*/
throw new RuntimeException("Unable to report failure", e);
}
ServletContext servletContext = getServletContext();
RPCServletUtils.writeResponseForUnexpectedFailure(servletContext,
getThreadLocalResponse(), e);
RPCServletUtils.writeResponseForUnexpectedFailure(getThreadLocalResponse(), e);
}

/**
Expand Down
32 changes: 24 additions & 8 deletions user/src/com/google/gwt/user/server/rpc/RPCServletUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletContext;
Expand All @@ -37,6 +39,8 @@
*/
public class RPCServletUtils {

private static final Logger logger = Logger.getLogger(RPCServletUtils.class.getName());

public static final String CHARSET_UTF8_NAME = "UTF-8";

/**
Expand Down Expand Up @@ -319,20 +323,27 @@ public static boolean shouldGzipResponseContent(HttpServletRequest request,
&& exceedsUncompressedContentLengthLimit(responseContent);
}

@Deprecated
public static void writeResponse(ServletContext servletContext,
HttpServletResponse response, String responseContent, boolean gzipResponse)
throws IOException {
writeResponse(response, responseContent, gzipResponse);
}


/**
* Write the response content into the {@link HttpServletResponse}. If
* <code>gzipResponse</code> is <code>true</code>, the response content will
* be gzipped prior to being written into the response.
*
* @param servletContext servlet context for this response
* @param response response instance
* @param responseContent a string containing the response content
* @param gzipResponse if <code>true</code> the response content will be gzip
* encoded before being written into the response
* @throws IOException if reading, writing, or closing the response's output
* stream fails
*/
public static void writeResponse(ServletContext servletContext,
public static void writeResponse(
HttpServletResponse response, String responseContent, boolean gzipResponse)
throws IOException {

Expand Down Expand Up @@ -363,7 +374,7 @@ public static void writeResponse(ServletContext servletContext,
}

if (caught != null) {
servletContext.log("Unable to compress response", caught);
logger.log(Level.SEVERE, "Unable to compress response", caught);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
Expand All @@ -378,18 +389,23 @@ public static void writeResponse(ServletContext servletContext,
response.getOutputStream().write(responseBytes);
}

@Deprecated
public static void writeResponseForUnexpectedFailure(
ServletContext servletContext, HttpServletResponse response,
Throwable failure) {
writeResponseForUnexpectedFailure(response, failure);
}

/**
* Called when the servlet itself has a problem, rather than the invoked
* third-party method. It writes a simple 500 message back to the client.
*
* @param servletContext
* @param response
* @param failure
*/
public static void writeResponseForUnexpectedFailure(
ServletContext servletContext, HttpServletResponse response,
Throwable failure) {
servletContext.log("Exception while dispatching incoming RPC call", failure);
HttpServletResponse response, Throwable failure) {
logger.log(Level.SEVERE, "Exception while dispatching incoming RPC call", failure);

// Send GENERIC_FAILURE_MSG with 500 status.
//
Expand All @@ -403,7 +419,7 @@ public static void writeResponseForUnexpectedFailure(
response.getWriter().write(GENERIC_FAILURE_MSG);
}
} catch (IOException ex) {
servletContext.log(
logger.log(Level.SEVERE,
"respondWithUnexpectedFailure failed while sending the previous failure to the client",
ex);
}
Expand Down
50 changes: 29 additions & 21 deletions user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
Expand All @@ -45,6 +47,8 @@
public class RemoteServiceServlet extends AbstractRemoteServiceServlet
implements SerializationPolicyProvider {

private static final Logger logger = Logger.getLogger(RemoteServiceServlet.class.getName());

/**
* Loads a serialization policy stored as a servlet resource in the same
* ServletContext as this servlet. Returns null if not found.
Expand All @@ -62,7 +66,7 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
modulePath = new URL(moduleBaseURL).getPath();
} catch (MalformedURLException ex) {
// log the information, we will default
servlet.log("Malformed moduleBaseURL: " + moduleBaseURL, ex);
logger.log(Level.SEVERE, "Malformed moduleBaseURL: " + moduleBaseURL, ex);
}
}

Expand All @@ -74,12 +78,12 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
* this method.
*/
if (modulePath == null || !modulePath.startsWith(contextPath)) {
String message = "ERROR: The module path requested, "
String message = "The module path requested, "
+ modulePath
+ ", is not in the same web application as this servlet, "
+ contextPath
+ ". Your module may not be properly configured or your client and server code maybe out of date.";
servlet.log(message);
logger.log(Level.SEVERE, message);
} else {
// Strip off the context path from the module base URL. It should be a
// strict prefix.
Expand All @@ -98,11 +102,13 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
null);
if (serializationPolicy.hasClientFields()) {
if (ENABLE_ENHANCED_CLASSES) {
servlet.log("WARNING: Service deserializes enhanced JPA/JDO classes, which is " +
logger.log(Level.WARNING,
"Service deserializes enhanced JPA/JDO classes, which is " +
"unsafe. See https://github.com/gwtproject/gwt/issues/9709 for more " +
"detail on the vulnerability that this presents.");
} else {
servlet.log("ERROR: Service deserializes enhanced JPA/JDO classes, which is " +
logger.log(Level.SEVERE,
"Service deserializes enhanced JPA/JDO classes, which is " +
"unsafe. Review build logs to see which classes are affected, or set " +
ENABLE_GWT_ENHANCED_CLASSES_PROPERTY + " to true to allow using this " +
"service. See https://github.com/gwtproject/gwt/issues/9709 for more " +
Expand All @@ -111,17 +117,19 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet,
}
}
} catch (ParseException e) {
servlet.log("ERROR: Failed to parse the policy file '"
logger.log(Level.SEVERE,
"Failed to parse the policy file '"
+ serializationPolicyFilePath + "'", e);
} catch (IOException e) {
servlet.log("ERROR: Could not read the policy file '"
logger.log(Level.SEVERE,
"Could not read the policy file '"
+ serializationPolicyFilePath + "'", e);
}
} else {
String message = "ERROR: The serialization policy file '"
String message = "The serialization policy file '"
+ serializationPolicyFilePath
+ "' was not found; did you forget to include it in this deployment?";
servlet.log(message);
logger.log(Level.SEVERE, message);
}
} finally {
if (is != null) {
Expand Down Expand Up @@ -260,8 +268,8 @@ public final SerializationPolicy getSerializationPolicy(String moduleBaseURL,

if (serializationPolicy == null) {
// Failed to get the requested serialization policy; use the default
log(
"WARNING: Failed to get the SerializationPolicy '"
logger.log(Level.WARNING,
"Failed to get the SerializationPolicy '"
+ strongName
+ "' for module '"
+ moduleBaseURL
Expand Down Expand Up @@ -311,7 +319,8 @@ public String processCall(String payload) throws SerializationException {
try {
rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this);
} catch (IncompatibleRemoteServiceException ex) {
log(
logger.log(
Level.SEVERE,
"An IncompatibleRemoteServiceException was thrown while processing this call.",
ex);
return RPC.encodeResponseForFailedRequest(null, ex);
Expand Down Expand Up @@ -350,12 +359,13 @@ public String processCall(RPCRequest rpcRequest) throws SerializationException {
rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(),
rpcRequest.getFlags());
} catch (IncompatibleRemoteServiceException ex) {
log(
logger.log(Level.SEVERE,
"An IncompatibleRemoteServiceException was thrown while processing this call.",
ex);
return RPC.encodeResponseForFailedRequest(rpcRequest, ex);
} catch (RpcTokenException tokenException) {
log("An RpcTokenException was thrown while processing this call.",
logger.log(Level.SEVERE,
"An RpcTokenException was thrown while processing this call.",
tokenException);
return RPC.encodeResponseForFailedRequest(rpcRequest, tokenException);
}
Expand All @@ -364,9 +374,8 @@ public String processCall(RPCRequest rpcRequest) throws SerializationException {
/**
* Standard HttpServlet method: handle the POST.
*
* This doPost method swallows ALL exceptions, logs them in the
* ServletContext, and returns a GENERIC_FAILURE_MSG response with status code
* 500.
* This doPost method swallows ALL exceptions, logs them,
* and returns a GENERIC_FAILURE_MSG response with status code 500.
*
* @throws ServletException
* @throws SerializationException
Expand Down Expand Up @@ -469,12 +478,12 @@ protected SerializationPolicy loadPolicyFromCodeServer(String url) {

@Override
public void logInfo(String message) {
RemoteServiceServlet.this.log(message);
logger.log(Level.INFO, message);
}

@Override
public void logError(String message, Throwable throwable) {
RemoteServiceServlet.this.log(message, throwable);
logger.log(Level.SEVERE, message, throwable);
}
};
return CODE_SERVER_CLIENT.loadPolicy(url, adapter);
Expand Down Expand Up @@ -541,7 +550,6 @@ private void writeResponse(HttpServletRequest request,
boolean gzipEncode = RPCServletUtils.acceptsGzipEncoding(request)
&& shouldCompressResponse(request, response, responsePayload);

RPCServletUtils.writeResponse(getServletContext(), response,
responsePayload, gzipEncode);
RPCServletUtils.writeResponse(response, responsePayload, gzipEncode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ public String getServletName() {
}

private class MockServletContext implements ServletContext {
private String messageLogged;

public MockServletContext() {
}
Expand Down Expand Up @@ -190,7 +189,7 @@ public void log(String arg0) {
}

public void log(String arg0, Throwable arg1) {
messageLogged = arg0;
throw new UnsupportedOperationException();
}

public void removeAttribute(String arg0) {
Expand Down Expand Up @@ -329,16 +328,15 @@ public InputStream getResourceAsStream(String resource) {
SerializationPolicy serializationPolicy = rss.doGetSerializationPolicy(
mockRequest, "http://www.google.com/MyModule", "12345");
assertNull(serializationPolicy);
assertNotNull(mockContext.messageLogged);
}

/**
* Test method for
* {@link com.google.gwt.user.server.rpc.RemoteServiceServlet#doGetSerializationPolicy(javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String)}.
*
* This method tests that if the module path is in a different context than
* the RemoteServiceServlet which is processing the request, a message will be
* logged and null is returned for the SerializationPolicy.
* the RemoteServiceServlet which is processing the request,
* null is returned for the SerializationPolicy.
*/
public void testDoGetSerializationPolicy_ModuleInSeparateServlet()
throws ServletException {
Expand All @@ -353,7 +351,6 @@ public void testDoGetSerializationPolicy_ModuleInSeparateServlet()
mockRequest.contextPath = "/foo";
SerializationPolicy serializationPolicy = rss.doGetSerializationPolicy(
mockRequest, "http://www.google.com/MyModule", "");
assertNotNull(mockContext.messageLogged);
assertNull(serializationPolicy);
}

Expand Down