001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master; 019 020import static org.apache.hadoop.hbase.util.DNS.MASTER_HOSTNAME_KEY; 021 022import java.io.IOException; 023import java.net.InetAddress; 024import javax.servlet.ServletException; 025import javax.servlet.http.HttpServlet; 026import javax.servlet.http.HttpServletRequest; 027import javax.servlet.http.HttpServletResponse; 028import org.apache.hadoop.hbase.http.InfoServer; 029import org.apache.hadoop.hbase.util.Addressing; 030import org.apache.yetus.audience.InterfaceAudience; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034@InterfaceAudience.Private 035class MasterRedirectServlet extends HttpServlet { 036 037 private static final long serialVersionUID = 2894774810058302473L; 038 039 private static final Logger LOG = LoggerFactory.getLogger(MasterRedirectServlet.class); 040 041 private final int regionServerInfoPort; 042 private final String regionServerHostname; 043 044 /** 045 * @param infoServer that we're trying to send all requests to 046 * @param hostname may be null. if given, will be used for redirects instead of host from client. 047 */ 048 public MasterRedirectServlet(InfoServer infoServer, String hostname) { 049 regionServerInfoPort = infoServer.getPort(); 050 regionServerHostname = hostname; 051 } 052 053 @Override 054 public void doGet(HttpServletRequest request, HttpServletResponse response) 055 throws ServletException, IOException { 056 String redirectHost = regionServerHostname; 057 if (redirectHost == null) { 058 redirectHost = request.getServerName(); 059 if (!Addressing.isLocalAddress(InetAddress.getByName(redirectHost))) { 060 LOG.warn("Couldn't resolve '" + redirectHost + "' as an address local to this node and '" + 061 MASTER_HOSTNAME_KEY + "' is not set; client will get an HTTP 400 response. If " + 062 "your HBase deployment relies on client accessible names that the region server " + 063 "process can't resolve locally, then you should set the previously mentioned " + 064 "configuration variable to an appropriate hostname."); 065 // no sending client provided input back to the client, so the goal host is just in the 066 // logs. 067 response.sendError(400, 068 "Request was to a host that I can't resolve for any of the network interfaces on " + 069 "this node. If this is due to an intermediary such as an HTTP load balancer or " + 070 "other proxy, your HBase administrator can set '" + MASTER_HOSTNAME_KEY + 071 "' to point to the correct hostname."); 072 return; 073 } 074 } 075 // TODO: this scheme should come from looking at the scheme registered in the infoserver's http 076 // server for the host and port we're using, but it's buried way too deep to do that ATM. 077 String redirectUrl = request.getScheme() + "://" + redirectHost + ":" + regionServerInfoPort + 078 request.getRequestURI(); 079 response.sendRedirect(redirectUrl); 080 } 081}