use of com.netflix.zuul.exception.ZuulException in project zuul by Netflix.
the class ClientRequestReceiver method fireWriteError.
private void fireWriteError(String requestPart, Throwable cause, ChannelHandlerContext ctx) throws Exception {
final String errMesg = String.format("Error writing %s to client", requestPart);
if (cause instanceof java.nio.channels.ClosedChannelException || cause instanceof Errors.NativeIoException) {
LOG.debug(errMesg + " - client connection is closed.");
if (zuulRequest != null) {
zuulRequest.getContext().cancel();
StatusCategoryUtils.storeStatusCategoryIfNotAlreadyFailure(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_CANCELLED);
}
} else {
LOG.error(errMesg, cause);
ctx.fireExceptionCaught(new ZuulException(cause, errMesg, true));
}
}
use of com.netflix.zuul.exception.ZuulException in project zuul by Netflix.
the class ClientRequestReceiver method channelReadInternal.
private void channelReadInternal(final ChannelHandlerContext ctx, Object msg) throws Exception {
// a response to the client channel.
if (msg instanceof LastHttpContent) {
ctx.channel().attr(ATTR_LAST_CONTENT_RECEIVED).set(Boolean.TRUE);
}
if (msg instanceof HttpRequest) {
clientRequest = (HttpRequest) msg;
zuulRequest = buildZuulHttpRequest(clientRequest, ctx);
// Handle invalid HTTP requests.
if (clientRequest.decoderResult().isFailure()) {
LOG.warn("Invalid http request. clientRequest = {} , uri = {}, info = {}", clientRequest, clientRequest.uri(), ChannelUtils.channelInfoForLogging(ctx.channel()), clientRequest.decoderResult().cause());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
RejectionUtils.rejectByClosingConnection(ctx, ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST, "decodefailure", clientRequest, /* injectedLatencyMillis= */
null);
return;
} else if (zuulRequest.hasBody() && zuulRequest.getBodyLength() > zuulRequest.getMaxBodySize()) {
String errorMsg = "Request too large. " + "clientRequest = " + clientRequest.toString() + ", uri = " + String.valueOf(clientRequest.uri()) + ", info = " + ChannelUtils.channelInfoForLogging(ctx.channel());
final ZuulException ze = new ZuulException(errorMsg);
ze.setStatusCode(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE.code());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
} else if (zuulRequest.getHeaders().getAll(HttpHeaderNames.HOST.toString()).size() > 1) {
LOG.debug("Multiple Host headers. clientRequest = {} , uri = {}, info = {}", clientRequest, clientRequest.uri(), ChannelUtils.channelInfoForLogging(ctx.channel()));
final ZuulException ze = new ZuulException("Multiple Host headers");
ze.setStatusCode(HttpResponseStatus.BAD_REQUEST.code());
StatusCategoryUtils.setStatusCategory(zuulRequest.getContext(), ZuulStatusCategory.FAILURE_CLIENT_BAD_REQUEST);
zuulRequest.getContext().setError(ze);
zuulRequest.getContext().setShouldSendErrorResponse(true);
}
handleExpect100Continue(ctx, clientRequest);
// Send the request down the filter pipeline
ctx.fireChannelRead(zuulRequest);
} else if (msg instanceof HttpContent) {
if ((zuulRequest != null) && (!zuulRequest.getContext().isCancelled())) {
ctx.fireChannelRead(msg);
} else {
// We already sent response for this request, these are laggard request body chunks that are still arriving
ReferenceCountUtil.release(msg);
}
} else if (msg instanceof HAProxyMessage) {
// do nothing, should already be handled by ElbProxyProtocolHandler
LOG.debug("Received HAProxyMessage for Proxy Protocol IP: {}", ((HAProxyMessage) msg).sourceAddress());
ReferenceCountUtil.release(msg);
} else {
LOG.debug("Received unrecognized message type. " + msg.getClass().getName());
ReferenceCountUtil.release(msg);
}
}
use of com.netflix.zuul.exception.ZuulException in project zuul by Netflix.
the class ClientResponseWriter method channelRead.
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
final Channel channel = ctx.channel();
if (msg instanceof HttpResponseMessage) {
final HttpResponseMessage resp = (HttpResponseMessage) msg;
if (skipProcessing(resp)) {
return;
}
if ((!isHandlingRequest) || (startedSendingResponseToClient)) {
/* This can happen if we are already in the process of streaming response back to client OR NOT within active
request/response cycle and something like IDLE or Request Read timeout occurs. In that case we have no way
to recover other than closing the socket and cleaning up resources used by BOTH responses.
*/
resp.disposeBufferedBody();
if (zuulResponse != null)
zuulResponse.disposeBufferedBody();
// This will trigger CompleteEvent if one is needed
ctx.close();
return;
}
startedSendingResponseToClient = true;
zuulResponse = resp;
if ("close".equalsIgnoreCase(zuulResponse.getHeaders().getFirst("Connection"))) {
closeConnection = true;
}
channel.attr(ATTR_ZUUL_RESP).set(zuulResponse);
if (channel.isActive()) {
// Track if this is happening.
if (!ClientRequestReceiver.isLastContentReceivedForChannel(channel)) {
StatusCategory status = StatusCategoryUtils.getStatusCategory(ClientRequestReceiver.getRequestFromChannel(channel));
if (ZuulStatusCategory.FAILURE_CLIENT_TIMEOUT.equals(status)) {
// If the request timed-out while being read, then there won't have been any LastContent, but thats ok because the connection will have to be discarded anyway.
} else {
responseBeforeReceivedLastContentCounter.increment();
LOG.warn("Writing response to client channel before have received the LastContent of request! " + zuulResponse.getInboundRequest().getInfoForLogging() + ", " + ChannelUtils.channelInfoForLogging(channel));
}
}
// Write out and flush the response to the client channel.
channel.write(buildHttpResponse(zuulResponse));
writeBufferedBodyContent(zuulResponse, channel);
channel.flush();
} else {
channel.close();
}
} else if (msg instanceof HttpContent) {
final HttpContent chunk = (HttpContent) msg;
if (channel.isActive()) {
channel.writeAndFlush(chunk);
} else {
chunk.release();
channel.close();
}
} else {
// should never happen
ReferenceCountUtil.release(msg);
throw new ZuulException("Received invalid message from origin", true);
}
}
use of com.netflix.zuul.exception.ZuulException in project zuul by Netflix.
the class ClientResponseWriter method exceptionCaught.
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
int status = 500;
final String errorMsg = "ClientResponseWriter caught exception in client connection pipeline: " + ChannelUtils.channelInfoForLogging(ctx.channel());
if (cause instanceof ZuulException) {
final ZuulException ze = (ZuulException) cause;
status = ze.getStatusCode();
LOG.error(errorMsg, cause);
} else if (cause instanceof ReadTimeoutException) {
LOG.error(errorMsg + ", Read timeout fired");
status = 504;
} else {
LOG.error(errorMsg, cause);
}
if (isHandlingRequest && !startedSendingResponseToClient && ctx.channel().isActive()) {
final HttpResponse httpResponse = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.valueOf(status));
ctx.writeAndFlush(httpResponse).addListener(ChannelFutureListener.CLOSE);
startedSendingResponseToClient = true;
} else {
ctx.close();
}
}
use of com.netflix.zuul.exception.ZuulException in project zuul by Netflix.
the class OriginResponseReceiver method userEventTriggered.
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof CompleteEvent) {
final CompleteReason reason = ((CompleteEvent) evt).getReason();
if ((reason != SESSION_COMPLETE) && (edgeProxy != null)) {
LOG.error("Origin request completed with reason other than COMPLETE: {}, {}", reason.name(), ChannelUtils.channelInfoForLogging(ctx.channel()));
final ZuulException ze = new ZuulException("CompleteEvent", reason.name(), true);
edgeProxy.errorFromOrigin(ze);
}
// See channelWrite() where these vars are first set onto the channel.
try {
super.userEventTriggered(ctx, evt);
} finally {
postCompleteHook(ctx, evt);
}
} else if (evt instanceof SslHandshakeCompletionEvent && !((SslHandshakeCompletionEvent) evt).isSuccess()) {
Throwable cause = ((SslHandshakeCompletionEvent) evt).cause();
ctx.channel().attr(SSL_HANDSHAKE_UNSUCCESS_FROM_ORIGIN_THROWABLE).set(cause);
} else if (evt instanceof IdleStateEvent) {
if (edgeProxy != null) {
LOG.error("Origin request received IDLE event: {}", ChannelUtils.channelInfoForLogging(ctx.channel()));
edgeProxy.errorFromOrigin(new OutboundException(READ_TIMEOUT, edgeProxy.getRequestAttempts()));
}
super.userEventTriggered(ctx, evt);
} else {
super.userEventTriggered(ctx, evt);
}
}
Aggregations