440020 Abort bad proxy responses with sendError(-1)

This commit is contained in:
Greg Wilkins 2014-07-23 16:31:19 +10:00
parent 564ffca5dc
commit e199b671bb
5 changed files with 32 additions and 26 deletions

View File

@ -32,6 +32,7 @@ import java.util.Set;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import javax.servlet.AsyncContext; import javax.servlet.AsyncContext;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@ -51,6 +52,7 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.HttpCookieStore; import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
@ -558,7 +560,15 @@ public class ProxyServlet extends HttpServlet
_log.debug(getRequestId(request) + " proxying failed", failure); _log.debug(getRequestId(request) + " proxying failed", failure);
if (response.isCommitted()) if (response.isCommitted())
{ {
request.setAttribute("org.eclipse.jetty.server.Response.failure", failure); // Use Jetty specific behavior to close connection
try
{
response.sendError(-1);
}
catch (IOException e)
{
getServletContext().log("close failed", e);
}
AsyncContext asyncContext = request.getAsyncContext(); AsyncContext asyncContext = request.getAsyncContext();
asyncContext.complete(); asyncContext.complete();
} }

View File

@ -402,21 +402,8 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
} }
else else
{ {
// There is no way in the Servlet API to directly close a connection, // Complete generating the response
// so we rely on applications to pass this attribute to signal they _response.closeOutput();
// want to hard close the connection, without even closing the output.
Object failure = _request.getAttribute("org.eclipse.jetty.server.Response.failure");
if (failure != null)
{
if (LOG.isDebugEnabled())
LOG.debug("Explicit response failure", failure);
failed();
}
else
{
// Complete generating the response
_response.closeOutput();
}
} }
} }
catch(EofException|ClosedChannelException e) catch(EofException|ClosedChannelException e)
@ -812,10 +799,11 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable, H
/** /**
* If a write or similar to this channel fails this method should be called. The standard implementation * If a write or similar to this channel fails this method should be called. The standard implementation
* of {@link #failed()} is a noop. But the different implementations of HttpChannel might want to take actions. * is to call {@link HttpTransport#abort()}
*/ */
public void failed() public void abort()
{ {
_transport.abort();
} }
private class CommitCallback implements Callback private class CommitCallback implements Callback

View File

@ -537,10 +537,10 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
} }
@Override @Override
public void failed() public void abort()
{ {
super.abort();
_generator.setPersistent(false); _generator.setPersistent(false);
getEndPoint().shutdownOutput();
} }
@Override @Override

View File

@ -157,7 +157,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
catch(IOException e) catch(IOException e)
{ {
LOG.debug(e); LOG.debug(e);
_channel.failed(); _channel.abort();
} }
releaseBuffer(); releaseBuffer();
return; return;
@ -192,7 +192,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
catch(IOException e) catch(IOException e)
{ {
LOG.debug(e); LOG.debug(e);
_channel.failed(); _channel.abort();
} }
releaseBuffer(); releaseBuffer();
return; return;

View File

@ -541,10 +541,7 @@ public class Response implements HttpServletResponse
@Override @Override
public void sendError(int sc) throws IOException public void sendError(int sc) throws IOException
{ {
if (sc == 102) sendError(sc, null);
sendProcessing();
else
sendError(sc, null);
} }
@Override @Override
@ -553,6 +550,17 @@ public class Response implements HttpServletResponse
if (isIncluding()) if (isIncluding())
return; return;
switch(code)
{
case -1:
_channel.abort();
return;
case 102:
sendProcessing();
return;
default:
}
if (isCommitted()) if (isCommitted())
LOG.warn("Committed before "+code+" "+message); LOG.warn("Committed before "+code+" "+message);