static void sendRedirect( final ChannelHandlerContext ctx, final ChannelEvent e, final Class<? extends ComponentId> compClass, final MappingHttpRequest request) { e.getFuture().cancel(); String redirectUri = null; if (Topology.isEnabled(compClass)) { // have an enabled service, lets use that final URI serviceUri = ServiceUris.remote(Topology.lookup(compClass)); redirectUri = serviceUri.toASCIIString() + request.getServicePath().replace(serviceUri.getPath(), ""); } else if (Topology.isEnabled( Eucalyptus.class)) { // can't find service info, redirect via clc master final URI serviceUri = ServiceUris.remote(Topology.lookup(Eucalyptus.class)); redirectUri = serviceUri.toASCIIString().replace(Eucalyptus.INSTANCE.getServicePath(), "") + request.getServicePath().replace(serviceUri.getPath(), ""); } HttpResponse response = null; if (redirectUri == null || isRedirectLoop(request, redirectUri)) { response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.SERVICE_UNAVAILABLE); if (Logs.isDebug()) { String errorMessage = "Failed to lookup service for " + Components.lookup(compClass).getName() + " for path " + request.getServicePath() + ".\nCurrent state: \n\t" + Joiner.on("\n\t").join(Topology.enabledServices()); byte[] errorBytes = Exceptions.string(new ServiceStateException(errorMessage)).getBytes(); response.setContent(ChannelBuffers.wrappedBuffer(errorBytes)); } } else { response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.TEMPORARY_REDIRECT); if (request.getQuery() != null) { redirectUri += "?" + request.getQuery(); } response.setHeader(HttpHeaders.Names.LOCATION, redirectUri); } response.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); if (ctx.getChannel().isConnected()) { ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE); } }
@Override protected void encodeInitialLine(final ChannelBuffer buf, final HttpMessage message) throws Exception { final MappingHttpRequest request = (MappingHttpRequest) message; buf.writeBytes(request.getMethod().toString().getBytes("ASCII")); buf.writeByte(HttpUtils.SP); buf.writeBytes(request.getServicePath().getBytes("ASCII")); buf.writeByte(HttpUtils.SP); buf.writeBytes(request.getProtocolVersion().toString().getBytes("ASCII")); buf.writeBytes(HttpUtils.CRLF); }
private static boolean isRedirectLoop(final MappingHttpRequest request, final String uri) { final String requestHost = request.getHeader(HttpHeaders.Names.HOST); final String requestPath = request.getServicePath(); return requestHost != null && requestPath != null && uri.contains(requestHost + requestPath); }