Replace the stock Jetty ErrorHandler with a vague response

Mirror the behavior of RestApiServlet. Anytime an exception is
caught by Jetty format back just "Internal server error" after
logging the exception to the server's error log.

Change-Id: I3b1dfdea45b833b5ffd0cd1731d24ecf7cd75eb1
This commit is contained in:
Shawn Pearce
2013-05-16 16:03:32 -07:00
parent fec1537a56
commit bf159416bd
3 changed files with 81 additions and 0 deletions

View File

@@ -6,6 +6,7 @@ java_library2(
'//gerrit-cache-h2:cache-h2',
'//gerrit-common:server',
'//gerrit-extension-api:api',
'//gerrit-gwtexpui:server',
'//gerrit-httpd:httpd',
'//gerrit-openid:openid',
'//gerrit-server:common_rules',

View File

@@ -0,0 +1,79 @@
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.pgm.http.jetty;
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.gwtexpui.server.CacheHeaders;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
class HiddenErrorHandler extends ErrorHandler {
private static final Logger log = LoggerFactory.getLogger(HiddenErrorHandler.class);
private static final byte[] MSG = "Internal server error\n".getBytes(Charsets.ISO_8859_1);
public void handle(String target, Request baseRequest,
HttpServletRequest req, HttpServletResponse res) throws IOException {
AbstractHttpConnection.getCurrentConnection().getRequest().setHandled(true);
try {
log(req);
} finally {
replyGenericError(res);
}
}
private void replyGenericError(HttpServletResponse res) throws IOException {
if (!res.isCommitted()) {
res.reset();
res.setStatus(SC_INTERNAL_SERVER_ERROR);
res.setHeader(HttpHeaders.CONTENT_TYPE, "text/plain; charset=ISO-8859-1");
res.setContentLength(MSG.length);
try {
CacheHeaders.setNotCacheable(res);
} finally {
ServletOutputStream out = res.getOutputStream();
try {
out.write(MSG);
} finally {
out.close();
}
}
}
}
private static void log(HttpServletRequest req) {
Throwable err = (Throwable)req.getAttribute("javax.servlet.error.exception");
if (err != null) {
String uri = req.getRequestURI();
if (!Strings.isNullOrEmpty(req.getQueryString())) {
uri += "?" + req.getQueryString();
}
log.error(String.format("Error in %s %s", req.getMethod(), uri), err);
}
}
}

View File

@@ -332,6 +332,7 @@ public class JettyServer {
// for Gerrit plug-ins to enable user-level sessions.
//
app.setSessionHandler(new SessionHandler());
app.setErrorHandler(new HiddenErrorHandler());
// This is the path we are accessed by clients within our domain.
//